Merge commit alsa/devel into topic/misc
[safe/jmp/linux-2.6] / sound / core / hwdep.c
index 618c43b..a70ee7f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Hardware dependent layer
- *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  *
  *
  *   This program is free software; you can redistribute it and/or modify
  *
  */
 
-#include <sound/driver.h>
 #include <linux/major.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/mutex.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/minors.h>
 #include <sound/hwdep.h>
 #include <sound/info.h>
 
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
+MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
 MODULE_DESCRIPTION("Hardware dependent layer");
 MODULE_LICENSE("GPL");
 
 static LIST_HEAD(snd_hwdep_devices);
-static DECLARE_MUTEX(register_mutex);
+static DEFINE_MUTEX(register_mutex);
 
 static int snd_hwdep_free(struct snd_hwdep *hwdep);
 static int snd_hwdep_dev_free(struct snd_device *device);
 static int snd_hwdep_dev_register(struct snd_device *device);
-static int snd_hwdep_dev_unregister(struct snd_device *device);
+static int snd_hwdep_dev_disconnect(struct snd_device *device);
 
 
 static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device)
 {
-       struct list_head *p;
        struct snd_hwdep *hwdep;
 
-       list_for_each(p, &snd_hwdep_devices) {
-               hwdep = list_entry(p, struct snd_hwdep, list);
+       list_for_each_entry(hwdep, &snd_hwdep_devices, list)
                if (hwdep->card == card && hwdep->device == device)
                        return hwdep;
-       }
        return NULL;
 }
 
@@ -103,20 +99,21 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
        if (hw == NULL)
                return -ENODEV;
 
-       if (!hw->ops.open)
-               return -ENXIO;
-
        if (!try_module_get(hw->card->module))
                return -EFAULT;
 
        init_waitqueue_entry(&wait, current);
        add_wait_queue(&hw->open_wait, &wait);
-       down(&hw->open_mutex);
+       mutex_lock(&hw->open_mutex);
        while (1) {
                if (hw->exclusive && hw->used > 0) {
                        err = -EBUSY;
                        break;
                }
+               if (!hw->ops.open) {
+                       err = 0;
+                       break;
+               }
                err = hw->ops.open(hw, file);
                if (err >= 0)
                        break;
@@ -128,9 +125,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
                } else
                        break;
                set_current_state(TASK_INTERRUPTIBLE);
-               up(&hw->open_mutex);
+               mutex_unlock(&hw->open_mutex);
                schedule();
-               down(&hw->open_mutex);
+               mutex_lock(&hw->open_mutex);
                if (signal_pending(current)) {
                        err = -ERESTARTSYS;
                        break;
@@ -147,7 +144,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
                                hw->ops.release(hw, file);
                }
        }
-       up(&hw->open_mutex);
+       mutex_unlock(&hw->open_mutex);
        if (err < 0)
                module_put(hw->card->module);
        return err;
@@ -155,18 +152,20 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
 
 static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
-       int err = -ENXIO;
+       int err = 0;
        struct snd_hwdep *hw = file->private_data;
-       down(&hw->open_mutex);
-       if (hw->ops.release) {
+       struct module *mod = hw->card->module;
+
+       mutex_lock(&hw->open_mutex);
+       if (hw->ops.release)
                err = hw->ops.release(hw, file);
-               wake_up(&hw->open_wait);
-       }
        if (hw->used > 0)
                hw->used--;
+       mutex_unlock(&hw->open_mutex);
+       wake_up(&hw->open_wait);
+
        snd_card_file_remove(hw->card, file);
-       up(&hw->open_mutex);
-       module_put(hw->card->module);
+       module_put(mod);
        return err;
 }
 
@@ -272,7 +271,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
 
                        if (get_user(device, (int __user *)arg))
                                return -EFAULT;
-                       down(&register_mutex);
+                       mutex_lock(&register_mutex);
                        device = device < 0 ? 0 : device + 1;
                        while (device < SNDRV_MINOR_HWDEPS) {
                                if (snd_hwdep_search(card, device))
@@ -281,7 +280,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
                        }
                        if (device >= SNDRV_MINOR_HWDEPS)
                                device = -1;
-                       up(&register_mutex);
+                       mutex_unlock(&register_mutex);
                        if (put_user(device, (int __user *)arg))
                                return -EFAULT;
                        return 0;
@@ -294,13 +293,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
 
                        if (get_user(device, &info->device))
                                return -EFAULT;
-                       down(&register_mutex);
+                       mutex_lock(&register_mutex);
                        hwdep = snd_hwdep_search(card, device);
                        if (hwdep)
                                err = snd_hwdep_info(hwdep, info);
                        else
                                err = -ENXIO;
-                       up(&register_mutex);
+                       mutex_unlock(&register_mutex);
                        return err;
                }
        }
@@ -317,7 +316,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
 
  */
 
-static struct file_operations snd_hwdep_f_ops =
+static const struct file_operations snd_hwdep_f_ops =
 {
        .owner =        THIS_MODULE,
        .llseek =       snd_hwdep_llseek,
@@ -352,12 +351,13 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
        static struct snd_device_ops ops = {
                .dev_free = snd_hwdep_dev_free,
                .dev_register = snd_hwdep_dev_register,
-               .dev_unregister = snd_hwdep_dev_unregister
+               .dev_disconnect = snd_hwdep_dev_disconnect,
        };
 
-       snd_assert(rhwdep != NULL, return -EINVAL);
-       *rhwdep = NULL;
-       snd_assert(card != NULL, return -ENXIO);
+       if (snd_BUG_ON(!card))
+               return -ENXIO;
+       if (rhwdep)
+               *rhwdep = NULL;
        hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
        if (hwdep == NULL) {
                snd_printk(KERN_ERR "hwdep: cannot allocate\n");
@@ -375,14 +375,16 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
                return err;
        }
        init_waitqueue_head(&hwdep->open_wait);
-       init_MUTEX(&hwdep->open_mutex);
-       *rhwdep = hwdep;
+       mutex_init(&hwdep->open_mutex);
+       if (rhwdep)
+               *rhwdep = hwdep;
        return 0;
 }
 
 static int snd_hwdep_free(struct snd_hwdep *hwdep)
 {
-       snd_assert(hwdep != NULL, return -ENXIO);
+       if (!hwdep)
+               return 0;
        if (hwdep->private_free)
                hwdep->private_free(hwdep);
        kfree(hwdep);
@@ -401,9 +403,9 @@ static int snd_hwdep_dev_register(struct snd_device *device)
        int err;
        char name[32];
 
-       down(&register_mutex);
+       mutex_lock(&register_mutex);
        if (snd_hwdep_search(hwdep->card, hwdep->device)) {
-               up(&register_mutex);
+               mutex_unlock(&register_mutex);
                return -EBUSY;
        }
        list_add_tail(&hwdep->list, &snd_hwdep_devices);
@@ -414,7 +416,7 @@ static int snd_hwdep_dev_register(struct snd_device *device)
                snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
                           hwdep->card->number, hwdep->device);
                list_del(&hwdep->list);
-               up(&register_mutex);
+               mutex_unlock(&register_mutex);
                return err;
        }
 #ifdef CONFIG_SND_OSSEMUL
@@ -434,18 +436,19 @@ static int snd_hwdep_dev_register(struct snd_device *device)
                }
        }
 #endif
-       up(&register_mutex);
+       mutex_unlock(&register_mutex);
        return 0;
 }
 
-static int snd_hwdep_dev_unregister(struct snd_device *device)
+static int snd_hwdep_dev_disconnect(struct snd_device *device)
 {
        struct snd_hwdep *hwdep = device->device_data;
 
-       snd_assert(hwdep != NULL, return -ENXIO);
-       down(&register_mutex);
+       if (snd_BUG_ON(!hwdep))
+               return -ENXIO;
+       mutex_lock(&register_mutex);
        if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
-               up(&register_mutex);
+               mutex_unlock(&register_mutex);
                return -EINVAL;
        }
 #ifdef CONFIG_SND_OSSEMUL
@@ -453,9 +456,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
                snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
 #endif
        snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
-       list_del(&hwdep->list);
-       up(&register_mutex);
-       return snd_hwdep_free(hwdep);
+       list_del_init(&hwdep->list);
+       mutex_unlock(&register_mutex);
+       return 0;
 }
 
 #ifdef CONFIG_PROC_FS
@@ -466,16 +469,13 @@ static int snd_hwdep_dev_unregister(struct snd_device *device)
 static void snd_hwdep_proc_read(struct snd_info_entry *entry,
                                struct snd_info_buffer *buffer)
 {
-       struct list_head *p;
        struct snd_hwdep *hwdep;
 
-       down(&register_mutex);
-       list_for_each(p, &snd_hwdep_devices) {
-               hwdep = list_entry(p, struct snd_hwdep, list);
+       mutex_lock(&register_mutex);
+       list_for_each_entry(hwdep, &snd_hwdep_devices, list)
                snd_iprintf(buffer, "%02i-%02i: %s\n",
                            hwdep->card->number, hwdep->device, hwdep->name);
-       }
-       up(&register_mutex);
+       mutex_unlock(&register_mutex);
 }
 
 static struct snd_info_entry *snd_hwdep_proc_entry;
@@ -485,7 +485,6 @@ static void __init snd_hwdep_proc_init(void)
        struct snd_info_entry *entry;
 
        if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
-               entry->c.text.read_size = PAGE_SIZE;
                entry->c.text.read = snd_hwdep_proc_read;
                if (snd_info_register(entry) < 0) {
                        snd_info_free_entry(entry);
@@ -497,7 +496,7 @@ static void __init snd_hwdep_proc_init(void)
 
 static void __exit snd_hwdep_proc_done(void)
 {
-       snd_info_unregister(snd_hwdep_proc_entry);
+       snd_info_free_entry(snd_hwdep_proc_entry);
 }
 #else /* !CONFIG_PROC_FS */
 #define snd_hwdep_proc_init()