Commit 30d8340b authored by Takashi Sakamoto's avatar Takashi Sakamoto Committed by Takashi Iwai

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: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4c8099e9
...@@ -118,8 +118,6 @@ struct snd_card { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
return change;
} else { } else {
int ret = 0; if (!ue->tlv_data_size || !ue->tlv_data)
return -ENXIO;
if (size < ue->tlv_data_size)
return -ENOSPC;
mutex_lock(&ue->card->user_ctl_lock);
if (!ue->tlv_data_size || !ue->tlv_data) {
ret = -ENXIO;
goto err_unlock;
}
if (size < ue->tlv_data_size) {
ret = -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, ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment