X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Finit.c;h=4d9258884e444c368be86da0c470a69726f2253d;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=d72f58f450ce442dac0386be21a94c567ac2e293;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/sound/core/init.c b/sound/core/init.c index d72f58f45..4d9258884 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -28,6 +28,7 @@ #include #include #include + #include #include #include @@ -37,19 +38,49 @@ struct snd_shutdown_f_ops { struct snd_shutdown_f_ops *next; }; -unsigned int snd_cards_lock = 0; /* locked for registering/using */ -snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; -DEFINE_RWLOCK(snd_card_rwlock); +static unsigned int snd_cards_lock; /* locked for registering/using */ +struct snd_card *snd_cards[SNDRV_CARDS]; +EXPORT_SYMBOL(snd_cards); + +static DEFINE_MUTEX(snd_card_mutex); #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) -int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag); +int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag); +EXPORT_SYMBOL(snd_mixer_oss_notify_callback); #endif -static void snd_card_id_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) +#ifdef CONFIG_PROC_FS +static void snd_card_id_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) { snd_iprintf(buffer, "%s\n", entry->card->id); } +static inline int init_info_for_card(struct snd_card *card) +{ + int err; + struct snd_info_entry *entry; + + if ((err = snd_info_card_register(card)) < 0) { + snd_printd("unable to create card info\n"); + return err; + } + if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) { + snd_printd("unable to create card entry\n"); + return err; + } + entry->c.text.read = snd_card_id_read; + if (snd_info_register(entry) < 0) { + snd_info_free_entry(entry); + entry = NULL; + } + card->proc_id = entry; + return 0; +} +#else /* !CONFIG_PROC_FS */ +#define init_info_for_card(card) +#endif + static void snd_card_free_thread(void * __card); /** @@ -61,18 +92,18 @@ static void snd_card_free_thread(void * __card); * * Creates and initializes a soundcard structure. * - * Returns kmallocated snd_card_t structure. Creates the ALSA control interface + * Returns kmallocated snd_card structure. Creates the ALSA control interface * (which is blocked until snd_card_register function is called). */ -snd_card_t *snd_card_new(int idx, const char *xid, +struct snd_card *snd_card_new(int idx, const char *xid, struct module *module, int extra_size) { - snd_card_t *card; + struct snd_card *card; int err; if (extra_size < 0) extra_size = 0; - card = kcalloc(1, sizeof(*card) + extra_size, GFP_KERNEL); + card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL); if (card == NULL) return NULL; if (xid) { @@ -81,7 +112,7 @@ snd_card_t *snd_card_new(int idx, const char *xid, strlcpy(card->id, xid, sizeof(card->id)); } err = 0; - write_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); if (idx < 0) { int idx2; for (idx2 = 0; idx2 < SNDRV_CARDS; idx2++) @@ -99,12 +130,12 @@ snd_card_t *snd_card_new(int idx, const char *xid, else err = -ENODEV; if (idx < 0 || err < 0) { - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); snd_printk(KERN_ERR "cannot find the slot for index %d (range 0-%i)\n", idx, snd_ecards_limit - 1); goto __error; } snd_cards_lock |= 1 << idx; /* lock it */ - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); card->number = idx; card->module = module; INIT_LIST_HEAD(&card->devices); @@ -116,7 +147,7 @@ snd_card_t *snd_card_new(int idx, const char *xid, init_waitqueue_head(&card->shutdown_sleep); INIT_WORK(&card->free_workq, snd_card_free_thread, card); #ifdef CONFIG_PM - init_MUTEX(&card->power_lock); + mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); #endif /* the control interface cannot be accessed from the user space until */ @@ -130,7 +161,7 @@ snd_card_t *snd_card_new(int idx, const char *xid, goto __error_ctl; } if (extra_size > 0) - card->private_data = (char *)card + sizeof(snd_card_t); + card->private_data = (char *)card + sizeof(struct snd_card); return card; __error_ctl: @@ -140,11 +171,57 @@ snd_card_t *snd_card_new(int idx, const char *xid, return NULL; } +EXPORT_SYMBOL(snd_card_new); + +/* return non-zero if a card is already locked */ +int snd_card_locked(int card) +{ + int locked; + + mutex_lock(&snd_card_mutex); + locked = snd_cards_lock & (1 << card); + mutex_unlock(&snd_card_mutex); + return locked; +} + +static loff_t snd_disconnect_llseek(struct file *file, loff_t offset, int orig) +{ + return -ENODEV; +} + +static ssize_t snd_disconnect_read(struct file *file, char __user *buf, + size_t count, loff_t *offset) +{ + return -ENODEV; +} + +static ssize_t snd_disconnect_write(struct file *file, const char __user *buf, + size_t count, loff_t *offset) +{ + return -ENODEV; +} + static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) { return POLLERR | POLLNVAL; } +static long snd_disconnect_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -ENODEV; +} + +static int snd_disconnect_mmap(struct file *file, struct vm_area_struct *vma) +{ + return -ENODEV; +} + +static int snd_disconnect_fasync(int fd, struct file *file, int on) +{ + return -ENODEV; +} + /** * snd_card_disconnect - disconnect all APIs from the file-operations (user space) * @card: soundcard structure @@ -156,12 +233,13 @@ static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait) * Note: The current implementation replaces all active file->f_op with special * dummy file operations (they do nothing except release). */ -int snd_card_disconnect(snd_card_t * card) +int snd_card_disconnect(struct snd_card *card) { struct snd_monitor_file *mfile; struct file *file; struct snd_shutdown_f_ops *s_f_ops; - struct file_operations *f_ops, *old_f_ops; + struct file_operations *f_ops; + const struct file_operations *old_f_ops; int err; spin_lock(&card->files_lock); @@ -173,9 +251,9 @@ int snd_card_disconnect(snd_card_t * card) spin_unlock(&card->files_lock); /* phase 1: disable fops (user space) operations for ALSA API */ - write_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); snd_cards[card->number] = NULL; - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); /* phase 2: replace file->f_op with special dummy operations */ @@ -195,7 +273,16 @@ int snd_card_disconnect(snd_card_t * card) memset(f_ops, 0, sizeof(*f_ops)); f_ops->owner = file->f_op->owner; f_ops->release = file->f_op->release; + f_ops->llseek = snd_disconnect_llseek; + f_ops->read = snd_disconnect_read; + f_ops->write = snd_disconnect_write; f_ops->poll = snd_disconnect_poll; + f_ops->unlocked_ioctl = snd_disconnect_ioctl; +#ifdef CONFIG_COMPAT + f_ops->compat_ioctl = snd_disconnect_ioctl; +#endif + f_ops->mmap = snd_disconnect_mmap; + f_ops->fasync = snd_disconnect_fasync; s_f_ops->next = card->s_f_ops; card->s_f_ops = s_f_ops; @@ -226,9 +313,7 @@ int snd_card_disconnect(snd_card_t * card) return 0; } -#if defined(CONFIG_PM) && defined(CONFIG_SND_GENERIC_PM) -static void snd_generic_device_unregister(struct snd_generic_device *dev); -#endif +EXPORT_SYMBOL(snd_card_disconnect); /** * snd_card_free - frees given soundcard structure @@ -241,26 +326,19 @@ static void snd_generic_device_unregister(struct snd_generic_device *dev); * Returns zero. Frees all associated devices and frees the control * interface associated to given soundcard. */ -int snd_card_free(snd_card_t * card) +int snd_card_free(struct snd_card *card) { struct snd_shutdown_f_ops *s_f_ops; if (card == NULL) return -EINVAL; - write_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); snd_cards[card->number] = NULL; - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); #ifdef CONFIG_PM wake_up(&card->power_sleep); -#ifdef CONFIG_SND_GENERIC_PM - if (card->pm_dev) { - snd_generic_device_unregister(card->pm_dev); - card->pm_dev = NULL; - } -#endif #endif - /* wait, until all devices are ready for the free operation */ wait_event(card->shutdown_sleep, card->files == NULL); @@ -282,8 +360,7 @@ int snd_card_free(snd_card_t * card) } if (card->private_free) card->private_free(card); - if (card->proc_id) - snd_info_unregister(card->proc_id); + snd_info_unregister(card->proc_id); if (snd_info_card_free(card) < 0) { snd_printk(KERN_WARNING "unable to free card info\n"); /* Not fatal error */ @@ -293,16 +370,18 @@ int snd_card_free(snd_card_t * card) card->s_f_ops = s_f_ops->next; kfree(s_f_ops); } - write_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); snd_cards_lock &= ~(1 << card->number); - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); kfree(card); return 0; } +EXPORT_SYMBOL(snd_card_free); + static void snd_card_free_thread(void * __card) { - snd_card_t *card = __card; + struct snd_card *card = __card; struct module * module = card->module; if (!try_module_get(module)) { @@ -329,7 +408,7 @@ static void snd_card_free_thread(void * __card) * * Returns - zero otherwise a negative error code if the start of thread failed. */ -int snd_card_free_in_thread(snd_card_t * card) +int snd_card_free_in_thread(struct snd_card *card) { if (card->files == NULL) { snd_card_free(card); @@ -345,9 +424,11 @@ int snd_card_free_in_thread(snd_card_t * card) return -EFAULT; } -static void choose_default_id(snd_card_t * card) +EXPORT_SYMBOL(snd_card_free_in_thread); + +static void choose_default_id(struct snd_card *card) { - int i, len, idx_flag = 0, loops = 8; + int i, len, idx_flag = 0, loops = SNDRV_CARDS; char *id, *spos; id = spos = card->shortname; @@ -389,9 +470,12 @@ static void choose_default_id(snd_card_t * card) __change: len = strlen(id); - if (idx_flag) - id[len-1]++; - else if ((size_t)len <= sizeof(card->id) - 3) { + if (idx_flag) { + if (id[len-1] != '9') + id[len-1]++; + else + id[len-1] = 'A'; + } else if ((size_t)len <= sizeof(card->id) - 3) { strcat(id, "_1"); idx_flag++; } else { @@ -417,40 +501,24 @@ static void choose_default_id(snd_card_t * card) * * Returns zero otherwise a negative error code if the registrain failed. */ -int snd_card_register(snd_card_t * card) +int snd_card_register(struct snd_card *card) { int err; - snd_info_entry_t *entry; - snd_runtime_check(card != NULL, return -EINVAL); + snd_assert(card != NULL, return -EINVAL); if ((err = snd_device_register_all(card)) < 0) return err; - write_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); if (snd_cards[card->number]) { /* already registered */ - write_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); return 0; } if (card->id[0] == '\0') choose_default_id(card); snd_cards[card->number] = card; - write_unlock(&snd_card_rwlock); - if ((err = snd_info_card_register(card)) < 0) { - snd_printd("unable to create card info\n"); - goto __skip_info; - } - if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) { - snd_printd("unable to create card entry\n"); - goto __skip_info; - } - entry->c.text.read_size = PAGE_SIZE; - entry->c.text.read = snd_card_id_read; - if (snd_info_register(entry) < 0) { - snd_info_free_entry(entry); - entry = NULL; - } - card->proc_id = entry; - __skip_info: + mutex_unlock(&snd_card_mutex); + init_info_for_card(card); #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) if (snd_mixer_oss_notify_callback) snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); @@ -458,45 +526,49 @@ int snd_card_register(snd_card_t * card) return 0; } -static snd_info_entry_t *snd_card_info_entry = NULL; +EXPORT_SYMBOL(snd_card_register); + +#ifdef CONFIG_PROC_FS +static struct snd_info_entry *snd_card_info_entry; -static void snd_card_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) +static void snd_card_info_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) { int idx, count; - snd_card_t *card; + struct snd_card *card; for (idx = count = 0; idx < SNDRV_CARDS; idx++) { - read_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); if ((card = snd_cards[idx]) != NULL) { count++; - snd_iprintf(buffer, "%i [%-15s]: %s - %s\n", + snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n", idx, card->id, card->driver, card->shortname); - snd_iprintf(buffer, " %s\n", + snd_iprintf(buffer, " %s\n", card->longname); } - read_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); } if (!count) snd_iprintf(buffer, "--- no soundcards ---\n"); } -#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) +#ifdef CONFIG_SND_OSSEMUL -void snd_card_info_read_oss(snd_info_buffer_t * buffer) +void snd_card_info_read_oss(struct snd_info_buffer *buffer) { int idx, count; - snd_card_t *card; + struct snd_card *card; for (idx = count = 0; idx < SNDRV_CARDS; idx++) { - read_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); if ((card = snd_cards[idx]) != NULL) { count++; snd_iprintf(buffer, "%s\n", card->longname); } - read_unlock(&snd_card_rwlock); + mutex_unlock(&snd_card_mutex); } if (!count) { snd_iprintf(buffer, "--- no soundcards ---\n"); @@ -506,28 +578,30 @@ void snd_card_info_read_oss(snd_info_buffer_t * buffer) #endif #ifdef MODULE -static snd_info_entry_t *snd_card_module_info_entry; -static void snd_card_module_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) +static struct snd_info_entry *snd_card_module_info_entry; +static void snd_card_module_info_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) { int idx; - snd_card_t *card; + struct snd_card *card; for (idx = 0; idx < SNDRV_CARDS; idx++) { - read_lock(&snd_card_rwlock); + mutex_lock(&snd_card_mutex); if ((card = snd_cards[idx]) != NULL) - snd_iprintf(buffer, "%i %s\n", idx, card->module->name); - read_unlock(&snd_card_rwlock); + snd_iprintf(buffer, "%2i %s\n", + idx, card->module->name); + mutex_unlock(&snd_card_mutex); } } #endif int __init snd_card_info_init(void) { - snd_info_entry_t *entry; + struct snd_info_entry *entry; entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); - snd_runtime_check(entry != NULL, return -ENOMEM); - entry->c.text.read_size = PAGE_SIZE; + if (! entry) + return -ENOMEM; entry->c.text.read = snd_card_info_read; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -538,7 +612,6 @@ int __init snd_card_info_init(void) #ifdef MODULE entry = snd_info_create_module_entry(THIS_MODULE, "modules", NULL); if (entry) { - entry->c.text.read_size = PAGE_SIZE; entry->c.text.read = snd_card_module_info_read; if (snd_info_register(entry) < 0) snd_info_free_entry(entry); @@ -552,15 +625,15 @@ int __init snd_card_info_init(void) int __exit snd_card_info_done(void) { - if (snd_card_info_entry) - snd_info_unregister(snd_card_info_entry); + snd_info_unregister(snd_card_info_entry); #ifdef MODULE - if (snd_card_module_info_entry) - snd_info_unregister(snd_card_module_info_entry); + snd_info_unregister(snd_card_module_info_entry); #endif return 0; } +#endif /* CONFIG_PROC_FS */ + /** * snd_component_add - add a component string * @card: soundcard structure @@ -572,7 +645,7 @@ int __exit snd_card_info_done(void) * Returns zero otherwise a negative error code. */ -int snd_component_add(snd_card_t *card, const char *component) +int snd_component_add(struct snd_card *card, const char *component) { char *ptr; int len = strlen(component); @@ -592,6 +665,8 @@ int snd_component_add(snd_card_t *card, const char *component) return 0; } +EXPORT_SYMBOL(snd_component_add); + /** * snd_card_file_add - add the file to the file list of the card * @card: soundcard structure @@ -603,7 +678,7 @@ int snd_component_add(snd_card_t *card, const char *component) * * Returns zero or a negative error code. */ -int snd_card_file_add(snd_card_t *card, struct file *file) +int snd_card_file_add(struct snd_card *card, struct file *file) { struct snd_monitor_file *mfile; @@ -624,6 +699,8 @@ int snd_card_file_add(snd_card_t *card, struct file *file) return 0; } +EXPORT_SYMBOL(snd_card_file_add); + /** * snd_card_file_remove - remove the file from the file list * @card: soundcard structure @@ -637,7 +714,7 @@ int snd_card_file_add(snd_card_t *card, struct file *file) * * Returns zero or a negative error code. */ -int snd_card_file_remove(snd_card_t *card, struct file *file) +int snd_card_file_remove(struct snd_card *card, struct file *file) { struct snd_monitor_file *mfile, *pfile = NULL; @@ -665,18 +742,19 @@ int snd_card_file_remove(snd_card_t *card, struct file *file) return 0; } +EXPORT_SYMBOL(snd_card_file_remove); + #ifdef CONFIG_PM /** * snd_power_wait - wait until the power-state is changed. * @card: soundcard structure * @power_state: expected power state - * @file: file structure for the O_NONBLOCK check (optional) * * Waits until the power-state is changed. * * Note: the power lock must be active before call. */ -int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file) +int snd_power_wait(struct snd_card *card, unsigned int power_state) { wait_queue_t wait; int result = 0; @@ -693,12 +771,6 @@ int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file } if (snd_power_get_state(card) == power_state) break; -#if 0 /* block all devices */ - if (file && (file->f_flags & O_NONBLOCK)) { - result = -EAGAIN; - break; - } -#endif set_current_state(TASK_UNINTERRUPTIBLE); snd_power_unlock(card); schedule_timeout(30 * HZ); @@ -708,180 +780,5 @@ int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file return result; } -/** - * snd_card_set_pm_callback - set the PCI power-management callbacks - * @card: soundcard structure - * @suspend: suspend callback function - * @resume: resume callback function - * @private_data: private data to pass to the callback functions - * - * Sets the power-management callback functions of the card. - * These callbacks are called from ALSA's common PCI suspend/resume - * handler and from the control API. - */ -int snd_card_set_pm_callback(snd_card_t *card, - int (*suspend)(snd_card_t *, pm_message_t), - int (*resume)(snd_card_t *), - void *private_data) -{ - card->pm_suspend = suspend; - card->pm_resume = resume; - card->pm_private_data = private_data; - return 0; -} - -#ifdef CONFIG_SND_GENERIC_PM -/* - * use platform_device for generic power-management without a proper bus - * (e.g. ISA) - */ -struct snd_generic_device { - struct platform_device pdev; - snd_card_t *card; -}; - -#define get_snd_generic_card(dev) container_of(to_platform_device(dev), struct snd_generic_device, pdev)->card - -#define SND_GENERIC_NAME "snd_generic_pm" - -static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level); -static int snd_generic_resume(struct device *dev, u32 level); - -static struct device_driver snd_generic_driver = { - .name = SND_GENERIC_NAME, - .bus = &platform_bus_type, - .suspend = snd_generic_suspend, - .resume = snd_generic_resume, -}; - -static int generic_driver_registered; - -static void generic_driver_unregister(void) -{ - if (generic_driver_registered) { - generic_driver_registered--; - if (! generic_driver_registered) - driver_unregister(&snd_generic_driver); - } -} - -static struct snd_generic_device *snd_generic_device_register(snd_card_t *card) -{ - struct snd_generic_device *dev; - - if (! generic_driver_registered) { - if (driver_register(&snd_generic_driver) < 0) - return NULL; - } - generic_driver_registered++; - - dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); - if (! dev) { - generic_driver_unregister(); - return NULL; - } - - dev->pdev.name = SND_GENERIC_NAME; - dev->pdev.id = card->number; - dev->card = card; - if (platform_device_register(&dev->pdev) < 0) { - kfree(dev); - generic_driver_unregister(); - return NULL; - } - return dev; -} - -static void snd_generic_device_unregister(struct snd_generic_device *dev) -{ - platform_device_unregister(&dev->pdev); - kfree(dev); - generic_driver_unregister(); -} - -/* suspend/resume callbacks for snd_generic platform device */ -static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level) -{ - snd_card_t *card; - - if (level != SUSPEND_DISABLE) - return 0; - - card = get_snd_generic_card(dev); - if (card->power_state == SNDRV_CTL_POWER_D3hot) - return 0; - card->pm_suspend(card, PMSG_SUSPEND); - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - return 0; -} - -static int snd_generic_resume(struct device *dev, u32 level) -{ - snd_card_t *card; - - if (level != RESUME_ENABLE) - return 0; - - card = get_snd_generic_card(dev); - if (card->power_state == SNDRV_CTL_POWER_D0) - return 0; - card->pm_resume(card); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} - -/** - * snd_card_set_generic_pm_callback - set the generic power-management callbacks - * @card: soundcard structure - * @suspend: suspend callback function - * @resume: resume callback function - * @private_data: private data to pass to the callback functions - * - * Registers the power-management and sets the lowlevel callbacks for - * the given card. These callbacks are called from the ALSA's common - * PM handler and from the control API. - */ -int snd_card_set_generic_pm_callback(snd_card_t *card, - int (*suspend)(snd_card_t *, pm_message_t), - int (*resume)(snd_card_t *), - void *private_data) -{ - card->pm_dev = snd_generic_device_register(card); - if (! card->pm_dev) - return -ENOMEM; - snd_card_set_pm_callback(card, suspend, resume, private_data); - return 0; -} -#endif /* CONFIG_SND_GENERIC_PM */ - -#ifdef CONFIG_PCI -int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state) -{ - snd_card_t *card = pci_get_drvdata(dev); - int err; - if (! card || ! card->pm_suspend) - return 0; - if (card->power_state == SNDRV_CTL_POWER_D3hot) - return 0; - err = card->pm_suspend(card, PMSG_SUSPEND); - pci_save_state(dev); - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - return err; -} - -int snd_card_pci_resume(struct pci_dev *dev) -{ - snd_card_t *card = pci_get_drvdata(dev); - if (! card || ! card->pm_resume) - return 0; - if (card->power_state == SNDRV_CTL_POWER_D0) - return 0; - /* restore the PCI config space */ - pci_restore_state(dev); - card->pm_resume(card); - snd_power_change_state(card, SNDRV_CTL_POWER_D0); - return 0; -} -#endif - +EXPORT_SYMBOL(snd_power_wait); #endif /* CONFIG_PM */