X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Finit.c;fp=sound%2Fcore%2Finit.c;h=39ed2e5bb0af1b4a5c4320d7f14300f08bc40b8e;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=d72f58f450ce442dac0386be21a94c567ac2e293;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/sound/core/init.c b/sound/core/init.c index d72f58f45..39ed2e5bb 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -28,6 +28,7 @@ #include #include #include + #include #include #include @@ -38,18 +39,46 @@ struct snd_shutdown_f_ops { }; unsigned int snd_cards_lock = 0; /* locked for registering/using */ -snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; +struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL}; DEFINE_RWLOCK(snd_card_rwlock); #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); #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_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; + return 0; +} +#else /* !CONFIG_PROC_FS */ +#define init_info_for_card(card) +#endif + static void snd_card_free_thread(void * __card); /** @@ -61,18 +90,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) { @@ -116,7 +145,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 +159,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 +169,44 @@ snd_card_t *snd_card_new(int idx, const char *xid, return NULL; } +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 +218,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); @@ -195,7 +258,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,10 +298,6 @@ 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 - /** * snd_card_free - frees given soundcard structure * @card: soundcard structure @@ -241,7 +309,7 @@ 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; @@ -253,14 +321,7 @@ int snd_card_free(snd_card_t * card) #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 +343,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 */ @@ -302,7 +362,7 @@ int snd_card_free(snd_card_t * card) 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 +389,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 +405,9 @@ int snd_card_free_in_thread(snd_card_t * card) return -EFAULT; } -static void choose_default_id(snd_card_t * card) +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 +449,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,12 +480,11 @@ 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); @@ -435,22 +497,7 @@ int snd_card_register(snd_card_t * card) 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: + 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,23 +505,25 @@ int snd_card_register(snd_card_t * card) return 0; } -static snd_info_entry_t *snd_card_info_entry = NULL; +#ifdef CONFIG_PROC_FS +static struct snd_info_entry *snd_card_info_entry = NULL; -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); 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); @@ -483,12 +532,12 @@ static void snd_card_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buff 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); @@ -506,16 +555,18 @@ 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); if ((card = snd_cards[idx]) != NULL) - snd_iprintf(buffer, "%i %s\n", idx, card->module->name); + snd_iprintf(buffer, "%2i %s\n", + idx, card->module->name); read_unlock(&snd_card_rwlock); } } @@ -523,10 +574,11 @@ static void snd_card_module_info_read(snd_info_entry_t *entry, snd_info_buffer_t 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); + if (! entry) + return -ENOMEM; entry->c.text.read_size = PAGE_SIZE; entry->c.text.read = snd_card_info_read; if (snd_info_register(entry) < 0) { @@ -552,15 +604,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 +624,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); @@ -603,7 +655,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; @@ -637,7 +689,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; @@ -670,13 +722,12 @@ int snd_card_file_remove(snd_card_t *card, struct file *file) * 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 +744,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 +753,4 @@ 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 - #endif /* CONFIG_PM */