aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/control.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index be5b97cd8dc3..196a6fe100ca 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1029,7 +1029,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
1029struct user_element { 1029struct user_element {
1030 struct snd_ctl_elem_info info; 1030 struct snd_ctl_elem_info info;
1031 struct snd_card *card; 1031 struct snd_card *card;
1032 void *elem_data; /* element data */ 1032 char *elem_data; /* element data */
1033 unsigned long elem_data_size; /* size of element data in bytes */ 1033 unsigned long elem_data_size; /* size of element data in bytes */
1034 void *tlv_data; /* TLV data */ 1034 void *tlv_data; /* TLV data */
1035 unsigned long tlv_data_size; /* TLV data size */ 1035 unsigned long tlv_data_size; /* TLV data size */
@@ -1078,9 +1078,12 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
1078 struct snd_ctl_elem_value *ucontrol) 1078 struct snd_ctl_elem_value *ucontrol)
1079{ 1079{
1080 struct user_element *ue = kcontrol->private_data; 1080 struct user_element *ue = kcontrol->private_data;
1081 unsigned int size = ue->elem_data_size;
1082 char *src = ue->elem_data +
1083 snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
1081 1084
1082 mutex_lock(&ue->card->user_ctl_lock); 1085 mutex_lock(&ue->card->user_ctl_lock);
1083 memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size); 1086 memcpy(&ucontrol->value, src, size);
1084 mutex_unlock(&ue->card->user_ctl_lock); 1087 mutex_unlock(&ue->card->user_ctl_lock);
1085 return 0; 1088 return 0;
1086} 1089}
@@ -1090,11 +1093,14 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
1090{ 1093{
1091 int change; 1094 int change;
1092 struct user_element *ue = kcontrol->private_data; 1095 struct user_element *ue = kcontrol->private_data;
1096 unsigned int size = ue->elem_data_size;
1097 char *dst = ue->elem_data +
1098 snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
1093 1099
1094 mutex_lock(&ue->card->user_ctl_lock); 1100 mutex_lock(&ue->card->user_ctl_lock);
1095 change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0; 1101 change = memcmp(&ucontrol->value, dst, size) != 0;
1096 if (change) 1102 if (change)
1097 memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size); 1103 memcpy(dst, &ucontrol->value, size);
1098 mutex_unlock(&ue->card->user_ctl_lock); 1104 mutex_unlock(&ue->card->user_ctl_lock);
1099 return change; 1105 return change;
1100} 1106}
@@ -1278,7 +1284,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
1278 if (err < 0) 1284 if (err < 0)
1279 return err; 1285 return err;
1280 memcpy(&kctl->id, &info->id, sizeof(kctl->id)); 1286 memcpy(&kctl->id, &info->id, sizeof(kctl->id));
1281 kctl->private_data = kzalloc(sizeof(struct user_element) + private_size, 1287 kctl->private_data = kzalloc(sizeof(struct user_element) + private_size * count,
1282 GFP_KERNEL); 1288 GFP_KERNEL);
1283 if (kctl->private_data == NULL) { 1289 if (kctl->private_data == NULL) {
1284 kfree(kctl); 1290 kfree(kctl);