2 * Initialization routines
3 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <sound/driver.h>
23 #include <linux/init.h>
24 #include <linux/sched.h>
25 #include <linux/file.h>
26 #include <linux/slab.h>
27 #include <linux/time.h>
28 #include <linux/ctype.h>
29 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include <sound/control.h>
33 #include <sound/info.h>
35 struct snd_shutdown_f_ops
{
36 struct file_operations f_ops
;
37 struct snd_shutdown_f_ops
*next
;
40 int snd_cards_count
= 0;
41 unsigned int snd_cards_lock
= 0; /* locked for registering/using */
42 snd_card_t
*snd_cards
[SNDRV_CARDS
] = {[0 ... (SNDRV_CARDS
-1)] = NULL
};
43 rwlock_t snd_card_rwlock
= RW_LOCK_UNLOCKED
;
45 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
46 int (*snd_mixer_oss_notify_callback
)(snd_card_t
*card
, int free_flag
);
49 static void snd_card_id_read(snd_info_entry_t
*entry
, snd_info_buffer_t
* buffer
)
51 snd_iprintf(buffer
, "%s\n", entry
->card
->id
);
54 static void snd_card_free_thread(void * __card
);
57 * snd_card_new - create and initialize a soundcard structure
58 * @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
59 * @xid: card identification (ASCII string)
60 * @module: top level module for locking
61 * @extra_size: allocate this extra size after the main soundcard structure
63 * Creates and initializes a soundcard structure.
65 * Returns kmallocated snd_card_t structure. Creates the ALSA control interface
66 * (which is blocked until snd_card_register function is called).
68 snd_card_t
*snd_card_new(int idx
, const char *xid
,
69 struct module
*module
, int extra_size
)
76 card
= kcalloc(1, sizeof(*card
) + extra_size
, GFP_KERNEL
);
80 if (!snd_info_check_reserved_words(xid
))
82 strlcpy(card
->id
, xid
, sizeof(card
->id
));
85 write_lock(&snd_card_rwlock
);
88 for (idx2
= 0; idx2
< snd_ecards_limit
; idx2
++)
89 if (!(snd_cards_lock
& (1 << idx2
))) {
93 if (idx
< 0 && snd_ecards_limit
< SNDRV_CARDS
)
94 /* for dynamically additional devices like hotplug:
95 * increment the limit if still free slot exists.
97 idx
= snd_ecards_limit
++;
98 } else if (idx
< snd_ecards_limit
) {
99 if (snd_cards_lock
& (1 << idx
))
100 err
= -ENODEV
; /* invalid */
101 } else if (idx
< SNDRV_CARDS
)
102 snd_ecards_limit
= idx
+ 1; /* increase the limit */
105 if (idx
< 0 || err
< 0) {
106 write_unlock(&snd_card_rwlock
);
107 snd_printk(KERN_ERR
"cannot find the slot for index %d (range 0-%i)\n", idx
, snd_ecards_limit
- 1);
110 snd_cards_lock
|= 1 << idx
; /* lock it */
111 write_unlock(&snd_card_rwlock
);
113 card
->module
= module
;
114 INIT_LIST_HEAD(&card
->devices
);
115 init_rwsem(&card
->controls_rwsem
);
116 rwlock_init(&card
->ctl_files_rwlock
);
117 INIT_LIST_HEAD(&card
->controls
);
118 INIT_LIST_HEAD(&card
->ctl_files
);
119 spin_lock_init(&card
->files_lock
);
120 init_waitqueue_head(&card
->shutdown_sleep
);
121 INIT_WORK(&card
->free_workq
, snd_card_free_thread
, card
);
123 init_MUTEX(&card
->power_lock
);
124 init_waitqueue_head(&card
->power_sleep
);
126 /* the control interface cannot be accessed from the user space until */
127 /* snd_cards_bitmask and snd_cards are set with snd_card_register */
128 if ((err
= snd_ctl_register(card
)) < 0) {
129 snd_printd("unable to register control minors\n");
132 if ((err
= snd_info_card_create(card
)) < 0) {
133 snd_printd("unable to create card info\n");
137 card
->private_data
= (char *)card
+ sizeof(snd_card_t
);
141 snd_ctl_unregister(card
);
147 static unsigned int snd_disconnect_poll(struct file
* file
, poll_table
* wait
)
149 return POLLERR
| POLLNVAL
;
153 * snd_card_disconnect - disconnect all APIs from the file-operations (user space)
154 * @card: soundcard structure
156 * Disconnects all APIs from the file-operations (user space).
158 * Returns zero, otherwise a negative error code.
160 * Note: The current implementation replaces all active file->f_op with special
161 * dummy file operations (they do nothing except release).
163 int snd_card_disconnect(snd_card_t
* card
)
165 struct snd_monitor_file
*mfile
;
167 struct snd_shutdown_f_ops
*s_f_ops
;
168 struct file_operations
*f_ops
, *old_f_ops
;
171 spin_lock(&card
->files_lock
);
172 if (card
->shutdown
) {
173 spin_unlock(&card
->files_lock
);
177 spin_unlock(&card
->files_lock
);
179 /* phase 1: disable fops (user space) operations for ALSA API */
180 write_lock(&snd_card_rwlock
);
181 snd_cards
[card
->number
] = NULL
;
182 write_unlock(&snd_card_rwlock
);
184 /* phase 2: replace file->f_op with special dummy operations */
186 spin_lock(&card
->files_lock
);
191 /* it's critical part, use endless loop */
192 /* we have no room to fail */
193 s_f_ops
= kmalloc(sizeof(struct snd_shutdown_f_ops
), GFP_ATOMIC
);
195 panic("Atomic allocation failed for snd_shutdown_f_ops!");
197 f_ops
= &s_f_ops
->f_ops
;
199 memset(f_ops
, 0, sizeof(*f_ops
));
200 f_ops
->owner
= file
->f_op
->owner
;
201 f_ops
->release
= file
->f_op
->release
;
202 f_ops
->poll
= snd_disconnect_poll
;
204 s_f_ops
->next
= card
->s_f_ops
;
205 card
->s_f_ops
= s_f_ops
;
207 f_ops
= fops_get(f_ops
);
209 old_f_ops
= file
->f_op
;
210 file
->f_op
= f_ops
; /* must be atomic */
215 spin_unlock(&card
->files_lock
);
217 /* phase 3: notify all connected devices about disconnection */
218 /* at this point, they cannot respond to any calls except release() */
220 snd_ctl_disconnect(card
);
222 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
223 if (snd_mixer_oss_notify_callback
)
224 snd_mixer_oss_notify_callback(card
, SND_MIXER_OSS_NOTIFY_DISCONNECT
);
227 /* notify all devices that we are disconnected */
228 err
= snd_device_disconnect_all(card
);
230 snd_printk(KERN_ERR
"not all devices for card %i can be disconnected\n", card
->number
);
236 * snd_card_free - frees given soundcard structure
237 * @card: soundcard structure
239 * This function releases the soundcard structure and the all assigned
240 * devices automatically. That is, you don't have to release the devices
243 * Returns zero. Frees all associated devices and frees the control
244 * interface associated to given soundcard.
246 int snd_card_free(snd_card_t
* card
)
248 struct snd_shutdown_f_ops
*s_f_ops
;
252 write_lock(&snd_card_rwlock
);
253 snd_cards
[card
->number
] = NULL
;
255 write_unlock(&snd_card_rwlock
);
258 wake_up(&card
->power_sleep
);
261 pm_unregister(card
->pm_dev
);
267 /* wait, until all devices are ready for the free operation */
268 wait_event(card
->shutdown_sleep
, card
->files
== NULL
);
270 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
271 if (snd_mixer_oss_notify_callback
)
272 snd_mixer_oss_notify_callback(card
, SND_MIXER_OSS_NOTIFY_FREE
);
274 if (snd_device_free_all(card
, SNDRV_DEV_CMD_PRE
) < 0) {
275 snd_printk(KERN_ERR
"unable to free all devices (pre)\n");
276 /* Fatal, but this situation should never occur */
278 if (snd_device_free_all(card
, SNDRV_DEV_CMD_NORMAL
) < 0) {
279 snd_printk(KERN_ERR
"unable to free all devices (normal)\n");
280 /* Fatal, but this situation should never occur */
282 if (snd_ctl_unregister(card
) < 0) {
283 snd_printk(KERN_ERR
"unable to unregister control minors\n");
284 /* Not fatal error */
286 if (snd_device_free_all(card
, SNDRV_DEV_CMD_POST
) < 0) {
287 snd_printk(KERN_ERR
"unable to free all devices (post)\n");
288 /* Fatal, but this situation should never occur */
290 if (card
->private_free
)
291 card
->private_free(card
);
293 snd_info_unregister(card
->proc_id
);
294 if (snd_info_card_free(card
) < 0) {
295 snd_printk(KERN_WARNING
"unable to free card info\n");
296 /* Not fatal error */
298 while (card
->s_f_ops
) {
299 s_f_ops
= card
->s_f_ops
;
300 card
->s_f_ops
= s_f_ops
->next
;
303 write_lock(&snd_card_rwlock
);
304 snd_cards_lock
&= ~(1 << card
->number
);
305 write_unlock(&snd_card_rwlock
);
310 static void snd_card_free_thread(void * __card
)
312 snd_card_t
*card
= __card
;
313 struct module
* module
= card
->module
;
315 if (!try_module_get(module
)) {
316 snd_printk(KERN_ERR
"unable to lock toplevel module for card %i in free thread\n", card
->number
);
326 * snd_card_free_in_thread - call snd_card_free() in thread
327 * @card: soundcard structure
329 * This function schedules the call of snd_card_free() function in a
330 * work queue. When all devices are released (non-busy), the work
331 * is woken up and calls snd_card_free().
333 * When a card can be disconnected at any time by hotplug service,
334 * this function should be used in disconnect (or detach) callback
335 * instead of calling snd_card_free() directly.
337 * Returns - zero otherwise a negative error code if the start of thread failed.
339 int snd_card_free_in_thread(snd_card_t
* card
)
341 if (card
->files
== NULL
) {
346 if (schedule_work(&card
->free_workq
))
349 snd_printk(KERN_ERR
"schedule_work() failed in snd_card_free_in_thread for card %i\n", card
->number
);
350 /* try to free the structure immediately */
355 static void choose_default_id(snd_card_t
* card
)
357 int i
, len
, idx_flag
= 0, loops
= 8;
360 id
= spos
= card
->shortname
;
361 while (*id
!= '\0') {
367 while (*spos
!= '\0' && !isalnum(*spos
))
370 *id
++ = isalpha(card
->shortname
[0]) ? card
->shortname
[0] : 'D';
371 while (*spos
!= '\0' && (size_t)(id
- card
->id
) < sizeof(card
->id
) - 1) {
381 strcpy(id
, "default");
385 snd_printk(KERN_ERR
"unable to choose default card id (%s)", id
);
386 strcpy(card
->id
, card
->proc_root
->name
);
389 if (!snd_info_check_reserved_words(id
))
391 for (i
= 0; i
< snd_ecards_limit
; i
++) {
392 if (snd_cards
[i
] && !strcmp(snd_cards
[i
]->id
, id
))
401 else if ((size_t)len
<= sizeof(card
->id
) - 3) {
406 if ((size_t)len
<= sizeof(card
->id
) - 2)
417 * snd_card_register - register the soundcard
418 * @card: soundcard structure
420 * This function registers all the devices assigned to the soundcard.
421 * Until calling this, the ALSA control interface is blocked from the
422 * external accesses. Thus, you should call this function at the end
423 * of the initialization of the card.
425 * Returns zero otherwise a negative error code if the registrain failed.
427 int snd_card_register(snd_card_t
* card
)
430 snd_info_entry_t
*entry
;
432 snd_runtime_check(card
!= NULL
, return -EINVAL
);
433 if ((err
= snd_device_register_all(card
)) < 0)
435 write_lock(&snd_card_rwlock
);
436 if (snd_cards
[card
->number
]) {
437 /* already registered */
438 write_unlock(&snd_card_rwlock
);
441 if (card
->id
[0] == '\0')
442 choose_default_id(card
);
443 snd_cards
[card
->number
] = card
;
445 write_unlock(&snd_card_rwlock
);
446 if ((err
= snd_info_card_register(card
)) < 0) {
447 snd_printd("unable to create card info\n");
450 if ((entry
= snd_info_create_card_entry(card
, "id", card
->proc_root
)) == NULL
) {
451 snd_printd("unable to create card entry\n");
454 entry
->c
.text
.read_size
= PAGE_SIZE
;
455 entry
->c
.text
.read
= snd_card_id_read
;
456 if (snd_info_register(entry
) < 0) {
457 snd_info_free_entry(entry
);
460 card
->proc_id
= entry
;
462 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
463 if (snd_mixer_oss_notify_callback
)
464 snd_mixer_oss_notify_callback(card
, SND_MIXER_OSS_NOTIFY_REGISTER
);
469 static snd_info_entry_t
*snd_card_info_entry
= NULL
;
471 static void snd_card_info_read(snd_info_entry_t
*entry
, snd_info_buffer_t
* buffer
)
476 for (idx
= count
= 0; idx
< SNDRV_CARDS
; idx
++) {
477 read_lock(&snd_card_rwlock
);
478 if ((card
= snd_cards
[idx
]) != NULL
) {
480 snd_iprintf(buffer
, "%i [%-15s]: %s - %s\n",
485 snd_iprintf(buffer
, " %s\n",
488 read_unlock(&snd_card_rwlock
);
491 snd_iprintf(buffer
, "--- no soundcards ---\n");
494 #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
496 void snd_card_info_read_oss(snd_info_buffer_t
* buffer
)
501 for (idx
= count
= 0; idx
< SNDRV_CARDS
; idx
++) {
502 read_lock(&snd_card_rwlock
);
503 if ((card
= snd_cards
[idx
]) != NULL
) {
505 snd_iprintf(buffer
, "%s\n", card
->longname
);
507 read_unlock(&snd_card_rwlock
);
510 snd_iprintf(buffer
, "--- no soundcards ---\n");
517 static snd_info_entry_t
*snd_card_module_info_entry
;
518 static void snd_card_module_info_read(snd_info_entry_t
*entry
, snd_info_buffer_t
* buffer
)
523 for (idx
= 0; idx
< SNDRV_CARDS
; idx
++) {
524 read_lock(&snd_card_rwlock
);
525 if ((card
= snd_cards
[idx
]) != NULL
)
526 snd_iprintf(buffer
, "%i %s\n", idx
, card
->module
->name
);
527 read_unlock(&snd_card_rwlock
);
532 int __init
snd_card_info_init(void)
534 snd_info_entry_t
*entry
;
536 entry
= snd_info_create_module_entry(THIS_MODULE
, "cards", NULL
);
537 snd_runtime_check(entry
!= NULL
, return -ENOMEM
);
538 entry
->c
.text
.read_size
= PAGE_SIZE
;
539 entry
->c
.text
.read
= snd_card_info_read
;
540 if (snd_info_register(entry
) < 0) {
541 snd_info_free_entry(entry
);
544 snd_card_info_entry
= entry
;
547 entry
= snd_info_create_module_entry(THIS_MODULE
, "modules", NULL
);
549 entry
->c
.text
.read_size
= PAGE_SIZE
;
550 entry
->c
.text
.read
= snd_card_module_info_read
;
551 if (snd_info_register(entry
) < 0)
552 snd_info_free_entry(entry
);
554 snd_card_module_info_entry
= entry
;
561 int __exit
snd_card_info_done(void)
563 if (snd_card_info_entry
)
564 snd_info_unregister(snd_card_info_entry
);
566 if (snd_card_module_info_entry
)
567 snd_info_unregister(snd_card_module_info_entry
);
573 * snd_component_add - add a component string
574 * @card: soundcard structure
575 * @component: the component id string
577 * This function adds the component id string to the supported list.
578 * The component can be referred from the alsa-lib.
580 * Returns zero otherwise a negative error code.
583 int snd_component_add(snd_card_t
*card
, const char *component
)
586 int len
= strlen(component
);
588 ptr
= strstr(card
->components
, component
);
590 if (ptr
[len
] == '\0' || ptr
[len
] == ' ') /* already there */
593 if (strlen(card
->components
) + 1 + len
+ 1 > sizeof(card
->components
)) {
597 if (card
->components
[0] != '\0')
598 strcat(card
->components
, " ");
599 strcat(card
->components
, component
);
604 * snd_card_file_add - add the file to the file list of the card
605 * @card: soundcard structure
606 * @file: file pointer
608 * This function adds the file to the file linked-list of the card.
609 * This linked-list is used to keep tracking the connection state,
610 * and to avoid the release of busy resources by hotplug.
612 * Returns zero or a negative error code.
614 int snd_card_file_add(snd_card_t
*card
, struct file
*file
)
616 struct snd_monitor_file
*mfile
;
618 mfile
= kmalloc(sizeof(*mfile
), GFP_KERNEL
);
623 spin_lock(&card
->files_lock
);
624 if (card
->shutdown
) {
625 spin_unlock(&card
->files_lock
);
629 mfile
->next
= card
->files
;
631 spin_unlock(&card
->files_lock
);
636 * snd_card_file_remove - remove the file from the file list
637 * @card: soundcard structure
638 * @file: file pointer
640 * This function removes the file formerly added to the card via
641 * snd_card_file_add() function.
642 * If all files are removed and the release of the card is
643 * scheduled, it will wake up the the thread to call snd_card_free()
644 * (see snd_card_free_in_thread() function).
646 * Returns zero or a negative error code.
648 int snd_card_file_remove(snd_card_t
*card
, struct file
*file
)
650 struct snd_monitor_file
*mfile
, *pfile
= NULL
;
652 spin_lock(&card
->files_lock
);
655 if (mfile
->file
== file
) {
657 pfile
->next
= mfile
->next
;
659 card
->files
= mfile
->next
;
665 spin_unlock(&card
->files_lock
);
666 if (card
->files
== NULL
)
667 wake_up(&card
->shutdown_sleep
);
671 snd_printk(KERN_ERR
"ALSA card file remove problem (%p)\n", file
);
679 * snd_power_wait - wait until the power-state is changed.
680 * @card: soundcard structure
681 * @power_state: expected power state
682 * @file: file structure for the O_NONBLOCK check (optional)
684 * Waits until the power-state is changed.
686 * Note: the power lock must be active before call.
688 int snd_power_wait(snd_card_t
*card
, unsigned int power_state
, struct file
*file
)
694 if (snd_power_get_state(card
) == power_state
)
696 init_waitqueue_entry(&wait
, current
);
697 add_wait_queue(&card
->power_sleep
, &wait
);
699 if (card
->shutdown
) {
703 if (snd_power_get_state(card
) == power_state
)
705 #if 0 /* block all devices */
706 if (file
&& (file
->f_flags
& O_NONBLOCK
)) {
711 set_current_state(TASK_UNINTERRUPTIBLE
);
712 snd_power_unlock(card
);
713 schedule_timeout(30 * HZ
);
714 snd_power_lock(card
);
716 remove_wait_queue(&card
->power_sleep
, &wait
);
721 * snd_card_set_pm_callback - set the PCI power-management callbacks
722 * @card: soundcard structure
723 * @suspend: suspend callback function
724 * @resume: resume callback function
725 * @private_data: private data to pass to the callback functions
727 * Sets the power-management callback functions of the card.
728 * These callbacks are called from ALSA's common PCI suspend/resume
729 * handler and from the control API.
731 int snd_card_set_pm_callback(snd_card_t
*card
,
732 int (*suspend
)(snd_card_t
*, unsigned int),
733 int (*resume
)(snd_card_t
*, unsigned int),
736 card
->pm_suspend
= suspend
;
737 card
->pm_resume
= resume
;
738 card
->pm_private_data
= private_data
;
742 static int snd_generic_pm_callback(struct pm_dev
*dev
, pm_request_t rqst
, void *data
)
744 snd_card_t
*card
= dev
->data
;
748 /* FIXME: the correct state value? */
749 card
->pm_suspend(card
, 0);
752 /* FIXME: the correct state value? */
753 card
->pm_resume(card
, 0);
760 * snd_card_set_dev_pm_callback - set the generic power-management callbacks
761 * @card: soundcard structure
762 * @type: PM device type (PM_XXX)
763 * @suspend: suspend callback function
764 * @resume: resume callback function
765 * @private_data: private data to pass to the callback functions
767 * Registers the power-management and sets the lowlevel callbacks for
768 * the given card with the given PM type. These callbacks are called
769 * from the ALSA's common PM handler and from the control API.
771 int snd_card_set_dev_pm_callback(snd_card_t
*card
, int type
,
772 int (*suspend
)(snd_card_t
*, unsigned int),
773 int (*resume
)(snd_card_t
*, unsigned int),
776 card
->pm_dev
= pm_register(type
, 0, snd_generic_pm_callback
);
779 card
->pm_dev
->data
= card
;
780 snd_card_set_pm_callback(card
, suspend
, resume
, private_data
);
785 int snd_card_pci_suspend(struct pci_dev
*dev
, u32 state
)
787 snd_card_t
*card
= pci_get_drvdata(dev
);
788 if (! card
|| ! card
->pm_suspend
)
790 if (card
->power_state
== SNDRV_CTL_POWER_D3hot
)
792 /* FIXME: correct state value? */
793 return card
->pm_suspend(card
, 0);
796 int snd_card_pci_resume(struct pci_dev
*dev
)
798 snd_card_t
*card
= pci_get_drvdata(dev
);
799 if (! card
|| ! card
->pm_resume
)
801 if (card
->power_state
== SNDRV_CTL_POWER_D0
)
803 /* restore the PCI config space */
804 pci_restore_state(dev
, dev
->saved_config_space
);
805 /* FIXME: correct state value? */
806 return card
->pm_resume(card
, 0);
810 #endif /* CONFIG_PM */