Update of /cvsroot/alsa/alsa-kernel/core In directory sc8-pr-cvs1:/tmp/cvs-serv17648/core
Modified Files: control.c Log Message: Control API update - separated volatile data from snd_kcontrol_t to reduce space for multi elements - added multi elements - changed trident driver to use multi elements - added dimen union to the info structure to describe matrix Index: control.c =================================================================== RCS file: /cvsroot/alsa/alsa-kernel/core/control.c,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- control.c 28 Feb 2003 13:05:04 -0000 1.28 +++ control.c 1 Apr 2003 13:55:43 -0000 1.29 @@ -106,6 +106,7 @@ snd_card_t *card; snd_ctl_file_t *ctl; snd_kcontrol_t *control; + unsigned int idx; ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO); fasync_helper(-1, file, 0, &ctl->fasync); @@ -117,8 +118,9 @@ down_write(&card->controls_rwsem); list_for_each(list, &card->controls) { control = snd_kcontrol(list); - if (control->owner == ctl) - control->owner = NULL; + for (idx = 0; idx < control->count; idx++) + if (control->vd[idx].owner == ctl) + control->vd[idx].owner = NULL; } up_write(&card->controls_rwsem); snd_ctl_empty_read_queue(ctl); @@ -163,8 +165,8 @@ } _found: wake_up(&ctl->change_sleep); - kill_fasync(&ctl->fasync, SIGIO, POLL_IN); spin_unlock_irqrestore(&ctl->read_lock, flags); + kill_fasync(&ctl->fasync, SIGIO, POLL_IN); } read_unlock(&card->ctl_files_rwlock); } @@ -172,21 +174,29 @@ /** * snd_ctl_new - create a control instance from the template * @control: the control template + * @access: the default control access * * Allocates a new snd_kcontrol_t instance and copies the given template - * to the new instance. + * to the new instance. It does not copy volatile data (access). * * Returns the pointer of the new instance, or NULL on failure. */ -snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control) +snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access) { snd_kcontrol_t *kctl; + unsigned int idx; snd_runtime_check(control != NULL, return NULL); - kctl = (snd_kcontrol_t *)snd_magic_kmalloc(snd_kcontrol_t, 0, GFP_KERNEL); + snd_runtime_check(control->count > 0, return NULL); + kctl = (snd_kcontrol_t *)snd_magic_kcalloc(snd_kcontrol_t, + sizeof(snd_kcontrol_volatile_t) * control->count, + GFP_KERNEL); if (kctl == NULL) return NULL; *kctl = *control; + kctl->vd = (snd_kcontrol_volatile_t *)(kctl + 1); + for (idx = 0; idx < kctl->count; idx++) + kctl->vd[idx].access = access; return kctl; } @@ -197,13 +207,14 @@ * * Allocates a new snd_kcontrol_t instance and initialize from the given * template. When the access field of ncontrol is 0, it's assumed as - * READWRITE access. + * READWRITE access. When the count field is 0, it's assumes as one. * * Returns the pointer of the newly generated instance, or NULL on failure. */ snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data) { snd_kcontrol_t kctl; + unsigned int access; snd_runtime_check(ncontrol != NULL, return NULL); snd_assert(ncontrol->info != NULL, return NULL); @@ -214,14 +225,16 @@ if (ncontrol->name) strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1); kctl.id.index = ncontrol->index; - kctl.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_INDIRECT)); + kctl.count = ncontrol->count ? ncontrol->count : 1; + 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)); kctl.info = ncontrol->info; kctl.get = ncontrol->get; kctl.put = ncontrol->put; kctl.private_value = ncontrol->private_value; kctl.private_data = private_data; - return snd_ctl_new(&kctl); + return snd_ctl_new(&kctl, access); } /** @@ -253,16 +266,20 @@ */ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol) { + snd_ctl_elem_id_t id; + unsigned int idx; + snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); snd_assert(kcontrol->info != NULL, return -EINVAL); - snd_assert(!(kcontrol->access & SNDRV_CTL_ELEM_ACCESS_READ) || kcontrol->get != NULL, return -EINVAL); - snd_assert(!(kcontrol->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kcontrol->put != NULL, return -EINVAL); down_write(&card->controls_rwsem); list_add_tail(&kcontrol->list, &card->controls); - card->controls_count++; - kcontrol->id.numid = ++card->last_numid; + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; up_write(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &kcontrol->id); + id = kcontrol->id; + for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; } @@ -278,12 +295,17 @@ */ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol) { + snd_ctl_elem_id_t id; + unsigned int idx; + snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); down_write(&card->controls_rwsem); list_del(&kcontrol->list); - card->controls_count--; + card->controls_count -= kcontrol->count; up_write(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &kcontrol->id); + id = kcontrol->id; + for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_REMOVE, &id); snd_ctl_free_one(kcontrol); return 0; } @@ -308,7 +330,8 @@ return snd_ctl_remove(card, kctl); } -static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */ +static snd_kcontrol_t *_ctl_find_id +(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */ /** * snd_ctl_rename_id - replace the id of a control on the card @@ -332,7 +355,8 @@ return -ENOENT; } kctl->id = *dst_id; - kctl->id.numid = ++card->last_numid; + kctl->id.numid = card->last_numid + 1; + card->last_numid += kctl->count; up_write(&card->controls_rwsem); return 0; } @@ -345,7 +369,7 @@ snd_runtime_check(card != NULL && numid != 0, return NULL); list_for_each(list, &card->controls) { kctl = snd_kcontrol(list); - if (kctl->id.numid == numid) + if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) return kctl; } return NULL; @@ -369,8 +393,14 @@ continue; if (strncmp(kctl->id.name, id->name, sizeof(kctl->id.name))) continue; - if (kctl->id.index != id->index) + if (kctl->id.index > id->index) + continue; + if (kctl->id.index + kctl->count <= id->index) + continue; + if (kctl->id.index != id->index) { + printk("BOOOR: %i, %i, %i\n", kctl->id.index, kctl->count, id->index); continue; + } return kctl; } return NULL; @@ -438,12 +468,13 @@ snd_ctl_elem_list_t list; snd_kcontrol_t *kctl; snd_ctl_elem_id_t *dst, *id; - int offset, space; + unsigned int offset, space, first, jidx; if (copy_from_user(&list, _list, sizeof(list))) return -EFAULT; offset = list.offset; space = list.space; + first = 0; /* try limit maximum space */ if (space > 16384) return -ENOMEM; @@ -455,17 +486,27 @@ down_read(&card->controls_rwsem); list.count = card->controls_count; plist = card->controls.next; - while (offset-- > 0 && plist != &card->controls) + while (plist != &card->controls) { + if (offset == 0) + break; + kctl = snd_kcontrol(plist); + if (offset < kctl->count) + break; + offset -= kctl->count; plist = plist->next; + } list.used = 0; id = dst; while (space > 0 && plist != &card->controls) { kctl = snd_kcontrol(plist); - memcpy(id, &kctl->id, sizeof(snd_ctl_elem_id_t)); - id++; + for (jidx = offset; space > 0 && jidx < kctl->count; jidx++) { + snd_ctl_build_ioff(id, kctl, jidx); + id++; + space--; + list.used++; + } plist = plist->next; - space--; - list.used++; + offset = 0; } up_read(&card->controls_rwsem); if (list.used > 0 && copy_to_user(list.pids, dst, list.used * sizeof(snd_ctl_elem_id_t))) @@ -486,6 +527,8 @@ snd_card_t *card = ctl->card; snd_ctl_elem_info_t info; snd_kcontrol_t *kctl; + snd_kcontrol_volatile_t *vd; + unsigned int index_offset; int result; if (copy_from_user(&info, _info, sizeof(info))) @@ -502,13 +545,15 @@ result = kctl->info(kctl, &info); if (result >= 0) { snd_assert(info.access == 0, ); - info.id = kctl->id; - info.access = kctl->access; - if (kctl->owner) { + index_offset = snd_ctl_get_ioff(kctl, &info.id); + vd = &kctl->vd[index_offset]; + snd_ctl_build_ioff(&info.id, kctl, index_offset); + info.access = vd->access; + if (vd->owner) { info.access |= SNDRV_CTL_ELEM_ACCESS_LOCK; - if (kctl->owner == ctl) + if (vd->owner == ctl) info.access |= SNDRV_CTL_ELEM_ACCESS_OWNER; - info.owner = kctl->owner_pid; + info.owner = vd->owner_pid; } else { info.owner = -1; } @@ -522,8 +567,11 @@ static int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *_control) { + snd_ctl_elem_value_t *control; snd_kcontrol_t *kctl; + snd_kcontrol_volatile_t *vd; + unsigned int index_offset; int result, indirect; control = kmalloc(sizeof(*control), GFP_KERNEL); @@ -536,16 +584,18 @@ if (kctl == NULL) { result = -ENOENT; } else { - indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; + 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 ((kctl->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get != NULL) { + 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); - if (result >= 0) - control->id = kctl->id; - } else + } else { result = -EPERM; + } } } up_read(&card->controls_rwsem); @@ -561,6 +611,8 @@ snd_card_t *card = file->card; snd_ctl_elem_value_t *control; snd_kcontrol_t *kctl; + snd_kcontrol_volatile_t *vd; + unsigned int index_offset; int result, indirect; control = kmalloc(sizeof(*control), GFP_KERNEL); @@ -573,22 +625,23 @@ if (kctl == NULL) { result = -ENOENT; } else { - indirect = kctl->access & SNDRV_CTL_ELEM_ACCESS_INDIRECT ? 1 : 0; + 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 (!(kctl->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL || - (kctl->owner != NULL && kctl->owner != 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) - control->id = kctl->id; } if (result > 0) { up_read(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &control->id); result = 0; goto __unlocked; } @@ -608,6 +661,7 @@ snd_card_t *card = file->card; snd_ctl_elem_id_t id; snd_kcontrol_t *kctl; + snd_kcontrol_volatile_t *vd; int result; if (copy_from_user(&id, _id, sizeof(id))) @@ -617,11 +671,12 @@ if (kctl == NULL) { result = -ENOENT; } else { - if (kctl->owner != NULL) + vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)]; + if (vd->owner != NULL) result = -EBUSY; else { - kctl->owner = file; - kctl->owner_pid = current->pid; + vd->owner = file; + vd->owner_pid = current->pid; result = 0; } } @@ -634,6 +689,7 @@ snd_card_t *card = file->card; snd_ctl_elem_id_t id; snd_kcontrol_t *kctl; + snd_kcontrol_volatile_t *vd; int result; if (copy_from_user(&id, _id, sizeof(id))) @@ -643,13 +699,14 @@ if (kctl == NULL) { result = -ENOENT; } else { - if (kctl->owner == NULL) + vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)]; + if (vd->owner == NULL) result = -EINVAL; - else if (kctl->owner != file) + else if (vd->owner != file) result = -EPERM; else { - kctl->owner = NULL; - kctl->owner_pid = 0; + vd->owner = NULL; + vd->owner_pid = 0; result = 0; } } ------------------------------------------------------- This SF.net email is sponsored by: ValueWeb: Dedicated Hosting for just $79/mo with 500 GB of bandwidth! No other company gives more support or power for your dedicated server http://click.atdmt.com/AFF/go/sdnxxaff00300020aff/direct/01/ _______________________________________________ Alsa-cvslog mailing list [EMAIL PROTECTED] https://lists.sourceforge.net/lists/listinfo/alsa-cvslog