|
@@ -1029,7 +1029,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
|
|
|
struct user_element {
|
|
|
struct snd_ctl_elem_info info;
|
|
|
struct snd_card *card;
|
|
|
- void *elem_data; /* element data */
|
|
|
+ char *elem_data; /* element data */
|
|
|
unsigned long elem_data_size; /* size of element data in bytes */
|
|
|
void *tlv_data; /* TLV data */
|
|
|
unsigned long tlv_data_size; /* TLV data size */
|
|
@@ -1078,9 +1078,12 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
|
{
|
|
|
struct user_element *ue = kcontrol->private_data;
|
|
|
+ unsigned int size = ue->elem_data_size;
|
|
|
+ char *src = ue->elem_data +
|
|
|
+ snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
|
|
|
|
|
mutex_lock(&ue->card->user_ctl_lock);
|
|
|
- memcpy(&ucontrol->value, ue->elem_data, ue->elem_data_size);
|
|
|
+ memcpy(&ucontrol->value, src, size);
|
|
|
mutex_unlock(&ue->card->user_ctl_lock);
|
|
|
return 0;
|
|
|
}
|
|
@@ -1090,11 +1093,14 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
|
|
|
{
|
|
|
int change;
|
|
|
struct user_element *ue = kcontrol->private_data;
|
|
|
+ unsigned int size = ue->elem_data_size;
|
|
|
+ char *dst = ue->elem_data +
|
|
|
+ snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
|
|
|
|
|
mutex_lock(&ue->card->user_ctl_lock);
|
|
|
- change = memcmp(&ucontrol->value, ue->elem_data, ue->elem_data_size) != 0;
|
|
|
+ change = memcmp(&ucontrol->value, dst, size) != 0;
|
|
|
if (change)
|
|
|
- memcpy(ue->elem_data, &ucontrol->value, ue->elem_data_size);
|
|
|
+ memcpy(dst, &ucontrol->value, size);
|
|
|
mutex_unlock(&ue->card->user_ctl_lock);
|
|
|
return change;
|
|
|
}
|
|
@@ -1278,7 +1284,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
|
|
if (err < 0)
|
|
|
return err;
|
|
|
memcpy(&kctl->id, &info->id, sizeof(kctl->id));
|
|
|
- kctl->private_data = kzalloc(sizeof(struct user_element) + private_size,
|
|
|
+ kctl->private_data = kzalloc(sizeof(struct user_element) + private_size * count,
|
|
|
GFP_KERNEL);
|
|
|
if (kctl->private_data == NULL) {
|
|
|
kfree(kctl);
|