diff options
-rw-r--r-- | sound/core/control.c | 16 |
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, | |||
1029 | struct user_element { | 1029 | struct 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); |