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

Reply via email to