Hi,
this is the patch to remove indirect control access. In this version, I left the pointers in snd_ctl_elem_* struct but added/changed comments because the pointer member might influence on alignment. After confirming that it doesn't affect, we can get rid of them.
Takashi
diff -r 83ddcb1104e6 core/control.c --- a/core/control.c Thu Dec 20 18:15:07 2007 +0100 +++ b/core/control.c Thu Dec 20 18:17:08 2007 +0100 @@ -232,8 +232,6 @@ struct snd_kcontrol *snd_ctl_new1(const access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 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_CALLBACK)); kctl.info = ncontrol->info; @@ -692,7 +690,7 @@ int snd_ctl_elem_read(struct snd_card *c struct snd_kcontrol *kctl; struct snd_kcontrol_volatile *vd; unsigned int index_offset; - int result, indirect; + int result;
down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); @@ -701,17 +699,12 @@ int snd_ctl_elem_read(struct snd_card *c } else { index_offset = snd_ctl_get_ioff(kctl, &control->id); 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); return result; @@ -748,7 +741,7 @@ int snd_ctl_elem_write(struct snd_card * struct snd_kcontrol *kctl; struct snd_kcontrol_volatile *vd; unsigned int index_offset; - int result, indirect; + int result;
down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); @@ -757,23 +750,19 @@ int snd_ctl_elem_write(struct snd_card * } else { index_offset = snd_ctl_get_ioff(kctl, &control->id); 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 { - 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); diff -r 83ddcb1104e6 include/asound.h --- a/include/asound.h Thu Dec 20 18:15:07 2007 +0100 +++ b/include/asound.h Thu Dec 20 18:17:08 2007 +0100 @@ -745,8 +745,7 @@ typedef int __bitwise snd_ctl_elem_iface #define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */ #define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28) /* kernel use a TLV callback */ #define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */ -#define SNDRV_CTL_ELEM_ACCESS_DINDIRECT (1<<30) /* indirect access for matrix dimensions in the info structure */ -#define SNDRV_CTL_ELEM_ACCESS_INDIRECT (1<<31) /* indirect access for element value in the value structure */ +/* bits 30 and 31 are obsoleted (for indirect access) */
/* for further details see the ACPI and PCI power management specification */ #define SNDRV_CTL_POWER_D0 0x0000 /* full On */ @@ -800,30 +799,30 @@ struct snd_ctl_elem_info { } value; union { unsigned short d[4]; /* dimensions */ - unsigned short *d_ptr; /* indirect */ + unsigned short *d_ptr; /* indirect - obsoleted */ } dimen; unsigned char reserved[64-4*sizeof(unsigned short)]; };
struct snd_ctl_elem_value { struct snd_ctl_elem_id id; /* W: element ID */ - unsigned int indirect: 1; /* W: use indirect pointer (xxx_ptr member) */ + unsigned int indirect: 1; /* W: indirect access - obsoleted */ union { union { long value[128]; - long *value_ptr; + long *value_ptr; /* obsoleted */ } integer; union { long long value[64]; - long long *value_ptr; + long long *value_ptr; /* obsoleted */ } integer64; union { unsigned int item[128]; - unsigned int *item_ptr; + unsigned int *item_ptr; /* obsoleted */ } enumerated; union { unsigned char data[512]; - unsigned char *data_ptr; + unsigned char *data_ptr; /* obsoleted */ } bytes; struct snd_aes_iec958 iec958; } value; /* RO */