ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.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/initval.h>
45 #include <linux/kmod.h>
46 #include <linux/slab.h>
47
48 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
49 MODULE_DESCRIPTION("ALSA sequencer device management");
50 MODULE_LICENSE("GPL");
51 MODULE_CLASSES("{sound}");
52 MODULE_SUPPORTED_DEVICE("sound");
53
54 /*
55  * driver list
56  */
57 typedef struct ops_list ops_list_t;
58
59 /* driver state */
60 #define DRIVER_EMPTY            0
61 #define DRIVER_LOADED           (1<<0)
62 #define DRIVER_REQUESTED        (1<<1)
63 #define DRIVER_LOCKED           (1<<2)
64
65 struct ops_list {
66         char id[ID_LEN];        /* driver id */
67         int driver;             /* driver state */
68         int used;               /* reference counter */
69         int argsize;            /* argument size */
70
71         /* operators */
72         snd_seq_dev_ops_t ops;
73
74         /* registred devices */
75         struct list_head dev_list;      /* list of devices */
76         int num_devices;        /* number of associated devices */
77         int num_init_devices;   /* number of initialized devices */
78         struct semaphore reg_mutex;
79
80         struct list_head list;  /* next driver */
81 };
82
83
84 static LIST_HEAD(opslist);
85 static int num_ops;
86 static DECLARE_MUTEX(ops_mutex);
87 static snd_info_entry_t *info_entry = NULL;
88
89 /*
90  * prototypes
91  */
92 static int snd_seq_device_free(snd_seq_device_t *dev);
93 static int snd_seq_device_dev_free(snd_device_t *device);
94 static int snd_seq_device_dev_register(snd_device_t *device);
95 static int snd_seq_device_dev_disconnect(snd_device_t *device);
96 static int snd_seq_device_dev_unregister(snd_device_t *device);
97
98 static int init_device(snd_seq_device_t *dev, ops_list_t *ops);
99 static int free_device(snd_seq_device_t *dev, ops_list_t *ops);
100 static ops_list_t *find_driver(char *id, int create_if_empty);
101 static ops_list_t *create_driver(char *id);
102 static void unlock_driver(ops_list_t *ops);
103 static void remove_drivers(void);
104
105 /*
106  * show all drivers and their status
107  */
108
109 static void snd_seq_device_info(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
110 {
111         struct list_head *head;
112
113         down(&ops_mutex);
114         list_for_each(head, &opslist) {
115                 ops_list_t *ops = list_entry(head, ops_list_t, list);
116                 snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
117                                 ops->id,
118                                 ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""),
119                                 ops->driver & DRIVER_REQUESTED ? ",requested" : "",
120                                 ops->driver & DRIVER_LOCKED ? ",locked" : "",
121                                 ops->num_devices);
122         }
123         up(&ops_mutex); 
124 }
125  
126 /*
127  * load all registered drivers (called from seq_clientmgr.c)
128  */
129
130 void snd_seq_device_load_drivers(void)
131 {
132 #ifdef CONFIG_KMOD
133         struct list_head *head;
134
135         if (! current->fs->root)
136                 return;
137
138         down(&ops_mutex);
139         list_for_each(head, &opslist) {
140                 ops_list_t *ops = list_entry(head, ops_list_t, list);
141                 if (! (ops->driver & DRIVER_LOADED) &&
142                     ! (ops->driver & DRIVER_REQUESTED)) {
143                         ops->used++;
144                         up(&ops_mutex);
145                         ops->driver |= DRIVER_REQUESTED;
146                         request_module("snd-%s", ops->id);
147                         down(&ops_mutex);
148                         ops->used--;
149                 }
150         }
151         up(&ops_mutex);
152 #endif
153 }
154
155 /*
156  * register a sequencer device
157  * card = card info (NULL allowed)
158  * device = device number (if any)
159  * id = id of driver
160  * result = return pointer (NULL allowed if unnecessary)
161  */
162 int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
163                        snd_seq_device_t **result)
164 {
165         snd_seq_device_t *dev;
166         ops_list_t *ops;
167         int err;
168         static snd_device_ops_t dops = {
169                 .dev_free = snd_seq_device_dev_free,
170                 .dev_register = snd_seq_device_dev_register,
171                 .dev_disconnect = snd_seq_device_dev_disconnect,
172                 .dev_unregister = snd_seq_device_dev_unregister
173         };
174
175         if (result)
176                 *result = NULL;
177
178         snd_assert(id != NULL, return -EINVAL);
179
180         ops = find_driver(id, 1);
181         if (ops == NULL)
182                 return -ENOMEM;
183
184         dev = snd_magic_kcalloc(snd_seq_device_t, sizeof(*dev) + argsize, GFP_KERNEL);
185         if (dev == NULL) {
186                 unlock_driver(ops);
187                 return -ENOMEM;
188         }
189
190         /* set up device info */
191         dev->card = card;
192         dev->device = device;
193         strlcpy(dev->id, id, sizeof(dev->id));
194         dev->argsize = argsize;
195         dev->status = SNDRV_SEQ_DEVICE_FREE;
196
197         /* add this device to the list */
198         down(&ops->reg_mutex);
199         list_add_tail(&dev->list, &ops->dev_list);
200         ops->num_devices++;
201         up(&ops->reg_mutex);
202
203         unlock_driver(ops);
204         
205         if ((err = snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)) < 0) {
206                 snd_seq_device_free(dev);
207                 return err;
208         }
209         
210         if (result)
211                 *result = dev;
212
213         return 0;
214 }
215
216 /*
217  * free the existing device
218  */
219 static int snd_seq_device_free(snd_seq_device_t *dev)
220 {
221         ops_list_t *ops;
222
223         snd_assert(dev != NULL, return -EINVAL);
224
225         ops = find_driver(dev->id, 0);
226         if (ops == NULL)
227                 return -ENXIO;
228
229         /* remove the device from the list */
230         down(&ops->reg_mutex);
231         list_del(&dev->list);
232         ops->num_devices--;
233         up(&ops->reg_mutex);
234
235         free_device(dev, ops);
236         if (dev->private_free)
237                 dev->private_free(dev);
238         snd_magic_kfree(dev);
239
240         unlock_driver(ops);
241
242         return 0;
243 }
244
245 static int snd_seq_device_dev_free(snd_device_t *device)
246 {
247         snd_seq_device_t *dev = snd_magic_cast(snd_seq_device_t, device->device_data, return -ENXIO);
248         return snd_seq_device_free(dev);
249 }
250
251 /*
252  * register the device
253  */
254 static int snd_seq_device_dev_register(snd_device_t *device)
255 {
256         snd_seq_device_t *dev = snd_magic_cast(snd_seq_device_t, device->device_data, return -ENXIO);
257         ops_list_t *ops;
258
259         ops = find_driver(dev->id, 0);
260         if (ops == NULL)
261                 return -ENOENT;
262
263         /* initialize this device if the corresponding driver was
264          * already loaded
265          */
266         if (ops->driver & DRIVER_LOADED)
267                 init_device(dev, ops);
268
269         unlock_driver(ops);
270         return 0;
271 }
272
273 /*
274  * disconnect the device
275  */
276 static int snd_seq_device_dev_disconnect(snd_device_t *device)
277 {
278         snd_seq_device_t *dev = snd_magic_cast(snd_seq_device_t, device->device_data, return -ENXIO);
279         ops_list_t *ops;
280
281         ops = find_driver(dev->id, 0);
282         if (ops == NULL)
283                 return -ENOENT;
284
285         free_device(dev, ops);
286
287         unlock_driver(ops);
288         return 0;
289 }
290
291 /*
292  * unregister the existing device
293  */
294 static int snd_seq_device_dev_unregister(snd_device_t *device)
295 {
296         snd_seq_device_t *dev = snd_magic_cast(snd_seq_device_t, device->device_data, return -ENXIO);
297         return snd_seq_device_free(dev);
298 }
299
300 /*
301  * register device driver
302  * id = driver id
303  * entry = driver operators - duplicated to each instance
304  */
305 int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsize)
306 {
307         struct list_head *head;
308         ops_list_t *ops;
309
310         if (id == NULL || entry == NULL ||
311             entry->init_device == NULL || entry->free_device == NULL)
312                 return -EINVAL;
313
314         ops = find_driver(id, 1);
315         if (ops == NULL)
316                 return -ENOMEM;
317         if (ops->driver & DRIVER_LOADED) {
318                 snd_printk(KERN_WARNING "driver_register: driver '%s' already exists\n", id);
319                 unlock_driver(ops);
320                 return -EBUSY;
321         }
322
323         down(&ops->reg_mutex);
324         /* copy driver operators */
325         ops->ops = *entry;
326         ops->driver |= DRIVER_LOADED;
327         ops->argsize = argsize;
328
329         /* initialize existing devices if necessary */
330         list_for_each(head, &ops->dev_list) {
331                 snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
332                 init_device(dev, ops);
333         }
334         up(&ops->reg_mutex);
335
336         unlock_driver(ops);
337
338         return 0;
339 }
340
341
342 /*
343  * create driver record
344  */
345 static ops_list_t * create_driver(char *id)
346 {
347         ops_list_t *ops;
348
349         ops = kmalloc(sizeof(*ops), GFP_KERNEL);
350         if (ops == NULL)
351                 return ops;
352         memset(ops, 0, sizeof(*ops));
353
354         /* set up driver entry */
355         strlcpy(ops->id, id, sizeof(ops->id));
356         init_MUTEX(&ops->reg_mutex);
357         ops->driver = DRIVER_EMPTY;
358         INIT_LIST_HEAD(&ops->dev_list);
359         /* lock this instance */
360         ops->used = 1;
361
362         /* register driver entry */
363         down(&ops_mutex);
364         list_add_tail(&ops->list, &opslist);
365         num_ops++;
366         up(&ops_mutex);
367
368         return ops;
369 }
370
371
372 /*
373  * unregister the specified driver
374  */
375 int snd_seq_device_unregister_driver(char *id)
376 {
377         struct list_head *head;
378         ops_list_t *ops;
379
380         ops = find_driver(id, 0);
381         if (ops == NULL)
382                 return -ENXIO;
383         if (! (ops->driver & DRIVER_LOADED) ||
384             (ops->driver & DRIVER_LOCKED)) {
385                 snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n", id, ops->driver);
386                 unlock_driver(ops);
387                 return -EBUSY;
388         }
389
390         /* close and release all devices associated with this driver */
391         down(&ops->reg_mutex);
392         ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
393         list_for_each(head, &ops->dev_list) {
394                 snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
395                 free_device(dev, ops);
396         }
397
398         ops->driver = 0;
399         if (ops->num_init_devices > 0)
400                 snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", ops->num_init_devices);
401         up(&ops->reg_mutex);
402
403         unlock_driver(ops);
404
405         /* remove empty driver entries */
406         remove_drivers();
407
408         return 0;
409 }
410
411
412 /*
413  * remove empty driver entries
414  */
415 static void remove_drivers(void)
416 {
417         struct list_head *head;
418
419         down(&ops_mutex);
420         head = opslist.next;
421         while (head != &opslist) {
422                 ops_list_t *ops = list_entry(head, ops_list_t, list);
423                 if (! (ops->driver & DRIVER_LOADED) &&
424                     ops->used == 0 && ops->num_devices == 0) {
425                         head = head->next;
426                         list_del(&ops->list);
427                         kfree(ops);
428                         num_ops--;
429                 } else
430                         head = head->next;
431         }
432         up(&ops_mutex);
433 }
434
435 /*
436  * initialize the device - call init_device operator
437  */
438 static int init_device(snd_seq_device_t *dev, ops_list_t *ops)
439 {
440         if (! (ops->driver & DRIVER_LOADED))
441                 return 0; /* driver is not loaded yet */
442         if (dev->status != SNDRV_SEQ_DEVICE_FREE)
443                 return 0; /* already initialized */
444         if (ops->argsize != dev->argsize) {
445                 snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
446                 return -EINVAL;
447         }
448         if (ops->ops.init_device(dev) >= 0) {
449                 dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
450                 ops->num_init_devices++;
451         } else {
452                 snd_printk(KERN_ERR "init_device failed: %s: %s\n", dev->name, dev->id);
453         }
454
455         return 0;
456 }
457
458 /*
459  * release the device - call free_device operator
460  */
461 static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
462 {
463         int result;
464
465         if (! (ops->driver & DRIVER_LOADED))
466                 return 0; /* driver is not loaded yet */
467         if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
468                 return 0; /* not registered */
469         if (ops->argsize != dev->argsize) {
470                 snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
471                 return -EINVAL;
472         }
473         if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) {
474                 dev->status = SNDRV_SEQ_DEVICE_FREE;
475                 dev->driver_data = NULL;
476                 ops->num_init_devices--;
477         } else {
478                 snd_printk(KERN_ERR "free_device failed: %s: %s\n", dev->name, dev->id);
479         }
480
481         return 0;
482 }
483
484 /*
485  * find the matching driver with given id
486  */
487 static ops_list_t * find_driver(char *id, int create_if_empty)
488 {
489         struct list_head *head;
490
491         down(&ops_mutex);
492         list_for_each(head, &opslist) {
493                 ops_list_t *ops = list_entry(head, ops_list_t, list);
494                 if (strcmp(ops->id, id) == 0) {
495                         ops->used++;
496                         up(&ops_mutex);
497                         return ops;
498                 }
499         }
500         up(&ops_mutex);
501         if (create_if_empty)
502                 return create_driver(id);
503         return NULL;
504 }
505
506 static void unlock_driver(ops_list_t *ops)
507 {
508         down(&ops_mutex);
509         ops->used--;
510         up(&ops_mutex);
511 }
512
513
514 /*
515  * module part
516  */
517
518 static int __init alsa_seq_device_init(void)
519 {
520         info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers", snd_seq_root);
521         if (info_entry == NULL)
522                 return -ENOMEM;
523         info_entry->content = SNDRV_INFO_CONTENT_TEXT;
524         info_entry->c.text.read_size = 2048;
525         info_entry->c.text.read = snd_seq_device_info;
526         if (snd_info_register(info_entry) < 0) {
527                 snd_info_free_entry(info_entry);
528                 return -ENOMEM;
529         }
530         return 0;
531 }
532
533 static void __exit alsa_seq_device_exit(void)
534 {
535         remove_drivers();
536         snd_info_unregister(info_entry);
537         if (num_ops)
538                 snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
539 }
540
541 module_init(alsa_seq_device_init)
542 module_exit(alsa_seq_device_exit)
543
544 EXPORT_SYMBOL(snd_seq_device_load_drivers);
545 EXPORT_SYMBOL(snd_seq_device_new);
546 EXPORT_SYMBOL(snd_seq_device_register_driver);
547 EXPORT_SYMBOL(snd_seq_device_unregister_driver);