seq_device.c 13 KB

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