[Bluetooth] Fix reference count when connection lookup fails
[pandora-kernel.git] / sound / core / hwdep.c
index 618c43b..46b4768 100644 (file)
@@ -25,6 +25,7 @@
 #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>
@@ -36,12 +37,12 @@ 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)
@@ -111,7 +112,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
 
        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;
@@ -128,9 +129,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 +148,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;
@@ -157,7 +158,8 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
        int err = -ENXIO;
        struct snd_hwdep *hw = file->private_data;
-       down(&hw->open_mutex);
+       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);
@@ -165,8 +167,8 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
        if (hw->used > 0)
                hw->used--;
        snd_card_file_remove(hw->card, file);
-       up(&hw->open_mutex);
-       module_put(hw->card->module);
+       mutex_unlock(&hw->open_mutex);
+       module_put(mod);
        return err;
 }
 
@@ -272,7 +274,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 +283,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 +296,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;
                }
        }
@@ -352,7 +354,7 @@ 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);
@@ -375,7 +377,7 @@ 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);
+       mutex_init(&hwdep->open_mutex);
        *rhwdep = hwdep;
        return 0;
 }
@@ -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,18 @@ 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);
+       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 +455,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
@@ -469,13 +471,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
        struct list_head *p;
        struct snd_hwdep *hwdep;
 
-       down(&register_mutex);
+       mutex_lock(&register_mutex);
        list_for_each(p, &snd_hwdep_devices) {
                hwdep = list_entry(p, struct snd_hwdep, 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 +487,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 +498,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()