fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / core / seq / seq_device.c
index 9ece443..b79d011 100644 (file)
@@ -45,6 +45,7 @@
 #include <sound/initval.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
 
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
 MODULE_DESCRIPTION("ALSA sequencer device management");
@@ -69,7 +70,7 @@ struct ops_list {
        struct list_head dev_list;      /* list of devices */
        int num_devices;        /* number of associated devices */
        int num_init_devices;   /* number of initialized devices */
-       struct semaphore reg_mutex;
+       struct mutex reg_mutex;
 
        struct list_head list;  /* next driver */
 };
@@ -77,9 +78,9 @@ struct ops_list {
 
 static LIST_HEAD(opslist);
 static int num_ops;
-static DECLARE_MUTEX(ops_mutex);
+static DEFINE_MUTEX(ops_mutex);
 #ifdef CONFIG_PROC_FS
-static struct snd_info_entry *info_entry = NULL;
+static struct snd_info_entry *info_entry;
 #endif
 
 /*
@@ -89,7 +90,6 @@ static int snd_seq_device_free(struct snd_seq_device *dev);
 static int snd_seq_device_dev_free(struct snd_device *device);
 static int snd_seq_device_dev_register(struct snd_device *device);
 static int snd_seq_device_dev_disconnect(struct snd_device *device);
-static int snd_seq_device_dev_unregister(struct snd_device *device);
 
 static int init_device(struct snd_seq_device *dev, struct ops_list *ops);
 static int free_device(struct snd_seq_device *dev, struct ops_list *ops);
@@ -108,7 +108,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
 {
        struct list_head *head;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        list_for_each(head, &opslist) {
                struct ops_list *ops = list_entry(head, struct ops_list, list);
                snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
@@ -118,7 +118,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
                                ops->driver & DRIVER_LOCKED ? ",locked" : "",
                                ops->num_devices);
        }
-       up(&ops_mutex); 
+       mutex_unlock(&ops_mutex);
 }
 #endif
  
@@ -154,20 +154,20 @@ void snd_seq_device_load_drivers(void)
        if (! current->fs->root)
                return;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        list_for_each(head, &opslist) {
                struct ops_list *ops = list_entry(head, struct ops_list, list);
                if (! (ops->driver & DRIVER_LOADED) &&
                    ! (ops->driver & DRIVER_REQUESTED)) {
                        ops->used++;
-                       up(&ops_mutex);
+                       mutex_unlock(&ops_mutex);
                        ops->driver |= DRIVER_REQUESTED;
                        request_module("snd-%s", ops->id);
-                       down(&ops_mutex);
+                       mutex_lock(&ops_mutex);
                        ops->used--;
                }
        }
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 #endif
 }
 
@@ -188,7 +188,6 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
                .dev_free = snd_seq_device_dev_free,
                .dev_register = snd_seq_device_dev_register,
                .dev_disconnect = snd_seq_device_dev_disconnect,
-               .dev_unregister = snd_seq_device_dev_unregister
        };
 
        if (result)
@@ -214,10 +213,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
        dev->status = SNDRV_SEQ_DEVICE_FREE;
 
        /* add this device to the list */
-       down(&ops->reg_mutex);
+       mutex_lock(&ops->reg_mutex);
        list_add_tail(&dev->list, &ops->dev_list);
        ops->num_devices++;
-       up(&ops->reg_mutex);
+       mutex_unlock(&ops->reg_mutex);
 
        unlock_driver(ops);
        
@@ -246,10 +245,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev)
                return -ENXIO;
 
        /* remove the device from the list */
-       down(&ops->reg_mutex);
+       mutex_lock(&ops->reg_mutex);
        list_del(&dev->list);
        ops->num_devices--;
-       up(&ops->reg_mutex);
+       mutex_unlock(&ops->reg_mutex);
 
        free_device(dev, ops);
        if (dev->private_free)
@@ -307,15 +306,6 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device)
        return 0;
 }
 
-/*
- * unregister the existing device
- */
-static int snd_seq_device_dev_unregister(struct snd_device *device)
-{
-       struct snd_seq_device *dev = device->device_data;
-       return snd_seq_device_free(dev);
-}
-
 /*
  * register device driver
  * id = driver id
@@ -344,7 +334,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
                return -EBUSY;
        }
 
-       down(&ops->reg_mutex);
+       mutex_lock(&ops->reg_mutex);
        /* copy driver operators */
        ops->ops = *entry;
        ops->driver |= DRIVER_LOADED;
@@ -355,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
                struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
                init_device(dev, ops);
        }
-       up(&ops->reg_mutex);
+       mutex_unlock(&ops->reg_mutex);
 
        unlock_driver(ops);
        snd_seq_autoload_unlock();
@@ -371,24 +361,29 @@ static struct ops_list * create_driver(char *id)
 {
        struct ops_list *ops;
 
-       ops = kmalloc(sizeof(*ops), GFP_KERNEL);
+       ops = kzalloc(sizeof(*ops), GFP_KERNEL);
        if (ops == NULL)
                return ops;
-       memset(ops, 0, sizeof(*ops));
 
        /* set up driver entry */
        strlcpy(ops->id, id, sizeof(ops->id));
-       init_MUTEX(&ops->reg_mutex);
+       mutex_init(&ops->reg_mutex);
+       /*
+        * The ->reg_mutex locking rules are per-driver, so we create
+        * separate per-driver lock classes:
+        */
+       lockdep_set_class(&ops->reg_mutex, (struct lock_class_key *)id);
+
        ops->driver = DRIVER_EMPTY;
        INIT_LIST_HEAD(&ops->dev_list);
        /* lock this instance */
        ops->used = 1;
 
        /* register driver entry */
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        list_add_tail(&ops->list, &opslist);
        num_ops++;
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 
        return ops;
 }
@@ -414,7 +409,7 @@ int snd_seq_device_unregister_driver(char *id)
        }
 
        /* close and release all devices associated with this driver */
-       down(&ops->reg_mutex);
+       mutex_lock(&ops->reg_mutex);
        ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
        list_for_each(head, &ops->dev_list) {
                struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
@@ -425,7 +420,7 @@ int snd_seq_device_unregister_driver(char *id)
        if (ops->num_init_devices > 0)
                snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
                           ops->num_init_devices);
-       up(&ops->reg_mutex);
+       mutex_unlock(&ops->reg_mutex);
 
        unlock_driver(ops);
 
@@ -443,7 +438,7 @@ static void remove_drivers(void)
 {
        struct list_head *head;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        head = opslist.next;
        while (head != &opslist) {
                struct ops_list *ops = list_entry(head, struct ops_list, list);
@@ -456,7 +451,7 @@ static void remove_drivers(void)
                } else
                        head = head->next;
        }
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 }
 
 /*
@@ -519,16 +514,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
 {
        struct list_head *head;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        list_for_each(head, &opslist) {
                struct ops_list *ops = list_entry(head, struct ops_list, list);
                if (strcmp(ops->id, id) == 0) {
                        ops->used++;
-                       up(&ops_mutex);
+                       mutex_unlock(&ops_mutex);
                        return ops;
                }
        }
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
        if (create_if_empty)
                return create_driver(id);
        return NULL;
@@ -536,9 +531,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty)
 
 static void unlock_driver(struct ops_list *ops)
 {
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        ops->used--;
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 }
 
 
@@ -554,7 +549,6 @@ static int __init alsa_seq_device_init(void)
        if (info_entry == NULL)
                return -ENOMEM;
        info_entry->content = SNDRV_INFO_CONTENT_TEXT;
-       info_entry->c.text.read_size = 2048;
        info_entry->c.text.read = snd_seq_device_info;
        if (snd_info_register(info_entry) < 0) {
                snd_info_free_entry(info_entry);
@@ -568,7 +562,7 @@ static void __exit alsa_seq_device_exit(void)
 {
        remove_drivers();
 #ifdef CONFIG_PROC_FS
-       snd_info_unregister(info_entry);
+       snd_info_free_entry(info_entry);
 #endif
        if (num_ops)
                snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);