]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/core/control.c
[ALSA] Fix compile warning in timer.c
[mv-sheeva.git] / sound / core / control.c
index 1a14338bd51623ad82d2edce18fd53fba1068384..bb397eaa718793cb977687628eed02a9d4477907 100644 (file)
@@ -47,13 +47,12 @@ static LIST_HEAD(snd_control_compat_ioctls);
 
 static int snd_ctl_open(struct inode *inode, struct file *file)
 {
-       int cardnum = SNDRV_MINOR_CARD(iminor(inode));
        unsigned long flags;
        struct snd_card *card;
        struct snd_ctl_file *ctl;
        int err;
 
-       card = snd_cards[cardnum];
+       card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
        if (!card) {
                err = -ENODEV;
                goto __error1;
@@ -177,6 +176,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
        read_unlock(&card->ctl_files_rwlock);
 }
 
+EXPORT_SYMBOL(snd_ctl_notify);
+
 /**
  * snd_ctl_new - create a control instance from the template
  * @control: the control template
@@ -195,14 +196,18 @@ struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int acce
        snd_assert(control != NULL, return NULL);
        snd_assert(control->count > 0, return NULL);
        kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
-       if (kctl == NULL)
+       if (kctl == NULL) {
+               snd_printk(KERN_ERR "Cannot allocate control instance\n");
                return NULL;
+       }
        *kctl = *control;
        for (idx = 0; idx < kctl->count; idx++)
                kctl->vd[idx].access = access;
        return kctl;
 }
 
+EXPORT_SYMBOL(snd_ctl_new);
+
 /**
  * snd_ctl_new1 - create a control instance from the template
  * @ncontrol: the initialization record
@@ -241,6 +246,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
        return snd_ctl_new(&kctl, access);
 }
 
+EXPORT_SYMBOL(snd_ctl_new1);
+
 /**
  * snd_ctl_free_one - release the control instance
  * @kcontrol: the control instance
@@ -258,6 +265,8 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
        }
 }
 
+EXPORT_SYMBOL(snd_ctl_free_one);
+
 static unsigned int snd_ctl_hole_check(struct snd_card *card,
                                       unsigned int count)
 {
@@ -308,26 +317,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
 {
        struct snd_ctl_elem_id id;
        unsigned int idx;
+       int err = -EINVAL;
 
-       snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
-       snd_assert(kcontrol->info != NULL, return -EINVAL);
+       if (! kcontrol)
+               return err;
+       snd_assert(card != NULL, goto error);
+       snd_assert(kcontrol->info != NULL, goto error);
        id = kcontrol->id;
        down_write(&card->controls_rwsem);
        if (snd_ctl_find_id(card, &id)) {
                up_write(&card->controls_rwsem);
-               snd_ctl_free_one(kcontrol);
                snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n",
                                        id.iface,
                                        id.device,
                                        id.subdevice,
                                        id.name,
                                        id.index);
-               return -EBUSY;
+               err = -EBUSY;
+               goto error;
        }
        if (snd_ctl_find_hole(card, kcontrol->count) < 0) {
                up_write(&card->controls_rwsem);
-               snd_ctl_free_one(kcontrol);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto error;
        }
        list_add_tail(&kcontrol->list, &card->controls);
        card->controls_count += kcontrol->count;
@@ -337,8 +349,14 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
        for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++)
                snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id);
        return 0;
+
+ error:
+       snd_ctl_free_one(kcontrol);
+       return err;
 }
 
+EXPORT_SYMBOL(snd_ctl_add);
+
 /**
  * snd_ctl_remove - remove the control from the card and release it
  * @card: the card instance
@@ -365,6 +383,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
        return 0;
 }
 
+EXPORT_SYMBOL(snd_ctl_remove);
+
 /**
  * snd_ctl_remove_id - remove the control of the given id and release it
  * @card: the card instance
@@ -391,6 +411,8 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
        return ret;
 }
 
+EXPORT_SYMBOL(snd_ctl_remove_id);
+
 /**
  * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it
  * @file: active control handle
@@ -453,6 +475,8 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
        return 0;
 }
 
+EXPORT_SYMBOL(snd_ctl_rename_id);
+
 /**
  * snd_ctl_find_numid - find the control instance with the given number-id
  * @card: the card instance
@@ -479,6 +503,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
        return NULL;
 }
 
+EXPORT_SYMBOL(snd_ctl_find_numid);
+
 /**
  * snd_ctl_find_id - find the control instance with the given id
  * @card: the card instance
@@ -519,6 +545,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
        return NULL;
 }
 
+EXPORT_SYMBOL(snd_ctl_find_id);
+
 static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
                             unsigned int cmd, void __user *arg)
 {
@@ -655,7 +683,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
 
        if (copy_from_user(&info, _info, sizeof(info)))
                return -EFAULT;
-       result = snd_ctl_elem_info(ctl, &info);
+       snd_power_lock(ctl->card);
+       result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
+       if (result >= 0)
+               result = snd_ctl_elem_info(ctl, &info);
+       snd_power_unlock(ctl->card);
        if (result >= 0)
                if (copy_to_user(_info, &info, sizeof(info)))
                        return -EFAULT;
@@ -692,6 +724,8 @@ int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
        return result;
 }
 
+EXPORT_SYMBOL(snd_ctl_elem_read);
+
 static int snd_ctl_elem_read_user(struct snd_card *card,
                                  struct snd_ctl_elem_value __user *_control)
 {
@@ -705,7 +739,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
                kfree(control);
                return -EFAULT;
        }
-       result = snd_ctl_elem_read(card, control);
+       snd_power_lock(card);
+       result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
+       if (result >= 0)
+               result = snd_ctl_elem_read(card, control);
+       snd_power_unlock(card);
        if (result >= 0)
                if (copy_to_user(_control, control, sizeof(*control)))
                        result = -EFAULT;
@@ -751,10 +789,13 @@ int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
        return result;
 }
 
+EXPORT_SYMBOL(snd_ctl_elem_write);
+
 static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
                                   struct snd_ctl_elem_value __user *_control)
 {
        struct snd_ctl_elem_value *control;
+       struct snd_card *card;
        int result;
 
        control = kmalloc(sizeof(*control), GFP_KERNEL);
@@ -764,7 +805,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
                kfree(control);
                return -EFAULT;
        }
-       result = snd_ctl_elem_write(file->card, file, control);
+       card = file->card;
+       snd_power_lock(card);
+       result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
+       if (result >= 0)
+               result = snd_ctl_elem_write(card, file, control);
+       snd_power_unlock(card);
        if (result >= 0)
                if (copy_to_user(_control, control, sizeof(*control)))
                        result = -EFAULT;
@@ -956,17 +1002,15 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
        kctl.private_free = snd_ctl_elem_user_free;
        _kctl = snd_ctl_new(&kctl, access);
        if (_kctl == NULL) {
-               kfree(_kctl->private_data);
+               kfree(ue);
                return -ENOMEM;
        }
        _kctl->private_data = ue;
        for (idx = 0; idx < _kctl->count; idx++)
                _kctl->vd[idx].owner = file;
        err = snd_ctl_add(card, _kctl);
-       if (err < 0) {
-               snd_ctl_free_one(_kctl);
+       if (err < 0)
                return err;
-       }
 
        down_write(&card->controls_rwsem);
        card->user_ctl_count++;
@@ -1023,36 +1067,6 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
        return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * change the power state
- */
-static int snd_ctl_set_power_state(struct snd_card *card, unsigned int power_state)
-{
-       switch (power_state) {
-       case SNDRV_CTL_POWER_D0:
-               if (card->power_state != power_state) {
-                       card->pm_resume(card);
-                       snd_power_change_state(card, power_state);
-               }
-               break;
-       case SNDRV_CTL_POWER_D3hot:
-               if (card->power_state != power_state) {
-                       card->pm_suspend(card, PMSG_SUSPEND);
-                       snd_power_change_state(card, power_state);
-               }
-               break;
-       case SNDRV_CTL_POWER_D1:
-       case SNDRV_CTL_POWER_D2:
-       case SNDRV_CTL_POWER_D3cold:
-               /* not supported yet */
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-#endif
-
 static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct snd_ctl_file *ctl;
@@ -1092,19 +1106,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
        case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
                return snd_ctl_subscribe_events(ctl, ip);
        case SNDRV_CTL_IOCTL_POWER:
-               if (get_user(err, ip))
-                       return -EFAULT;
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-#ifdef CONFIG_PM
-               if (card->pm_suspend && card->pm_resume) {
-                       snd_power_lock(card);
-                       err = snd_ctl_set_power_state(card, err);
-                       snd_power_unlock(card);
-               } else
-#endif
-                       err = -ENOPROTOOPT;
-               return err;
+               return -ENOPROTOOPT;
        case SNDRV_CTL_IOCTL_POWER_STATE:
 #ifdef CONFIG_PM
                return put_user(card->power_state, ip) ? -EFAULT : 0;
@@ -1221,11 +1223,15 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
        return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
 }
 
+EXPORT_SYMBOL(snd_ctl_register_ioctl);
+
 #ifdef CONFIG_COMPAT
 int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
 {
        return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
 }
+
+EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
 #endif
 
 /*
@@ -1258,12 +1264,15 @@ int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
        return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
 }
 
+EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
+
 #ifdef CONFIG_COMPAT
 int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
 {
        return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
 }
 
+EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
 #endif
 
 static int snd_ctl_fasync(int fd, struct file * file, int on)
@@ -1302,12 +1311,6 @@ static struct file_operations snd_ctl_f_ops =
        .fasync =       snd_ctl_fasync,
 };
 
-static struct snd_minor snd_ctl_reg =
-{
-       .comment =      "ctl",
-       .f_ops =        &snd_ctl_f_ops,
-};
-
 /*
  * registration of the control device
  */
@@ -1321,8 +1324,8 @@ static int snd_ctl_dev_register(struct snd_device *device)
        cardnum = card->number;
        snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
        sprintf(name, "controlC%i", cardnum);
-       if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,
-                                       card, 0, &snd_ctl_reg, name)) < 0)
+       if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
+                                      &snd_ctl_f_ops, card, name)) < 0)
                return err;
        return 0;
 }
@@ -1374,7 +1377,8 @@ static int snd_ctl_dev_unregister(struct snd_device *device)
        snd_assert(card != NULL, return -ENXIO);
        cardnum = card->number;
        snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
-       if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
+       if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
+                                        card, -1)) < 0)
                return err;
        return snd_ctl_dev_free(device);
 }