ALSA: control: obsolete user_ctl_lock
At a previous commit, concurrent requests for TLV data are maintained exclusively between read requests and write/command requests. TLV callback handlers in each driver has no risk from concurrent access for reference/change. In current implementation, 'struct snd_card' has a mutex to control concurrent accesses to user-defined element sets. This commit obsoletes it. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
4c8099e9ca
commit
30d8340b58
@ -118,8 +118,6 @@ struct snd_card {
|
|||||||
int user_ctl_count; /* count of all user controls */
|
int user_ctl_count; /* count of all user controls */
|
||||||
struct list_head controls; /* all controls for this card */
|
struct list_head controls; /* all controls for this card */
|
||||||
struct list_head ctl_files; /* active control files */
|
struct list_head ctl_files; /* active control files */
|
||||||
struct mutex user_ctl_lock; /* protects user controls against
|
|
||||||
concurrent access */
|
|
||||||
|
|
||||||
struct snd_info_entry *proc_root; /* root for soundcard specific files */
|
struct snd_info_entry *proc_root; /* root for soundcard specific files */
|
||||||
struct snd_info_entry *proc_id; /* the card id */
|
struct snd_info_entry *proc_id; /* the card id */
|
||||||
|
@ -1095,9 +1095,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
|
|||||||
char *src = ue->elem_data +
|
char *src = ue->elem_data +
|
||||||
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
||||||
|
|
||||||
mutex_lock(&ue->card->user_ctl_lock);
|
|
||||||
memcpy(&ucontrol->value, src, size);
|
memcpy(&ucontrol->value, src, size);
|
||||||
mutex_unlock(&ue->card->user_ctl_lock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1110,11 +1108,9 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
|
|||||||
char *dst = ue->elem_data +
|
char *dst = ue->elem_data +
|
||||||
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
||||||
|
|
||||||
mutex_lock(&ue->card->user_ctl_lock);
|
|
||||||
change = memcmp(&ucontrol->value, dst, size) != 0;
|
change = memcmp(&ucontrol->value, dst, size) != 0;
|
||||||
if (change)
|
if (change)
|
||||||
memcpy(dst, &ucontrol->value, size);
|
memcpy(dst, &ucontrol->value, size);
|
||||||
mutex_unlock(&ue->card->user_ctl_lock);
|
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1124,44 +1120,37 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
|
|||||||
unsigned int __user *tlv)
|
unsigned int __user *tlv)
|
||||||
{
|
{
|
||||||
struct user_element *ue = kcontrol->private_data;
|
struct user_element *ue = kcontrol->private_data;
|
||||||
int change = 0;
|
|
||||||
void *new_data;
|
|
||||||
|
|
||||||
if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
|
if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
|
||||||
|
int change;
|
||||||
|
void *new_data;
|
||||||
|
|
||||||
if (size > 1024 * 128) /* sane value */
|
if (size > 1024 * 128) /* sane value */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
new_data = memdup_user(tlv, size);
|
new_data = memdup_user(tlv, size);
|
||||||
if (IS_ERR(new_data))
|
if (IS_ERR(new_data))
|
||||||
return PTR_ERR(new_data);
|
return PTR_ERR(new_data);
|
||||||
mutex_lock(&ue->card->user_ctl_lock);
|
|
||||||
change = ue->tlv_data_size != size;
|
change = ue->tlv_data_size != size;
|
||||||
if (!change)
|
if (!change)
|
||||||
change = memcmp(ue->tlv_data, new_data, size);
|
change = memcmp(ue->tlv_data, new_data, size);
|
||||||
kfree(ue->tlv_data);
|
kfree(ue->tlv_data);
|
||||||
ue->tlv_data = new_data;
|
ue->tlv_data = new_data;
|
||||||
ue->tlv_data_size = size;
|
ue->tlv_data_size = size;
|
||||||
mutex_unlock(&ue->card->user_ctl_lock);
|
|
||||||
} else {
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
mutex_lock(&ue->card->user_ctl_lock);
|
return change;
|
||||||
if (!ue->tlv_data_size || !ue->tlv_data) {
|
} else {
|
||||||
ret = -ENXIO;
|
if (!ue->tlv_data_size || !ue->tlv_data)
|
||||||
goto err_unlock;
|
return -ENXIO;
|
||||||
}
|
|
||||||
if (size < ue->tlv_data_size) {
|
if (size < ue->tlv_data_size)
|
||||||
ret = -ENOSPC;
|
return -ENOSPC;
|
||||||
goto err_unlock;
|
|
||||||
}
|
|
||||||
if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
|
if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
|
||||||
ret = -EFAULT;
|
return -EFAULT;
|
||||||
err_unlock:
|
|
||||||
mutex_unlock(&ue->card->user_ctl_lock);
|
return 0;
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
return change;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||||
|
@ -248,7 +248,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
|||||||
INIT_LIST_HEAD(&card->devices);
|
INIT_LIST_HEAD(&card->devices);
|
||||||
init_rwsem(&card->controls_rwsem);
|
init_rwsem(&card->controls_rwsem);
|
||||||
rwlock_init(&card->ctl_files_rwlock);
|
rwlock_init(&card->ctl_files_rwlock);
|
||||||
mutex_init(&card->user_ctl_lock);
|
|
||||||
INIT_LIST_HEAD(&card->controls);
|
INIT_LIST_HEAD(&card->controls);
|
||||||
INIT_LIST_HEAD(&card->ctl_files);
|
INIT_LIST_HEAD(&card->ctl_files);
|
||||||
spin_lock_init(&card->files_lock);
|
spin_lock_init(&card->files_lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user