|
@@ -232,8 +232,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
|
|
access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
|
access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
|
(ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
|
|
(ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
|
|
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
|
|
SNDRV_CTL_ELEM_ACCESS_INACTIVE|
|
|
- SNDRV_CTL_ELEM_ACCESS_DINDIRECT|
|
|
|
|
- SNDRV_CTL_ELEM_ACCESS_INDIRECT|
|
|
|
|
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
|
|
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
|
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
|
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK));
|
|
kctl.info = ncontrol->info;
|
|
kctl.info = ncontrol->info;
|
|
@@ -692,7 +690,7 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
|
|
struct snd_kcontrol *kctl;
|
|
struct snd_kcontrol *kctl;
|
|
struct snd_kcontrol_volatile *vd;
|
|
struct snd_kcontrol_volatile *vd;
|
|
unsigned int index_offset;
|
|
unsigned int index_offset;
|
|
- int result, indirect;
|
|
|
|
|
|
+ int result;
|
|
|
|
|
|
down_read(&card->controls_rwsem);
|
|
down_read(&card->controls_rwsem);
|
|
kctl = snd_ctl_find_id(card, &control->id);
|
|
kctl = snd_ctl_find_id(card, &control->id);
|
|
@@ -701,17 +699,12 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
|
|
} else {
|
|
} else {
|
|
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
|
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
|
vd = &kctl->vd[index_offset];
|
|
vd = &kctl->vd[index_offset];
|
|
- indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
|
|
|
|
- if (control->indirect != indirect) {
|
|
|
|
- result = -EACCES;
|
|
|
|
- } else {
|
|
|
|
- if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) {
|
|
|
|
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
|
|
|
- result = kctl->get(kctl, control);
|
|
|
|
- } else {
|
|
|
|
- result = -EPERM;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
|
|
|
|
+ kctl->get != NULL) {
|
|
|
|
+ snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
|
|
|
+ result = kctl->get(kctl, control);
|
|
|
|
+ } else
|
|
|
|
+ result = -EPERM;
|
|
}
|
|
}
|
|
up_read(&card->controls_rwsem);
|
|
up_read(&card->controls_rwsem);
|
|
return result;
|
|
return result;
|
|
@@ -748,7 +741,7 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
|
|
struct snd_kcontrol *kctl;
|
|
struct snd_kcontrol *kctl;
|
|
struct snd_kcontrol_volatile *vd;
|
|
struct snd_kcontrol_volatile *vd;
|
|
unsigned int index_offset;
|
|
unsigned int index_offset;
|
|
- int result, indirect;
|
|
|
|
|
|
+ int result;
|
|
|
|
|
|
down_read(&card->controls_rwsem);
|
|
down_read(&card->controls_rwsem);
|
|
kctl = snd_ctl_find_id(card, &control->id);
|
|
kctl = snd_ctl_find_id(card, &control->id);
|
|
@@ -757,23 +750,19 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
|
|
} else {
|
|
} else {
|
|
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
|
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
|
vd = &kctl->vd[index_offset];
|
|
vd = &kctl->vd[index_offset];
|
|
- indirect = vd->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0;
|
|
|
|
- if (control->indirect != indirect) {
|
|
|
|
- result = -EACCES;
|
|
|
|
|
|
+ if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
|
|
|
|
+ kctl->put == NULL ||
|
|
|
|
+ (file && vd->owner && vd->owner != file)) {
|
|
|
|
+ result = -EPERM;
|
|
} else {
|
|
} else {
|
|
- if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
|
|
|
|
- kctl->put == NULL ||
|
|
|
|
- (file && vd->owner != NULL && vd->owner != file)) {
|
|
|
|
- result = -EPERM;
|
|
|
|
- } else {
|
|
|
|
- snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
|
|
|
- result = kctl->put(kctl, control);
|
|
|
|
- }
|
|
|
|
- if (result > 0) {
|
|
|
|
- up_read(&card->controls_rwsem);
|
|
|
|
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
|
|
|
+ result = kctl->put(kctl, control);
|
|
|
|
+ }
|
|
|
|
+ if (result > 0) {
|
|
|
|
+ up_read(&card->controls_rwsem);
|
|
|
|
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
|
|
|
|
+ &control->id);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
up_read(&card->controls_rwsem);
|
|
up_read(&card->controls_rwsem);
|