summaryrefslogtreecommitdiffstats
path: root/sound/core/control.c
diff options
context:
space:
mode:
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>2017-08-03 20:20:42 +0900
committerTakashi Iwai <tiwai@suse.de>2017-08-04 16:50:55 +0200
commit30d8340b5857550007ab6fe9744e4384dfa6e55c (patch)
tree40a7d3ae6e0f9fecb8a74d1b8fe73e2e2af6c96c /sound/core/control.c
parent4c8099e9cad5ba11c770042549f68e7687eaa72b (diff)
downloadlinux-30d8340b5857550007ab6fe9744e4384dfa6e55c.tar.bz2
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>
Diffstat (limited to 'sound/core/control.c')
-rw-r--r--sound/core/control.c37
1 files changed, 13 insertions, 24 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index f3bd9bdba9a7..989292fe33c2 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1095,9 +1095,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
char *src = ue->elem_data +
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
- mutex_lock(&ue->card->user_ctl_lock);
memcpy(&ucontrol->value, src, size);
- mutex_unlock(&ue->card->user_ctl_lock);
return 0;
}
@@ -1110,11 +1108,9 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
char *dst = ue->elem_data +
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
- mutex_lock(&ue->card->user_ctl_lock);
change = memcmp(&ucontrol->value, dst, size) != 0;
if (change)
memcpy(dst, &ucontrol->value, size);
- mutex_unlock(&ue->card->user_ctl_lock);
return change;
}
@@ -1124,44 +1120,37 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
unsigned int __user *tlv)
{
struct user_element *ue = kcontrol->private_data;
- int change = 0;
- void *new_data;
if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
+ int change;
+ void *new_data;
+
if (size > 1024 * 128) /* sane value */
return -EINVAL;
new_data = memdup_user(tlv, size);
if (IS_ERR(new_data))
return PTR_ERR(new_data);
- mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
change = memcmp(ue->tlv_data, new_data, size);
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
- mutex_unlock(&ue->card->user_ctl_lock);
+
+ return change;
} 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))
- ret = -EFAULT;
-err_unlock:
- mutex_unlock(&ue->card->user_ctl_lock);
- if (ret)
- return ret;
+ return -EFAULT;
+
+ return 0;
}
- return change;
}
static int snd_ctl_elem_init_enum_names(struct user_element *ue)