37852cdace76091c83a4c33b063c1a60f5a0959c
[pandora-kernel.git] / sound / core / seq / seq_device.c
1 /*
2  *  ALSA sequencer device management
3  *  Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18  *
19  *
20  *----------------------------------------------------------------
21  *
22  * This device handler separates the card driver module from sequencer
23  * stuff (sequencer core, synth drivers, etc), so that user can avoid
24  * to spend unnecessary resources e.g. if he needs only listening to
25  * MP3s.
26  *
27  * The card (or lowlevel) driver creates a sequencer device entry
28  * via snd_seq_device_new().  This is an entry pointer to communicate
29  * with the sequencer device "driver", which is involved with the
30  * actual part to communicate with the sequencer core.
31  * Each sequencer device entry has an id string and the corresponding
32  * driver with the same id is loaded when required.  For example,
33  * lowlevel codes to access emu8000 chip on sbawe card are included in
34  * emu8000-synth module.  To activate this module, the hardware
35  * resources like i/o port are passed via snd_seq_device argument.
36  *
37  */
38
39 #include <sound/driver.h>
40 #include <linux/init.h>
41 #include <sound/core.h>
42 #include <sound/info.h>
43 #include <sound/seq_device.h>
44 #include <sound/seq_kernel.h>
45 #include <sound/initval.h>
46 #include <linux/kmod.h>
47 #include <linux/slab.h>
48 #include <linux/mutex.h>
49
50 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
51 MODULE_DESCRIPTION("ALSA sequencer device management");
52 MODULE_LICENSE("GPL");
53
54 /* driver state */
55 #define DRIVER_EMPTY            0
56 #define DRIVER_LOADED           (1<<0)
57 #define DRIVER_REQUESTED        (1<<1)
58 #define DRIVER_LOCKED           (1<<2)
59
60 struct ops_list {
61         char id[ID_LEN];        /* driver id */
62         int driver;             /* driver state */
63         int used;               /* reference counter */
64         int argsize;            /* argument size */
65
66         /* operators */
67         struct snd_seq_dev_ops ops;
68
69         /* registred devices */
70         struct list_head dev_list;      /* list of devices */
71         int num_devices;        /* number of associated devices */
72         int num_init_devices;   /* number of initialized devices */
73         struct mutex reg_mutex;
74
75         struct list_head list;  /* next driver */
76 };
77
78
79 static LIST_HEAD(opslist);
80 static int num_ops;
81 static DEFINE_MUTEX(ops_mutex);
82 #ifdef CONFIG_PROC_FS
83 static struct snd_info_entry *info_entry;
84 #endif
85
86 /*
87  * prototypes
88  */
89 static int snd_seq_device_free(struct snd_seq_device *dev);
90 static int snd_seq_device_dev_free(struct snd_device *device);
91 static int snd_seq_device_dev_register(struct snd_device *device);
92 static int snd_seq_device_dev_disconnect(struct snd_device *device);
93
94 static int init_device(struct snd_seq_device *dev, struct ops_list *ops);
95 static int free_device(struct snd_seq_device *dev, struct ops_list *ops);
96 static struct ops_list *find_driver(char *id, int create_if_empty);
97 static struct ops_list *create_driver(char *id);
98 static void unlock_driver(struct ops_list *ops);
99 static void remove_drivers(void);
100
101 /*
102  * show all drivers and their status
103  */
104
105 #ifdef CONFIG_PROC_FS
106 static void snd_seq_device_info(struct snd_info_entry *entry,
107                                 struct snd_info_buffer *buffer)
108 {
109         struct ops_list *ops;
110
111         mutex_lock(&ops_mutex);
112         list_for_each_entry(ops, &opslist, list) {
113                 snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
114                                 ops->id,
115                                 ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""),
116                                 ops->driver & DRIVER_REQUESTED ? ",requested" : "",
117                                 ops->driver & DRIVER_LOCKED ? ",locked" : "",
118                                 ops->num_devices);
119         }
120         mutex_unlock(&ops_mutex);
121 }
122 #endif
123  
124 /*
125  * load all registered drivers (called from seq_clientmgr.c)
126  */
127
128 #ifdef CONFIG_KMOD
129 /* avoid auto-loading during module_init() */
130 static int snd_seq_in_init;
131 void snd_seq_autoload_lock(void)
132 {
133         snd_seq_in_init++;
134 }
135
136 void snd_seq_autoload_unlock(void)
137 {
138         snd_seq_in_init--;
139 }
140 #endif
141
142 void snd_seq_device_load_drivers(void)
143 {
144 #ifdef CONFIG_KMOD
145         struct ops_list *ops;
146
147         /* Calling request_module during module_init()
148          * may cause blocking.
149          */
150         if (snd_seq_in_init)
151                 return;
152
153         if (! current->fs->root)
154                 return;
155
156         mutex_lock(&ops_mutex);
157         list_for_each_entry(ops, &opslist, list) {
158                 if (! (ops->driver & DRIVER_LOADED) &&
159                     ! (ops->driver & DRIVER_REQUESTED)) {
160                         ops->used++;
161                         mutex_unlock(&ops_mutex);
162                         ops->driver |= DRIVER_REQUESTED;
163                         request_module("snd-%s", ops->id);
164                         mutex_lock(&ops_mutex);
165                         ops->used--;
166                 }
167         }
168         mutex_unlock(&ops_mutex);
169 #endif
170 }
171
172 /*
173  * register a sequencer device
174  * card = card info (NULL allowed)
175  * device = device number (if any)
176  * id = id of driver
177  * result = return pointer (NULL allowed if unnecessary)
178  */
179 int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
180                        struct snd_seq_device **result)
181 {
182         struct snd_seq_device *dev;
183         struct ops_list *ops;
184         int err;
185         static struct snd_device_ops dops = {
186                 .dev_free = snd_seq_device_dev_free,
187                 .dev_register = snd_seq_device_dev_register,
188                 .dev_disconnect = snd_seq_device_dev_disconnect,
189         };
190
191         if (result)
192                 *result = NULL;
193
194         snd_assert(id != NULL, return -EINVAL);
195
196         ops = find_driver(id, 1);
197         if (ops == NULL)
198                 return -ENOMEM;
199
200         dev = kzalloc(sizeof(*dev)*2 + argsize, GFP_KERNEL);
201         if (dev == NULL) {
202                 unlock_driver(ops);
203                 return -ENOMEM;
204         }
205
206         /* set up device info */
207         dev->card = card;
208         dev->device = device;
209         strlcpy(dev->id, id, sizeof(dev->id));
210         dev->argsize = argsize;
211         dev->status = SNDRV_SEQ_DEVICE_FREE;
212
213         /* add this device to the list */
214         mutex_lock(&ops->reg_mutex);
215         list_add_tail(&dev->list, &ops->dev_list);
216         ops->num_devices++;
217         mutex_unlock(&ops->reg_mutex);
218
219         unlock_driver(ops);
220         
221         if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) {
222                 snd_seq_device_free(dev);
223                 return err;
224         }
225         
226         if (result)
227                 *result = dev;
228
229         return 0;
230 }
231
232 /*
233  * free the existing device
234  */
235 static int snd_seq_device_free(struct snd_seq_device *dev)
236 {
237         struct ops_list *ops;
238
239         snd_assert(dev != NULL, return -EINVAL);
240
241         ops = find_driver(dev->id, 0);
242         if (ops == NULL)
243                 return -ENXIO;
244
245         /* remove the device from the list */
246         mutex_lock(&ops->reg_mutex);
247         list_del(&dev->list);
248         ops->num_devices--;
249         mutex_unlock(&ops->reg_mutex);
250
251         free_device(dev, ops);
252         if (dev->private_free)
253                 dev->private_free(dev);
254         kfree(dev);
255
256         unlock_driver(ops);
257
258         return 0;
259 }
260
261 static int snd_seq_device_dev_free(struct snd_device *device)
262 {
263         struct snd_seq_device *dev = device->device_data;
264         return snd_seq_device_free(dev);
265 }
266
267 /*
268  * register the device
269  */
270 static int snd_seq_device_dev_register(struct snd_device *device)
271 {
272         struct snd_seq_device *dev = device->device_data;
273         struct ops_list *ops;
274
275         ops = find_driver(dev->id, 0);
276         if (ops == NULL)
277                 return -ENOENT;
278
279         /* initialize this device if the corresponding driver was
280          * already loaded
281          */
282         if (ops->driver & DRIVER_LOADED)
283                 init_device(dev, ops);
284
285         unlock_driver(ops);
286         return 0;
287 }
288
289 /*
290  * disconnect the device
291  */
292 static int snd_seq_device_dev_disconnect(struct snd_device *device)
293 {
294         struct snd_seq_device *dev = device->device_data;
295         struct ops_list *ops;
296
297         ops = find_driver(dev->id, 0);
298         if (ops == NULL)
299                 return -ENOENT;
300
301         free_device(dev, ops);
302
303         unlock_driver(ops);
304         return 0;
305 }
306
307 /*
308  * register device driver
309  * id = driver id
310  * entry = driver operators - duplicated to each instance
311  */
312 int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
313                                    int argsize)
314 {
315         struct ops_list *ops;
316         struct snd_seq_device *dev;
317
318         if (id == NULL || entry == NULL ||
319             entry->init_device == NULL || entry->free_device == NULL)
320                 return -EINVAL;
321
322         snd_seq_autoload_lock();
323         ops = find_driver(id, 1);
324         if (ops == NULL) {
325                 snd_seq_autoload_unlock();
326                 return -ENOMEM;
327         }
328         if (ops->driver & DRIVER_LOADED) {
329                 snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id);
330                 unlock_driver(ops);
331                 snd_seq_autoload_unlock();
332                 return -EBUSY;
333         }
334
335         mutex_lock(&ops->reg_mutex);
336         /* copy driver operators */
337         ops->ops = *entry;
338         ops->driver |= DRIVER_LOADED;
339         ops->argsize = argsize;
340
341         /* initialize existing devices if necessary */
342         list_for_each_entry(dev, &ops->dev_list, list) {
343                 init_device(dev, ops);
344         }
345         mutex_unlock(&ops->reg_mutex);
346
347         unlock_driver(ops);
348         snd_seq_autoload_unlock();
349
350         return 0;
351 }
352
353
354 /*
355  * create driver record
356  */
357 static struct ops_list * create_driver(char *id)
358 {
359         struct ops_list *ops;
360
361         ops = kzalloc(sizeof(*ops), GFP_KERNEL);
362         if (ops == NULL)
363                 return ops;
364
365         /* set up driver entry */
366         strlcpy(ops->id, id, sizeof(ops->id));
367         mutex_init(&ops->reg_mutex);
368         /*
369          * The ->reg_mutex locking rules are per-driver, so we create
370          * separate per-driver lock classes:
371          */
372         lockdep_set_class(&ops->reg_mutex, (struct lock_class_key *)id);
373
374         ops->driver = DRIVER_EMPTY;
375         INIT_LIST_HEAD(&ops->dev_list);
376         /* lock this instance */
377         ops->used = 1;
378
379         /* register driver entry */
380         mutex_lock(&ops_mutex);
381         list_add_tail(&ops->list, &opslist);
382         num_ops++;
383         mutex_unlock(&ops_mutex);
384
385         return ops;
386 }
387
388
389 /*
390  * unregister the specified driver
391  */
392 int snd_seq_device_unregister_driver(char *id)
393 {
394         struct ops_list *ops;
395         struct snd_seq_device *dev;
396
397         ops = find_driver(id, 0);
398         if (ops == NULL)
399                 return -ENXIO;
400         if (! (ops->driver & DRIVER_LOADED) ||
401             (ops->driver & DRIVER_LOCKED)) {
402                 snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n",
403                            id, ops->driver);
404                 unlock_driver(ops);
405                 return -EBUSY;
406         }
407
408         /* close and release all devices associated with this driver */
409         mutex_lock(&ops->reg_mutex);
410         ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
411         list_for_each_entry(dev, &ops->dev_list, list) {
412                 free_device(dev, ops);
413         }
414
415         ops->driver = 0;
416         if (ops->num_init_devices > 0)
417                 snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
418                            ops->num_init_devices);
419         mutex_unlock(&ops->reg_mutex);
420
421         unlock_driver(ops);
422
423         /* remove empty driver entries */
424         remove_drivers();
425
426         return 0;
427 }
428
429
430 /*
431  * remove empty driver entries
432  */
433 static void remove_drivers(void)
434 {
435         struct list_head *head;
436
437         mutex_lock(&ops_mutex);
438         head = opslist.next;
439         while (head != &opslist) {
440                 struct ops_list *ops = list_entry(head, struct ops_list, list);
441                 if (! (ops->driver & DRIVER_LOADED) &&
442                     ops->used == 0 && ops->num_devices == 0) {
443                         head = head->next;
444                         list_del(&ops->list);
445                         kfree(ops);
446                         num_ops--;
447                 } else
448                         head = head->next;
449         }
450         mutex_unlock(&ops_mutex);
451 }
452
453 /*
454  * initialize the device - call init_device operator
455  */
456 static int init_device(struct snd_seq_device *dev, struct ops_list *ops)
457 {
458         if (! (ops->driver & DRIVER_LOADED))
459                 return 0; /* driver is not loaded yet */
460         if (dev->status != SNDRV_SEQ_DEVICE_FREE)
461                 return 0; /* already initialized */
462         if (ops->argsize != dev->argsize) {
463                 snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
464                            dev->name, ops->id, ops->argsize, dev->argsize);
465                 return -EINVAL;
466         }
467         if (ops->ops.init_device(dev) >= 0) {
468                 dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
469                 ops->num_init_devices++;
470         } else {
471                 snd_printk(KERN_ERR "init_device failed: %s: %s\n",
472                            dev->name, dev->id);
473         }
474
475         return 0;
476 }
477
478 /*
479  * release the device - call free_device operator
480  */
481 static int free_device(struct snd_seq_device *dev, struct ops_list *ops)
482 {
483         int result;
484
485         if (! (ops->driver & DRIVER_LOADED))
486                 return 0; /* driver is not loaded yet */
487         if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
488                 return 0; /* not registered */
489         if (ops->argsize != dev->argsize) {
490                 snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
491                            dev->name, ops->id, ops->argsize, dev->argsize);
492                 return -EINVAL;
493         }
494         if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) {
495                 dev->status = SNDRV_SEQ_DEVICE_FREE;
496                 dev->driver_data = NULL;
497                 ops->num_init_devices--;
498         } else {
499                 snd_printk(KERN_ERR "free_device failed: %s: %s\n",
500                            dev->name, dev->id);
501         }
502
503         return 0;
504 }
505
506 /*
507  * find the matching driver with given id
508  */
509 static struct ops_list * find_driver(char *id, int create_if_empty)
510 {
511         struct ops_list *ops;
512
513         mutex_lock(&ops_mutex);
514         list_for_each_entry(ops, &opslist, list) {
515                 if (strcmp(ops->id, id) == 0) {
516                         ops->used++;
517                         mutex_unlock(&ops_mutex);
518                         return ops;
519                 }
520         }
521         mutex_unlock(&ops_mutex);
522         if (create_if_empty)
523                 return create_driver(id);
524         return NULL;
525 }
526
527 static void unlock_driver(struct ops_list *ops)
528 {
529         mutex_lock(&ops_mutex);
530         ops->used--;
531         mutex_unlock(&ops_mutex);
532 }
533
534
535 /*
536  * module part
537  */
538
539 static int __init alsa_seq_device_init(void)
540 {
541 #ifdef CONFIG_PROC_FS
542         info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers",
543                                                   snd_seq_root);
544         if (info_entry == NULL)
545                 return -ENOMEM;
546         info_entry->content = SNDRV_INFO_CONTENT_TEXT;
547         info_entry->c.text.read = snd_seq_device_info;
548         if (snd_info_register(info_entry) < 0) {
549                 snd_info_free_entry(info_entry);
550                 return -ENOMEM;
551         }
552 #endif
553         return 0;
554 }
555
556 static void __exit alsa_seq_device_exit(void)
557 {
558         remove_drivers();
559 #ifdef CONFIG_PROC_FS
560         snd_info_free_entry(info_entry);
561 #endif
562         if (num_ops)
563                 snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
564 }
565
566 module_init(alsa_seq_device_init)
567 module_exit(alsa_seq_device_exit)
568
569 EXPORT_SYMBOL(snd_seq_device_load_drivers);
570 EXPORT_SYMBOL(snd_seq_device_new);
571 EXPORT_SYMBOL(snd_seq_device_register_driver);
572 EXPORT_SYMBOL(snd_seq_device_unregister_driver);
573 #ifdef CONFIG_KMOD
574 EXPORT_SYMBOL(snd_seq_autoload_lock);
575 EXPORT_SYMBOL(snd_seq_autoload_unlock);
576 #endif