Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / sound / core / seq / seq_device.c
index 4d80f39..d9a3e5a 100644 (file)
 #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");
 MODULE_LICENSE("GPL");
 
-/*
- * driver list
- */
-typedef struct ops_list ops_list_t;
-
 /* driver state */
 #define DRIVER_EMPTY           0
 #define DRIVER_LOADED          (1<<0)
@@ -68,13 +64,13 @@ struct ops_list {
        int argsize;            /* argument size */
 
        /* operators */
-       snd_seq_dev_ops_t ops;
+       struct snd_seq_dev_ops ops;
 
        /* registred devices */
        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 */
 };
@@ -82,36 +78,40 @@ struct ops_list {
 
 static LIST_HEAD(opslist);
 static int num_ops;
-static DECLARE_MUTEX(ops_mutex);
-static snd_info_entry_t *info_entry = NULL;
+static DEFINE_MUTEX(ops_mutex);
+#ifdef CONFIG_PROC_FS
+static struct snd_info_entry *info_entry = NULL;
+#endif
 
 /*
  * prototypes
  */
-static int snd_seq_device_free(snd_seq_device_t *dev);
-static int snd_seq_device_dev_free(snd_device_t *device);
-static int snd_seq_device_dev_register(snd_device_t *device);
-static int snd_seq_device_dev_disconnect(snd_device_t *device);
-static int snd_seq_device_dev_unregister(snd_device_t *device);
-
-static int init_device(snd_seq_device_t *dev, ops_list_t *ops);
-static int free_device(snd_seq_device_t *dev, ops_list_t *ops);
-static ops_list_t *find_driver(char *id, int create_if_empty);
-static ops_list_t *create_driver(char *id);
-static void unlock_driver(ops_list_t *ops);
+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);
+static struct ops_list *find_driver(char *id, int create_if_empty);
+static struct ops_list *create_driver(char *id);
+static void unlock_driver(struct ops_list *ops);
 static void remove_drivers(void);
 
 /*
  * show all drivers and their status
  */
 
-static void snd_seq_device_info(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void snd_seq_device_info(struct snd_info_entry *entry,
+                               struct snd_info_buffer *buffer)
 {
        struct list_head *head;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        list_for_each(head, &opslist) {
-               ops_list_t *ops = list_entry(head, ops_list_t, list);
+               struct ops_list *ops = list_entry(head, struct ops_list, list);
                snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
                                ops->id,
                                ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""),
@@ -119,8 +119,9 @@ static void snd_seq_device_info(snd_info_entry_t *entry, snd_info_buffer_t * buf
                                ops->driver & DRIVER_LOCKED ? ",locked" : "",
                                ops->num_devices);
        }
-       up(&ops_mutex); 
+       mutex_unlock(&ops_mutex);
 }
+#endif
  
 /*
  * load all registered drivers (called from seq_clientmgr.c)
@@ -154,20 +155,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) {
-               ops_list_t *ops = list_entry(head, ops_list_t, list);
+               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
 }
 
@@ -178,13 +179,13 @@ void snd_seq_device_load_drivers(void)
  * id = id of driver
  * result = return pointer (NULL allowed if unnecessary)
  */
-int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
-                      snd_seq_device_t **result)
+int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
+                      struct snd_seq_device **result)
 {
-       snd_seq_device_t *dev;
-       ops_list_t *ops;
+       struct snd_seq_device *dev;
+       struct ops_list *ops;
        int err;
-       static snd_device_ops_t dops = {
+       static struct snd_device_ops dops = {
                .dev_free = snd_seq_device_dev_free,
                .dev_register = snd_seq_device_dev_register,
                .dev_disconnect = snd_seq_device_dev_disconnect,
@@ -200,7 +201,7 @@ int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
        if (ops == NULL)
                return -ENOMEM;
 
-       dev = kcalloc(1, sizeof(*dev)*2 + argsize, GFP_KERNEL);
+       dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL);
        if (dev == NULL) {
                unlock_driver(ops);
                return -ENOMEM;
@@ -214,10 +215,10 @@ int snd_seq_device_new(snd_card_t *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);
        
@@ -235,9 +236,9 @@ int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
 /*
  * free the existing device
  */
-static int snd_seq_device_free(snd_seq_device_t *dev)
+static int snd_seq_device_free(struct snd_seq_device *dev)
 {
-       ops_list_t *ops;
+       struct ops_list *ops;
 
        snd_assert(dev != NULL, return -EINVAL);
 
@@ -246,10 +247,10 @@ static int snd_seq_device_free(snd_seq_device_t *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)
@@ -261,19 +262,19 @@ static int snd_seq_device_free(snd_seq_device_t *dev)
        return 0;
 }
 
-static int snd_seq_device_dev_free(snd_device_t *device)
+static int snd_seq_device_dev_free(struct snd_device *device)
 {
-       snd_seq_device_t *dev = device->device_data;
+       struct snd_seq_device *dev = device->device_data;
        return snd_seq_device_free(dev);
 }
 
 /*
  * register the device
  */
-static int snd_seq_device_dev_register(snd_device_t *device)
+static int snd_seq_device_dev_register(struct snd_device *device)
 {
-       snd_seq_device_t *dev = device->device_data;
-       ops_list_t *ops;
+       struct snd_seq_device *dev = device->device_data;
+       struct ops_list *ops;
 
        ops = find_driver(dev->id, 0);
        if (ops == NULL)
@@ -292,10 +293,10 @@ static int snd_seq_device_dev_register(snd_device_t *device)
 /*
  * disconnect the device
  */
-static int snd_seq_device_dev_disconnect(snd_device_t *device)
+static int snd_seq_device_dev_disconnect(struct snd_device *device)
 {
-       snd_seq_device_t *dev = device->device_data;
-       ops_list_t *ops;
+       struct snd_seq_device *dev = device->device_data;
+       struct ops_list *ops;
 
        ops = find_driver(dev->id, 0);
        if (ops == NULL)
@@ -310,9 +311,9 @@ static int snd_seq_device_dev_disconnect(snd_device_t *device)
 /*
  * unregister the existing device
  */
-static int snd_seq_device_dev_unregister(snd_device_t *device)
+static int snd_seq_device_dev_unregister(struct snd_device *device)
 {
-       snd_seq_device_t *dev = device->device_data;
+       struct snd_seq_device *dev = device->device_data;
        return snd_seq_device_free(dev);
 }
 
@@ -321,10 +322,11 @@ static int snd_seq_device_dev_unregister(snd_device_t *device)
  * id = driver id
  * entry = driver operators - duplicated to each instance
  */
-int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsize)
+int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
+                                  int argsize)
 {
        struct list_head *head;
-       ops_list_t *ops;
+       struct ops_list *ops;
 
        if (id == NULL || entry == NULL ||
            entry->init_device == NULL || entry->free_device == NULL)
@@ -343,7 +345,7 @@ int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsi
                return -EBUSY;
        }
 
-       down(&ops->reg_mutex);
+       mutex_lock(&ops->reg_mutex);
        /* copy driver operators */
        ops->ops = *entry;
        ops->driver |= DRIVER_LOADED;
@@ -351,10 +353,10 @@ int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsi
 
        /* initialize existing devices if necessary */
        list_for_each(head, &ops->dev_list) {
-               snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
+               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();
@@ -366,9 +368,9 @@ int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsi
 /*
  * create driver record
  */
-static ops_list_t * create_driver(char *id)
+static struct ops_list * create_driver(char *id)
 {
-       ops_list_t *ops;
+       struct ops_list *ops;
 
        ops = kmalloc(sizeof(*ops), GFP_KERNEL);
        if (ops == NULL)
@@ -377,17 +379,17 @@ static ops_list_t * create_driver(char *id)
 
        /* set up driver entry */
        strlcpy(ops->id, id, sizeof(ops->id));
-       init_MUTEX(&ops->reg_mutex);
+       mutex_init(&ops->reg_mutex);
        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;
 }
@@ -399,30 +401,32 @@ static ops_list_t * create_driver(char *id)
 int snd_seq_device_unregister_driver(char *id)
 {
        struct list_head *head;
-       ops_list_t *ops;
+       struct ops_list *ops;
 
        ops = find_driver(id, 0);
        if (ops == NULL)
                return -ENXIO;
        if (! (ops->driver & DRIVER_LOADED) ||
            (ops->driver & DRIVER_LOCKED)) {
-               snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n", id, ops->driver);
+               snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n",
+                          id, ops->driver);
                unlock_driver(ops);
                return -EBUSY;
        }
 
        /* 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) {
-               snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
+               struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
                free_device(dev, ops);
        }
 
        ops->driver = 0;
        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);
+               snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
+                          ops->num_init_devices);
+       mutex_unlock(&ops->reg_mutex);
 
        unlock_driver(ops);
 
@@ -440,10 +444,10 @@ static void remove_drivers(void)
 {
        struct list_head *head;
 
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        head = opslist.next;
        while (head != &opslist) {
-               ops_list_t *ops = list_entry(head, ops_list_t, list);
+               struct ops_list *ops = list_entry(head, struct ops_list, list);
                if (! (ops->driver & DRIVER_LOADED) &&
                    ops->used == 0 && ops->num_devices == 0) {
                        head = head->next;
@@ -453,27 +457,29 @@ static void remove_drivers(void)
                } else
                        head = head->next;
        }
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 }
 
 /*
  * initialize the device - call init_device operator
  */
-static int init_device(snd_seq_device_t *dev, ops_list_t *ops)
+static int init_device(struct snd_seq_device *dev, struct ops_list *ops)
 {
        if (! (ops->driver & DRIVER_LOADED))
                return 0; /* driver is not loaded yet */
        if (dev->status != SNDRV_SEQ_DEVICE_FREE)
                return 0; /* already initialized */
        if (ops->argsize != dev->argsize) {
-               snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
+               snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+                          dev->name, ops->id, ops->argsize, dev->argsize);
                return -EINVAL;
        }
        if (ops->ops.init_device(dev) >= 0) {
                dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
                ops->num_init_devices++;
        } else {
-               snd_printk(KERN_ERR "init_device failed: %s: %s\n", dev->name, dev->id);
+               snd_printk(KERN_ERR "init_device failed: %s: %s\n",
+                          dev->name, dev->id);
        }
 
        return 0;
@@ -482,7 +488,7 @@ static int init_device(snd_seq_device_t *dev, ops_list_t *ops)
 /*
  * release the device - call free_device operator
  */
-static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
+static int free_device(struct snd_seq_device *dev, struct ops_list *ops)
 {
        int result;
 
@@ -491,7 +497,8 @@ static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
        if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
                return 0; /* not registered */
        if (ops->argsize != dev->argsize) {
-               snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
+               snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+                          dev->name, ops->id, ops->argsize, dev->argsize);
                return -EINVAL;
        }
        if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) {
@@ -499,7 +506,8 @@ static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
                dev->driver_data = NULL;
                ops->num_init_devices--;
        } else {
-               snd_printk(KERN_ERR "free_device failed: %s: %s\n", dev->name, dev->id);
+               snd_printk(KERN_ERR "free_device failed: %s: %s\n",
+                          dev->name, dev->id);
        }
 
        return 0;
@@ -508,30 +516,30 @@ static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
 /*
  * find the matching driver with given id
  */
-static ops_list_t * find_driver(char *id, int create_if_empty)
+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) {
-               ops_list_t *ops = list_entry(head, ops_list_t, list);
+               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;
 }
 
-static void unlock_driver(ops_list_t *ops)
+static void unlock_driver(struct ops_list *ops)
 {
-       down(&ops_mutex);
+       mutex_lock(&ops_mutex);
        ops->used--;
-       up(&ops_mutex);
+       mutex_unlock(&ops_mutex);
 }
 
 
@@ -541,7 +549,9 @@ static void unlock_driver(ops_list_t *ops)
 
 static int __init alsa_seq_device_init(void)
 {
-       info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers", snd_seq_root);
+#ifdef CONFIG_PROC_FS
+       info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers",
+                                                 snd_seq_root);
        if (info_entry == NULL)
                return -ENOMEM;
        info_entry->content = SNDRV_INFO_CONTENT_TEXT;
@@ -551,13 +561,16 @@ static int __init alsa_seq_device_init(void)
                snd_info_free_entry(info_entry);
                return -ENOMEM;
        }
+#endif
        return 0;
 }
 
 static void __exit alsa_seq_device_exit(void)
 {
        remove_drivers();
+#ifdef CONFIG_PROC_FS
        snd_info_unregister(info_entry);
+#endif
        if (num_ops)
                snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
 }