diff options
Diffstat (limited to 'sound/core')
35 files changed, 606 insertions, 1268 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index f79755f77a8..9dd121bb563 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -73,6 +73,15 @@ config SND_PCM_OSS To compile this driver as a module, choose M here: the module will be called snd-pcm-oss. +config SND_PCM_OSS_PLUGINS + bool "OSS PCM (digital audio) API - Include plugin system" + depends on SND_PCM_OSS + default y + help + If you disable this option, the ALSA's OSS PCM API will not + support conversion of channels, formats and rates. It will + behave like most of new OSS/Free drivers in 2.4/2.6 kernels. + config SND_SEQUENCER_OSS bool "OSS Sequencer API" depends on SND && SND_SEQUENCER @@ -130,6 +139,15 @@ config SND_SUPPORT_OLD_API Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3 or older). +config SND_VERBOSE_PROCFS + bool "Verbose procfs contents" + depends on SND + default y + help + Say Y here to include code for verbose procfs contents (provides + usefull information to developers when a problem occurs). On the + other side, it makes the ALSA subsystem larger. + config SND_VERBOSE_PRINTK bool "Verbose printk" depends on SND diff --git a/sound/core/control.c b/sound/core/control.c index abd62f94372..574745314e7 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -309,28 +309,29 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { struct snd_ctl_elem_id id; unsigned int idx; + int err = -EINVAL; - snd_assert(card != NULL, return -EINVAL); if (! kcontrol) - return -EINVAL; - snd_assert(kcontrol->info != NULL, return -EINVAL); + return err; + snd_assert(card != NULL, goto error); + snd_assert(kcontrol->info != NULL, goto error); id = kcontrol->id; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { up_write(&card->controls_rwsem); - snd_ctl_free_one(kcontrol); snd_printd(KERN_ERR "control %i:%i:%i:%s:%i is already present\n", id.iface, id.device, id.subdevice, id.name, id.index); - return -EBUSY; + err = -EBUSY; + goto error; } if (snd_ctl_find_hole(card, kcontrol->count) < 0) { up_write(&card->controls_rwsem); - snd_ctl_free_one(kcontrol); - return -ENOMEM; + err = -ENOMEM; + goto error; } list_add_tail(&kcontrol->list, &card->controls); card->controls_count += kcontrol->count; @@ -340,6 +341,10 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); return 0; + + error: + snd_ctl_free_one(kcontrol); + return err; } /** @@ -658,7 +663,11 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, if (copy_from_user(&info, _info, sizeof(info))) return -EFAULT; - result = snd_ctl_elem_info(ctl, &info); + snd_power_lock(ctl->card); + result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); + if (result >= 0) + result = snd_ctl_elem_info(ctl, &info); + snd_power_unlock(ctl->card); if (result >= 0) if (copy_to_user(_info, &info, sizeof(info))) return -EFAULT; @@ -708,7 +717,11 @@ static int snd_ctl_elem_read_user(struct snd_card *card, kfree(control); return -EFAULT; } - result = snd_ctl_elem_read(card, control); + snd_power_lock(card); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); + if (result >= 0) + result = snd_ctl_elem_read(card, control); + snd_power_unlock(card); if (result >= 0) if (copy_to_user(_control, control, sizeof(*control))) result = -EFAULT; @@ -758,6 +771,7 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, struct snd_ctl_elem_value __user *_control) { struct snd_ctl_elem_value *control; + struct snd_card *card; int result; control = kmalloc(sizeof(*control), GFP_KERNEL); @@ -767,7 +781,12 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, kfree(control); return -EFAULT; } - result = snd_ctl_elem_write(file->card, file, control); + card = file->card; + snd_power_lock(card); + result = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); + if (result >= 0) + result = snd_ctl_elem_write(card, file, control); + snd_power_unlock(card); if (result >= 0) if (copy_to_user(_control, control, sizeof(*control))) result = -EFAULT; @@ -959,17 +978,15 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl.private_free = snd_ctl_elem_user_free; _kctl = snd_ctl_new(&kctl, access); if (_kctl == NULL) { - kfree(_kctl->private_data); + kfree(ue); return -ENOMEM; } _kctl->private_data = ue; for (idx = 0; idx < _kctl->count; idx++) _kctl->vd[idx].owner = file; err = snd_ctl_add(card, _kctl); - if (err < 0) { - snd_ctl_free_one(_kctl); + if (err < 0) return err; - } down_write(&card->controls_rwsem); card->user_ctl_count++; diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 418c6d4e5da..84fef5084e1 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -107,7 +107,13 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, */ if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) goto error; - err = snd_ctl_elem_info(ctl, data); + + snd_power_lock(ctl->card); + err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0, NULL); + if (err >= 0) + err = snd_ctl_elem_info(ctl, data); + snd_power_unlock(ctl->card); + if (err < 0) goto error; /* restore info to 32bit */ @@ -167,7 +173,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, int *countp) { struct snd_kcontrol *kctl; - struct snd_ctl_elem_info info; + struct snd_ctl_elem_info *info; int err; down_read(&card->controls_rwsem); @@ -176,13 +182,19 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, up_read(&card->controls_rwsem); return -ENXIO; } - info.id = *id; - err = kctl->info(kctl, &info); + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (info == NULL) { + up_read(&card->controls_rwsem); + return -ENOMEM; + } + info->id = *id; + err = kctl->info(kctl, info); up_read(&card->controls_rwsem); if (err >= 0) { - err = info.type; - *countp = info.count; + err = info->type; + *countp = info->count; } + kfree(info); return err; } @@ -280,9 +292,14 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card, if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) goto error; - if ((err = snd_ctl_elem_read(card, data)) < 0) - goto error; - err = copy_ctl_value_to_user(data32, data, type, count); + + snd_power_lock(card); + err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); + if (err >= 0) + err = snd_ctl_elem_read(card, data); + snd_power_unlock(card); + if (err >= 0) + err = copy_ctl_value_to_user(data32, data, type, count); error: kfree(data); return err; @@ -292,17 +309,23 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, struct snd_ctl_elem_value32 __user *data32) { struct snd_ctl_elem_value *data; + struct snd_card *card = file->card; int err, type, count; data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return -ENOMEM; - if ((err = copy_ctl_value_from_user(file->card, data, data32, &type, &count)) < 0) - goto error; - if ((err = snd_ctl_elem_write(file->card, file, data)) < 0) + if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) goto error; - err = copy_ctl_value_to_user(data32, data, type, count); + + snd_power_lock(card); + err = snd_power_wait(card, SNDRV_CTL_POWER_D0, NULL); + if (err >= 0) + err = snd_ctl_elem_write(card, file, data); + snd_power_unlock(card); + if (err >= 0) + err = copy_ctl_value_to_user(data32, data, type, count); error: kfree(data); return err; diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 618c43be0bc..2524e66eccd 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -25,6 +25,7 @@ #include <linux/smp_lock.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/control.h> #include <sound/minors.h> @@ -36,7 +37,7 @@ MODULE_DESCRIPTION("Hardware dependent layer"); MODULE_LICENSE("GPL"); static LIST_HEAD(snd_hwdep_devices); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static int snd_hwdep_free(struct snd_hwdep *hwdep); static int snd_hwdep_dev_free(struct snd_device *device); @@ -111,7 +112,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); - down(&hw->open_mutex); + mutex_lock(&hw->open_mutex); while (1) { if (hw->exclusive && hw->used > 0) { err = -EBUSY; @@ -128,9 +129,9 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) } else break; set_current_state(TASK_INTERRUPTIBLE); - up(&hw->open_mutex); + mutex_unlock(&hw->open_mutex); schedule(); - down(&hw->open_mutex); + mutex_lock(&hw->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -147,7 +148,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file) hw->ops.release(hw, file); } } - up(&hw->open_mutex); + mutex_unlock(&hw->open_mutex); if (err < 0) module_put(hw->card->module); return err; @@ -157,7 +158,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) { int err = -ENXIO; struct snd_hwdep *hw = file->private_data; - down(&hw->open_mutex); + mutex_lock(&hw->open_mutex); if (hw->ops.release) { err = hw->ops.release(hw, file); wake_up(&hw->open_wait); @@ -165,7 +166,7 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) if (hw->used > 0) hw->used--; snd_card_file_remove(hw->card, file); - up(&hw->open_mutex); + mutex_unlock(&hw->open_mutex); module_put(hw->card->module); return err; } @@ -272,7 +273,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_MINOR_HWDEPS) { if (snd_hwdep_search(card, device)) @@ -281,7 +282,7 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, } if (device >= SNDRV_MINOR_HWDEPS) device = -1; - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (put_user(device, (int __user *)arg)) return -EFAULT; return 0; @@ -294,13 +295,13 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, if (get_user(device, &info->device)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); hwdep = snd_hwdep_search(card, device); if (hwdep) err = snd_hwdep_info(hwdep, info); else err = -ENXIO; - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } } @@ -375,7 +376,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, return err; } init_waitqueue_head(&hwdep->open_wait); - init_MUTEX(&hwdep->open_mutex); + mutex_init(&hwdep->open_mutex); *rhwdep = hwdep; return 0; } @@ -401,9 +402,9 @@ static int snd_hwdep_dev_register(struct snd_device *device) int err; char name[32]; - down(®ister_mutex); + mutex_lock(®ister_mutex); if (snd_hwdep_search(hwdep->card, hwdep->device)) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } list_add_tail(&hwdep->list, &snd_hwdep_devices); @@ -414,7 +415,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", hwdep->card->number, hwdep->device); list_del(&hwdep->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } #ifdef CONFIG_SND_OSSEMUL @@ -434,7 +435,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) } } #endif - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -443,9 +444,9 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) struct snd_hwdep *hwdep = device->device_data; snd_assert(hwdep != NULL, return -ENXIO); - down(®ister_mutex); + mutex_lock(®ister_mutex); if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EINVAL; } #ifdef CONFIG_SND_OSSEMUL @@ -454,7 +455,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) #endif snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); list_del(&hwdep->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return snd_hwdep_free(hwdep); } @@ -469,13 +470,13 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry, struct list_head *p; struct snd_hwdep *hwdep; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_for_each(p, &snd_hwdep_devices) { hwdep = list_entry(p, struct snd_hwdep, list); snd_iprintf(buffer, "%02i-%02i: %s\n", hwdep->card->number, hwdep->device, hwdep->name); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); } static struct snd_info_entry *snd_hwdep_proc_entry; diff --git a/sound/core/info.c b/sound/core/info.c index af123e3bdb2..2582b74d319 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -31,6 +31,7 @@ #include <sound/version.h> #include <linux/proc_fs.h> #include <linux/devfs_fs_kernel.h> +#include <linux/mutex.h> #include <stdarg.h> /* @@ -68,7 +69,7 @@ int snd_info_check_reserved_words(const char *str) return 1; } -static DECLARE_MUTEX(info_mutex); +static DEFINE_MUTEX(info_mutex); struct snd_info_private_data { struct snd_info_buffer *rbuffer; @@ -265,11 +266,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) struct proc_dir_entry *p; int mode, err; - down(&info_mutex); + mutex_lock(&info_mutex); p = PDE(inode); entry = p == NULL ? NULL : (struct snd_info_entry *)p->data; if (entry == NULL || entry->disconnected) { - up(&info_mutex); + mutex_unlock(&info_mutex); return -ENODEV; } if (!try_module_get(entry->module)) { @@ -361,13 +362,13 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) break; } file->private_data = data; - up(&info_mutex); + mutex_unlock(&info_mutex); if (entry->content == SNDRV_INFO_CONTENT_TEXT && (mode == O_RDONLY || mode == O_RDWR)) { if (entry->c.text.read) { - down(&entry->access); + mutex_lock(&entry->access); entry->c.text.read(entry, data->rbuffer); - up(&entry->access); + mutex_unlock(&entry->access); } } return 0; @@ -375,7 +376,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) __error: module_put(entry->module); __error1: - up(&info_mutex); + mutex_unlock(&info_mutex); return err; } @@ -747,7 +748,7 @@ static struct snd_info_entry *snd_info_create_entry(const char *name) } entry->mode = S_IFREG | S_IRUGO; entry->content = SNDRV_INFO_CONTENT_TEXT; - init_MUTEX(&entry->access); + mutex_init(&entry->access); return entry; } @@ -896,10 +897,10 @@ int snd_info_register(struct snd_info_entry * entry) snd_assert(entry != NULL, return -ENXIO); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; - down(&info_mutex); + mutex_lock(&info_mutex); p = snd_create_proc_entry(entry->name, entry->mode, root); if (!p) { - up(&info_mutex); + mutex_unlock(&info_mutex); return -ENOMEM; } p->owner = entry->module; @@ -908,7 +909,7 @@ int snd_info_register(struct snd_info_entry * entry) p->size = entry->size; p->data = entry; entry->p = p; - up(&info_mutex); + mutex_unlock(&info_mutex); return 0; } @@ -929,9 +930,9 @@ int snd_info_unregister(struct snd_info_entry * entry) snd_assert(entry->p != NULL, return -ENXIO); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; snd_assert(root, return -ENXIO); - down(&info_mutex); + mutex_lock(&info_mutex); snd_remove_proc_entry(root, entry->p); - up(&info_mutex); + mutex_unlock(&info_mutex); snd_info_free_entry(entry); return 0; } diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index 820f4772e44..f9ce854b3d1 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c @@ -28,6 +28,7 @@ #include <sound/info.h> #include <sound/version.h> #include <linux/utsname.h> +#include <linux/mutex.h> #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS) @@ -35,7 +36,7 @@ * OSS compatible part */ -static DECLARE_MUTEX(strings); +static DEFINE_MUTEX(strings); static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT]; static struct snd_info_entry *snd_sndstat_proc_entry; @@ -45,7 +46,7 @@ int snd_oss_info_register(int dev, int num, char *string) snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); - down(&strings); + mutex_lock(&strings); if (string == NULL) { if ((x = snd_sndstat_strings[num][dev]) != NULL) { kfree(x); @@ -54,12 +55,12 @@ int snd_oss_info_register(int dev, int num, char *string) } else { x = kstrdup(string, GFP_KERNEL); if (x == NULL) { - up(&strings); + mutex_unlock(&strings); return -ENOMEM; } } snd_sndstat_strings[num][dev] = x; - up(&strings); + mutex_unlock(&strings); return 0; } @@ -71,7 +72,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d char *str; snd_iprintf(buf, "\n%s:", id); - down(&strings); + mutex_lock(&strings); for (idx = 0; idx < SNDRV_CARDS; idx++) { str = snd_sndstat_strings[idx][dev]; if (str) { @@ -82,7 +83,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d snd_iprintf(buf, "%i: %s\n", idx, str); } } - up(&strings); + mutex_unlock(&strings); if (ok < 0) snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); return ok; diff --git a/sound/core/init.c b/sound/core/init.c index 75816688607..ad68761abba 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -145,7 +145,7 @@ struct snd_card *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 */ @@ -169,11 +169,44 @@ struct snd_card *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 @@ -224,7 +257,16 @@ int snd_card_disconnect(struct snd_card *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; diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 19b3dcbb09c..3fc6f97075e 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -31,7 +31,7 @@ #include <asm/uaccess.h> #include <linux/dma-mapping.h> #include <linux/moduleparam.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <sound/memalloc.h> #ifdef CONFIG_SBUS #include <asm/sbus.h> @@ -54,7 +54,7 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab); /* */ -static DECLARE_MUTEX(list_mutex); +static DEFINE_MUTEX(list_mutex); static LIST_HEAD(mem_list_head); /* buffer preservation list */ @@ -83,7 +83,7 @@ struct snd_mem_list { * Hacks */ -#if defined(__i386__) || defined(__ppc__) || defined(__x86_64__) +#if defined(__i386__) /* * A hack to allocate large buffers via dma_alloc_coherent() * @@ -141,10 +141,6 @@ static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, #endif /* arch */ -#if ! defined(__arm__) -#define NEED_RESERVE_PAGES -#endif - /* * * Generic memory allocators @@ -163,20 +159,6 @@ static inline void dec_snd_pages(int order) snd_allocated_pages -= 1 << order; } -static void mark_pages(struct page *page, int order) -{ - struct page *last_page = page + (1 << order); - while (page < last_page) - SetPageReserved(page++); -} - -static void unmark_pages(struct page *page, int order) -{ - struct page *last_page = page + (1 << order); - while (page < last_page) - ClearPageReserved(page++); -} - /** * snd_malloc_pages - allocate pages with the given size * @size: the size to allocate in bytes @@ -195,10 +177,8 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) snd_assert(gfp_flags != 0, return NULL); gfp_flags |= __GFP_COMP; /* compound page lets parts be mapped */ pg = get_order(size); - if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) { - mark_pages(virt_to_page(res), pg); + if ((res = (void *) __get_free_pages(gfp_flags, pg)) != NULL) inc_snd_pages(pg); - } return res; } @@ -217,7 +197,6 @@ void snd_free_pages(void *ptr, size_t size) return; pg = get_order(size); dec_snd_pages(pg); - unmark_pages(virt_to_page(ptr), pg); free_pages((unsigned long) ptr, pg); } @@ -242,12 +221,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d | __GFP_NORETRY /* don't trigger OOM-killer */ | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ res = dma_alloc_coherent(dev, PAGE_SIZE << pg, dma, gfp_flags); - if (res != NULL) { -#ifdef NEED_RESERVE_PAGES - mark_pages(virt_to_page(res), pg); /* should be dma_to_page() */ -#endif + if (res != NULL) inc_snd_pages(pg); - } return res; } @@ -262,9 +237,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, return; pg = get_order(size); dec_snd_pages(pg); -#ifdef NEED_RESERVE_PAGES - unmark_pages(virt_to_page(ptr), pg); /* should be dma_to_page() */ -#endif dma_free_coherent(dev, PAGE_SIZE << pg, ptr, dma); } @@ -440,7 +412,7 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) snd_assert(dmab, return 0); - down(&list_mutex); + mutex_lock(&list_mutex); list_for_each(p, &mem_list_head) { mem = list_entry(p, struct snd_mem_list, list); if (mem->id == id && @@ -452,11 +424,11 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) if (dmab->dev.dev == NULL) dmab->dev.dev = dev; kfree(mem); - up(&list_mutex); + mutex_unlock(&list_mutex); return dmab->bytes; } } - up(&list_mutex); + mutex_unlock(&list_mutex); return 0; } @@ -477,11 +449,11 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) mem = kmalloc(sizeof(*mem), GFP_KERNEL); if (! mem) return -ENOMEM; - down(&list_mutex); + mutex_lock(&list_mutex); mem->buffer = *dmab; mem->id = id; list_add_tail(&mem->list, &mem_list_head); - up(&list_mutex); + mutex_unlock(&list_mutex); return 0; } @@ -493,7 +465,7 @@ static void free_all_reserved_pages(void) struct list_head *p; struct snd_mem_list *mem; - down(&list_mutex); + mutex_lock(&list_mutex); while (! list_empty(&mem_list_head)) { p = mem_list_head.next; mem = list_entry(p, struct snd_mem_list, list); @@ -501,7 +473,7 @@ static void free_all_reserved_pages(void) snd_dma_free_pages(&mem->buffer); kfree(mem); } - up(&list_mutex); + mutex_unlock(&list_mutex); } @@ -522,7 +494,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, int devno; static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; - down(&list_mutex); + mutex_lock(&list_mutex); len += snprintf(page + len, count - len, "pages : %li bytes (%li pages per %likB)\n", pages * PAGE_SIZE, pages, PAGE_SIZE / 1024); @@ -537,7 +509,7 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, " addr = 0x%lx, size = %d bytes\n", (unsigned long)mem->buffer.addr, (int)mem->buffer.bytes); } - up(&list_mutex); + mutex_unlock(&list_mutex); return len; } diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c index d6a04c2d5a7..6658facc5cd 100644 --- a/sound/core/oss/copy.c +++ b/sound/core/oss/copy.c @@ -20,6 +20,9 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> @@ -85,3 +88,5 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index 322702e05f3..b6e7ce30e5a 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c @@ -20,6 +20,9 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> @@ -132,3 +135,5 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index 8cbfa415ce4..5b1bcdc6477 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c @@ -21,6 +21,9 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> @@ -103,7 +106,7 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, return frames; } -int conv_index(int src_format, int dst_format) +static int conv_index(int src_format, int dst_format) { int src_endian, dst_endian, sign, src_width, dst_width; @@ -156,3 +159,5 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index f08e65a2bff..9c68bc3f97a 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -1095,7 +1095,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, struct snd_mixer_oss *mixer = entry->private_data; int i; - down(&mixer->reg_mutex); + mutex_lock(&mixer->reg_mutex); for (i = 0; i < SNDRV_OSS_MAX_MIXERS; i++) { struct slot *p; @@ -1110,7 +1110,7 @@ static void snd_mixer_oss_proc_read(struct snd_info_entry *entry, else snd_iprintf(buffer, "\"\" 0\n"); } - up(&mixer->reg_mutex); + mutex_unlock(&mixer->reg_mutex); } static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, @@ -1134,9 +1134,9 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, cptr = snd_info_get_str(str, cptr, sizeof(str)); if (! *str) { /* remove the entry */ - down(&mixer->reg_mutex); + mutex_lock(&mixer->reg_mutex); mixer_slot_clear(&mixer->slots[ch]); - up(&mixer->reg_mutex); + mutex_unlock(&mixer->reg_mutex); continue; } snd_info_get_str(idxstr, cptr, sizeof(idxstr)); @@ -1145,7 +1145,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, snd_printk(KERN_ERR "mixer_oss: invalid index %d\n", idx); continue; } - down(&mixer->reg_mutex); + mutex_lock(&mixer->reg_mutex); slot = (struct slot *)mixer->slots[ch].private_data; if (slot && slot->assigned && slot->assigned->index == idx && ! strcmp(slot->assigned->name, str)) @@ -1168,7 +1168,7 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry, kfree(tbl); } __unlock: - up(&mixer->reg_mutex); + mutex_unlock(&mixer->reg_mutex); } } @@ -1288,7 +1288,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); if (mixer == NULL) return -ENOMEM; - init_MUTEX(&mixer->reg_mutex); + mutex_init(&mixer->reg_mutex); sprintf(name, "mixer%i%i", card->number, 0); if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, card, 0, diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c index 14f5578ec7a..2eb18807e6d 100644 --- a/sound/core/oss/mulaw.c +++ b/sound/core/oss/mulaw.c @@ -22,6 +22,9 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> @@ -262,6 +265,25 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin, return frames; } +static int getput_index(int format) +{ + int sign, width, endian; + sign = !snd_pcm_format_signed(format); + width = snd_pcm_format_width(format) / 8 - 1; + if (width < 0 || width > 3) { + snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); + width = 0; + } +#ifdef SNDRV_LITTLE_ENDIAN + endian = snd_pcm_format_big_endian(format); +#else + endian = snd_pcm_format_little_endian(format); +#endif + if (endian < 0) + endian = 0; + return width * 4 + endian * 2 + sign; +} + int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, @@ -306,3 +328,5 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 7fd072392c7..f8302b703a3 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -78,6 +78,7 @@ static inline void snd_leave_user(mm_segment_t fs) set_fs(fs); } +#ifdef CONFIG_SND_PCM_OSS_PLUGINS static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -122,6 +123,7 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin) } return 0; } +#endif /* CONFIG_SND_PCM_OSS_PLUGINS */ static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) { @@ -412,6 +414,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * params_channels(params) / 8; +#ifdef CONFIG_SND_PCM_OSS_PLUGINS snd_pcm_oss_plugin_clear(substream); if (!direct) { /* add necessary plugins */ @@ -441,6 +444,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) } } } +#endif err = snd_pcm_oss_period_size(substream, params, sparams); if (err < 0) @@ -498,11 +502,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) runtime->oss.periods = params_periods(sparams); oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); +#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { err = snd_pcm_plug_alloc(substream, oss_period_size); if (err < 0) goto failure; } +#endif oss_period_size *= oss_frame_size; oss_buffer_size = oss_period_size * runtime->oss.periods; @@ -784,6 +790,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; +#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; @@ -800,7 +807,9 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha if (frames1 <= 0) return frames1; bytes = frames1 * oss_frame_bytes; - } else { + } else +#endif + { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -871,6 +880,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; +#ifdef CONFIG_SND_PCM_OSS_PLUGINS char __user *final_dst = (char __user *)buf; if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; @@ -887,7 +897,9 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, bytes = frames1 * oss_frame_bytes; if (!in_kernel && copy_to_user(final_dst, buf, bytes)) return -EFAULT; - } else { + } else +#endif + { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -1631,10 +1643,10 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, const char *ptr, *ptrl; struct snd_pcm_oss_setup *setup; - down(&pcm->streams[stream].oss.setup_mutex); + mutex_lock(&pcm->streams[stream].oss.setup_mutex); for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { if (!strcmp(setup->task_name, task_name)) { - up(&pcm->streams[stream].oss.setup_mutex); + mutex_unlock(&pcm->streams[stream].oss.setup_mutex); return setup; } } @@ -1650,12 +1662,12 @@ static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, } for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { if (!strcmp(setup->task_name, ptrl)) { - up(&pcm->streams[stream].oss.setup_mutex); + mutex_unlock(&pcm->streams[stream].oss.setup_mutex); return setup; } } __not_found: - up(&pcm->streams[stream].oss.setup_mutex); + mutex_unlock(&pcm->streams[stream].oss.setup_mutex); return NULL; } @@ -1692,7 +1704,9 @@ static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime; runtime = substream->runtime; vfree(runtime->oss.buffer); +#ifdef CONFIG_SND_PCM_OSS_PLUGINS snd_pcm_oss_plugin_clear(substream); +#endif substream->oss.file = NULL; substream->oss.oss = 0; } @@ -1881,7 +1895,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) init_waitqueue_entry(&wait, current); add_wait_queue(&pcm->open_wait, &wait); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); while (1) { err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, iminor(inode), psetup, csetup); @@ -1895,16 +1909,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); schedule(); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&pcm->open_wait, &wait); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); if (err < 0) goto __error; return err; @@ -1930,9 +1944,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) snd_assert(substream != NULL, return -ENXIO); pcm = substream->pcm; snd_pcm_oss_sync(pcm_oss_file); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); snd_pcm_oss_release_file(pcm_oss_file); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); @@ -2246,8 +2260,10 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) if ((err = snd_pcm_oss_change_params(substream)) < 0) return err; } +#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first != NULL) return -EIO; +#endif if (area->vm_pgoff != 0) return -EINVAL; @@ -2277,7 +2293,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, { struct snd_pcm_str *pstr = entry->private_data; struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; - down(&pstr->oss.setup_mutex); + mutex_lock(&pstr->oss.setup_mutex); while (setup) { snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", setup->task_name, @@ -2291,7 +2307,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, setup->nosilence ? " no-silence" : ""); setup = setup->next; } - up(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); } static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) @@ -2321,12 +2337,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, struct snd_pcm_oss_setup *setup, *setup1, template; while (!snd_info_get_line(buffer, line, sizeof(line))) { - down(&pstr->oss.setup_mutex); + mutex_lock(&pstr->oss.setup_mutex); memset(&template, 0, sizeof(template)); ptr = snd_info_get_str(task_name, line, sizeof(task_name)); if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { snd_pcm_oss_proc_free_setup_list(pstr); - up(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); continue; } for (setup = pstr->oss.setup_list; setup; setup = setup->next) { @@ -2378,7 +2394,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, } if (setup) *setup = template; - up(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); } } diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 7e8676880dd..0e67dd280a5 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -25,6 +25,9 @@ #endif #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/slab.h> #include <linux/time.h> #include <linux/vmalloc.h> @@ -36,26 +39,6 @@ #define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first) #define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last) -static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin, - unsigned long *dst_vmask, - unsigned long **src_vmask) -{ - unsigned long *vmask = plugin->src_vmask; - bitmap_copy(vmask, dst_vmask, plugin->src_format.channels); - *src_vmask = vmask; - return 0; -} - -static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin, - unsigned long *src_vmask, - unsigned long **dst_vmask) -{ - unsigned long *vmask = plugin->dst_vmask; - bitmap_copy(vmask, src_vmask, plugin->dst_format.channels); - *dst_vmask = vmask; - return 0; -} - /* * because some cards might have rates "very close", we ignore * all "resampling" requests within +-5% @@ -193,19 +176,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, snd_pcm_plugin_free(plugin); return -ENOMEM; } - plugin->src_vmask = bitmap_alloc(src_format->channels); - if (plugin->src_vmask == NULL) { - snd_pcm_plugin_free(plugin); - return -ENOMEM; - } - plugin->dst_vmask = bitmap_alloc(dst_format->channels); - if (plugin->dst_vmask == NULL) { - snd_pcm_plugin_free(plugin); - return -ENOMEM; - } plugin->client_channels = snd_pcm_plugin_client_channels; - plugin->src_channels_mask = snd_pcm_plugin_src_channels_mask; - plugin->dst_channels_mask = snd_pcm_plugin_dst_channels_mask; *ret = plugin; return 0; } @@ -218,8 +189,6 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin) plugin->private_free(plugin); kfree(plugin->buf_channels); vfree(plugin->buf); - kfree(plugin->src_vmask); - kfree(plugin->dst_vmask); kfree(plugin); return 0; } @@ -429,24 +398,14 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, dstformat.channels); /* Format change (linearization) */ - if ((srcformat.format != dstformat.format || - !rate_match(srcformat.rate, dstformat.rate) || - srcformat.channels != dstformat.channels) && - !snd_pcm_format_linear(srcformat.format)) { - if (snd_pcm_format_linear(dstformat.format)) - tmpformat.format = dstformat.format; - else - tmpformat.format = SNDRV_PCM_FORMAT_S16; - switch (srcformat.format) { - case SNDRV_PCM_FORMAT_MU_LAW: - err = snd_pcm_plugin_build_mulaw(plug, - &srcformat, &tmpformat, - &plugin); - break; - default: + if (! rate_match(srcformat.rate, dstformat.rate) && + ! snd_pcm_format_linear(srcformat.format)) { + if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW) return -EINVAL; - } - pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err); + tmpformat.format = SNDRV_PCM_FORMAT_S16; + err = snd_pcm_plugin_build_mulaw(plug, + &srcformat, &tmpformat, + &plugin); if (err < 0) return err; err = snd_pcm_plugin_append(plugin); @@ -460,35 +419,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, /* channels reduction */ if (srcformat.channels > dstformat.channels) { - int sv = srcformat.channels; - int dv = dstformat.channels; - int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); - if (ttable == NULL) - return -ENOMEM; -#if 1 - if (sv == 2 && dv == 1) { - ttable[0] = HALF; - ttable[1] = HALF; - } else -#endif - { - int v; - for (v = 0; v < dv; ++v) - ttable[v * sv + v] = FULL; - } tmpformat.channels = dstformat.channels; - if (rate_match(srcformat.rate, dstformat.rate) && - snd_pcm_format_linear(dstformat.format)) - tmpformat.format = dstformat.format; - err = snd_pcm_plugin_build_route(plug, - &srcformat, &tmpformat, - ttable, &plugin); - kfree(ttable); + err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); - if (err < 0) { - snd_pcm_plugin_free(plugin); + if (err < 0) return err; - } err = snd_pcm_plugin_append(plugin); if (err < 0) { snd_pcm_plugin_free(plugin); @@ -500,18 +435,29 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, /* rate resampling */ if (!rate_match(srcformat.rate, dstformat.rate)) { + if (srcformat.format != SNDRV_PCM_FORMAT_S16) { + /* convert to S16 for resampling */ + tmpformat.format = SNDRV_PCM_FORMAT_S16; + err = snd_pcm_plugin_build_linear(plug, + &srcformat, &tmpformat, + &plugin); + if (err < 0) + return err; + err = snd_pcm_plugin_append(plugin); + if (err < 0) { + snd_pcm_plugin_free(plugin); + return err; + } + srcformat = tmpformat; + src_access = dst_access; + } tmpformat.rate = dstformat.rate; - if (srcformat.channels == dstformat.channels && - snd_pcm_format_linear(dstformat.format)) - tmpformat.format = dstformat.format; err = snd_pcm_plugin_build_rate(plug, &srcformat, &tmpformat, &plugin); pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err); - if (err < 0) { - snd_pcm_plugin_free(plugin); + if (err < 0) return err; - } err = snd_pcm_plugin_append(plugin); if (err < 0) { snd_pcm_plugin_free(plugin); @@ -521,56 +467,11 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, src_access = dst_access; } - /* channels extension */ - if (srcformat.channels < dstformat.channels) { - int sv = srcformat.channels; - int dv = dstformat.channels; - int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL); - if (ttable == NULL) - return -ENOMEM; -#if 0 - { - int v; - for (v = 0; v < sv; ++v) - ttable[v * sv + v] = FULL; - } -#else - { - /* Playback is spreaded on all channels */ - int vd, vs; - for (vd = 0, vs = 0; vd < dv; ++vd) { - ttable[vd * sv + vs] = FULL; - vs++; - if (vs == sv) - vs = 0; - } - } -#endif - tmpformat.channels = dstformat.channels; - if (snd_pcm_format_linear(dstformat.format)) - tmpformat.format = dstformat.format; - err = snd_pcm_plugin_build_route(plug, - &srcformat, &tmpformat, - ttable, &plugin); - kfree(ttable); - pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); - if (err < 0) { - snd_pcm_plugin_free(plugin); - return err; - } - err = snd_pcm_plugin_append(plugin); - if (err < 0) { - snd_pcm_plugin_free(plugin); - return err; - } - srcformat = tmpformat; - src_access = dst_access; - } - /* format change */ if (srcformat.format != dstformat.format) { tmpformat.format = dstformat.format; - if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { + if (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW || + tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) { err = snd_pcm_plugin_build_mulaw(plug, &srcformat, &tmpformat, &plugin); @@ -595,6 +496,22 @@ int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug, src_access = dst_access; } + /* channels extension */ + if (srcformat.channels < dstformat.channels) { + tmpformat.channels = dstformat.channels; + err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin); + pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err); + if (err < 0) + return err; + err = snd_pcm_plugin_append(plugin); + if (err < 0) { + snd_pcm_plugin_free(plugin); + return err; + } + srcformat = tmpformat; + src_access = dst_access; + } + /* de-interleave */ if (src_access != dst_access) { err = snd_pcm_plugin_build_copy(plug, @@ -650,92 +567,6 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu return count; } -static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug, - unsigned long *client_vmask) -{ - struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); - if (plugin == NULL) { - return 0; - } else { - int schannels = plugin->dst_format.channels; - DECLARE_BITMAP(bs, schannels); - unsigned long *srcmask; - unsigned long *dstmask = bs; - int err; - bitmap_fill(dstmask, schannels); - - while (1) { - err = plugin->src_channels_mask(plugin, dstmask, &srcmask); - if (err < 0) - return err; - dstmask = srcmask; - if (plugin->prev == NULL) - break; - plugin = plugin->prev; - } - bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels); - return 0; - } -} - -static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug, - struct snd_pcm_plugin_channel *src_channels) -{ - struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug); - unsigned int nchannels = plugin->src_format.channels; - DECLARE_BITMAP(bs, nchannels); - unsigned long *srcmask = bs; - int err; - unsigned int channel; - for (channel = 0; channel < nchannels; channel++) { - if (src_channels[channel].enabled) - set_bit(channel, srcmask); - else - clear_bit(channel, srcmask); - } - err = snd_pcm_plug_playback_channels_mask(plug, srcmask); - if (err < 0) - return err; - for (channel = 0; channel < nchannels; channel++) { - if (!test_bit(channel, srcmask)) - src_channels[channel].enabled = 0; - } - return 0; -} - -static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug, - struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *client_channels) -{ - struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug); - unsigned int nchannels = plugin->dst_format.channels; - DECLARE_BITMAP(bs, nchannels); - unsigned long *dstmask = bs; - unsigned long *srcmask; - int err; - unsigned int channel; - for (channel = 0; channel < nchannels; channel++) { - if (client_channels[channel].enabled) - set_bit(channel, dstmask); - else - clear_bit(channel, dstmask); - } - while (plugin) { - err = plugin->src_channels_mask(plugin, dstmask, &srcmask); - if (err < 0) - return err; - dstmask = srcmask; - plugin = plugin->prev; - } - plugin = snd_pcm_plug_first(plug); - nchannels = plugin->src_format.channels; - for (channel = 0; channel < nchannels; channel++) { - if (!test_bit(channel, dstmask)) - src_channels[channel].enabled = 0; - } - return 0; -} - snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size) { struct snd_pcm_plugin *plugin, *next; @@ -743,9 +574,6 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st int err; snd_pcm_sframes_t frames = size; - if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0) - return err; - plugin = snd_pcm_plug_first(plug); while (plugin && frames > 0) { if ((next = plugin->next) != NULL) { @@ -790,10 +618,6 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str return err; } frames = err; - if (!plugin->prev) { - if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0) - return err; - } } else { dst_channels = dst_channels_final; } @@ -916,3 +740,5 @@ int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_of } return 0; } + +#endif diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h index 29198da615c..3be91b3d537 100644 --- a/sound/core/oss/pcm_plugin.h +++ b/sound/core/oss/pcm_plugin.h @@ -22,12 +22,7 @@ * */ -#include <linux/bitmap.h> - -static inline unsigned long *bitmap_alloc(unsigned int nbits) -{ - return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL); -} +#ifdef CONFIG_SND_PCM_OSS_PLUGINS #define snd_pcm_plug_stream(plug) ((plug)->stream) @@ -69,12 +64,6 @@ struct snd_pcm_plugin { snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames, struct snd_pcm_plugin_channel **channels); - int (*src_channels_mask)(struct snd_pcm_plugin *plugin, - unsigned long *dst_vmask, - unsigned long **src_vmask); - int (*dst_channels_mask)(struct snd_pcm_plugin *plugin, - unsigned long *src_vmask, - unsigned long **dst_vmask); snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin, const struct snd_pcm_plugin_channel *src_channels, struct snd_pcm_plugin_channel *dst_channels, @@ -90,8 +79,6 @@ struct snd_pcm_plugin { char *buf; snd_pcm_uframes_t buf_frames; struct snd_pcm_plugin_channel *buf_channels; - unsigned long *src_vmask; - unsigned long *dst_vmask; char extra_data[0]; }; @@ -128,7 +115,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle, int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, - int *ttable, struct snd_pcm_plugin **r_plugin); int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle, struct snd_pcm_plugin_format *src_format, @@ -181,15 +167,13 @@ snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel); -#define ROUTE_PLUGIN_RESOLUTION 16 +#else -int getput_index(int format); -int copy_index(int format); -int conv_index(int src_format, int dst_format); +static inline snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size) { return drv_size; } +static inline snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size) { return clt_size; } +static inline int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { return format; } -void zero_channel(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *dst_channel, - size_t samples); +#endif #ifdef PLUGIN_DEBUG #define pdprintf( fmt, args... ) printk( "plugin: " fmt, ##args) diff --git a/sound/core/oss/plugin_ops.h b/sound/core/oss/plugin_ops.h index 0607e956608..1f5bde4631f 100644 --- a/sound/core/oss/plugin_ops.h +++ b/sound/core/oss/plugin_ops.h @@ -362,172 +362,6 @@ put_s16_xx12_0029: as_u32(dst) = (u_int32_t)swab16(sample) ^ 0x80; goto PUT_S16_ } #endif -#if 0 -#ifdef GET32_LABELS -/* src_wid src_endswap unsigned */ -static void *get32_labels[4 * 2 * 2] = { - &&get32_xxx1_1000, /* 8h -> 32h */ - &&get32_xxx1_9000, /* 8h ^> 32h */ - &&get32_xxx1_1000, /* 8s -> 32h */ - &&get32_xxx1_9000, /* 8s ^> 32h */ - &&get32_xx12_1200, /* 16h -> 32h */ - &&get32_xx12_9200, /* 16h ^> 32h */ - &&get32_xx12_2100, /* 16s -> 32h */ - &&get32_xx12_A100, /* 16s ^> 32h */ - &&get32_x123_1230, /* 24h -> 32h */ - &&get32_x123_9230, /* 24h ^> 32h */ - &&get32_123x_3210, /* 24s -> 32h */ - &&get32_123x_B210, /* 24s ^> 32h */ - &&get32_1234_1234, /* 32h -> 32h */ - &&get32_1234_9234, /* 32h ^> 32h */ - &&get32_1234_4321, /* 32s -> 32h */ - &&get32_1234_C321, /* 32s ^> 32h */ -}; -#endif - -#ifdef GET32_END -while (0) { -get32_xxx1_1000: sample = (u_int32_t)as_u8(src) << 24; goto GET32_END; -get32_xxx1_9000: sample = (u_int32_t)(as_u8(src) ^ 0x80) << 24; goto GET32_END; -get32_xx12_1200: sample = (u_int32_t)as_u16(src) << 16; goto GET32_END; -get32_xx12_9200: sample = (u_int32_t)(as_u16(src) ^ 0x8000) << 16; goto GET32_END; -get32_xx12_2100: sample = (u_int32_t)swab16(as_u16(src)) << 16; goto GET32_END; -get32_xx12_A100: sample = (u_int32_t)swab16(as_u16(src) ^ 0x80) << 16; goto GET32_END; -get32_x123_1230: sample = as_u32(src) << 8; goto GET32_END; -get32_x123_9230: sample = (as_u32(src) << 8) ^ 0x80000000; goto GET32_END; -get32_123x_3210: sample = swab32(as_u32(src) >> 8); goto GET32_END; -get32_123x_B210: sample = swab32((as_u32(src) >> 8) ^ 0x80); goto GET32_END; -get32_1234_1234: sample = as_u32(src); goto GET32_END; -get32_1234_9234: sample = as_u32(src) ^ 0x80000000; goto GET32_END; -get32_1234_4321: sample = swab32(as_u32(src)); goto GET32_END; -get32_1234_C321: sample = swab32(as_u32(src) ^ 0x80); goto GET32_END; -} -#endif -#endif - -#ifdef PUT_U32_LABELS -/* dst_wid dst_endswap unsigned */ -static void *put_u32_labels[4 * 2 * 2] = { - &&put_u32_1234_xxx9, /* u32h -> s8h */ - &&put_u32_1234_xxx1, /* u32h -> u8h */ - &&put_u32_1234_xxx9, /* u32h -> s8s */ - &&put_u32_1234_xxx1, /* u32h -> u8s */ - &&put_u32_1234_xx92, /* u32h -> s16h */ - &&put_u32_1234_xx12, /* u32h -> u16h */ - &&put_u32_1234_xx29, /* u32h -> s16s */ - &&put_u32_1234_xx21, /* u32h -> u16s */ - &&put_u32_1234_x923, /* u32h -> s24h */ - &&put_u32_1234_x123, /* u32h -> u24h */ - &&put_u32_1234_329x, /* u32h -> s24s */ - &&put_u32_1234_321x, /* u32h -> u24s */ - &&put_u32_1234_9234, /* u32h -> s32h */ - &&put_u32_1234_1234, /* u32h -> u32h */ - &&put_u32_1234_4329, /* u32h -> s32s */ - &&put_u32_1234_4321, /* u32h -> u32s */ -}; -#endif - -#ifdef PUT_U32_END -while (0) { -put_u32_1234_xxx1: as_u8(dst) = sample >> 24; goto PUT_U32_END; -put_u32_1234_xxx9: as_u8(dst) = (sample >> 24) ^ 0x80; goto PUT_U32_END; -put_u32_1234_xx12: as_u16(dst) = sample >> 16; goto PUT_U32_END; -put_u32_1234_xx92: as_u16(dst) = (sample >> 16) ^ 0x8000; goto PUT_U32_END; -put_u32_1234_xx21: as_u16(dst) = swab16(sample >> 16); goto PUT_U32_END; -put_u32_1234_xx29: as_u16(dst) = swab16(sample >> 16) ^ 0x80; goto PUT_U32_END; -put_u32_1234_x123: as_u32(dst) = sample >> 8; goto PUT_U32_END; -put_u32_1234_x923: as_u32(dst) = (sample >> 8) ^ 0x800000; goto PUT_U32_END; -put_u32_1234_321x: as_u32(dst) = swab32(sample) << 8; goto PUT_U32_END; -put_u32_1234_329x: as_u32(dst) = (swab32(sample) ^ 0x80) << 8; goto PUT_U32_END; -put_u32_1234_1234: as_u32(dst) = sample; goto PUT_U32_END; -put_u32_1234_9234: as_u32(dst) = sample ^ 0x80000000; goto PUT_U32_END; -put_u32_1234_4321: as_u32(dst) = swab32(sample); goto PUT_U32_END; -put_u32_1234_4329: as_u32(dst) = swab32(sample) ^ 0x80; goto PUT_U32_END; -} -#endif - -#ifdef GET_U_LABELS -/* width endswap unsigned*/ -static void *get_u_labels[4 * 2 * 2] = { - &&get_u_s8, /* s8 -> u8 */ - &&get_u_u8, /* u8 -> u8 */ - &&get_u_s8, /* s8 -> u8 */ - &&get_u_u8, /* u8 -> u8 */ - &&get_u_s16h, /* s16h -> u16h */ - &&get_u_u16h, /* u16h -> u16h */ - &&get_u_s16s, /* s16s -> u16h */ - &&get_u_u16s, /* u16s -> u16h */ - &&get_u_s24h, /* s24h -> u32h */ - &&get_u_u24h, /* u24h -> u32h */ - &&get_u_s24s, /* s24s -> u32h */ - &&get_u_u24s, /* u24s -> u32h */ - &&get_u_s32h, /* s32h -> u32h */ - &&get_u_u32h, /* u32h -> u32h */ - &&get_u_s32s, /* s32s -> u32h */ - &&get_u_u32s, /* u32s -> u32h */ -}; -#endif - -#ifdef GET_U_END -while (0) { -get_u_s8: sample = as_u8(src) ^ 0x80; goto GET_U_END; -get_u_u8: sample = as_u8(src); goto GET_U_END; -get_u_s16h: sample = as_u16(src) ^ 0x8000; goto GET_U_END; -get_u_u16h: sample = as_u16(src); goto GET_U_END; -get_u_s16s: sample = swab16(as_u16(src) ^ 0x80); goto GET_U_END; -get_u_u16s: sample = swab16(as_u16(src)); goto GET_U_END; -get_u_s24h: sample = (as_u32(src) ^ 0x800000); goto GET_U_END; -get_u_u24h: sample = as_u32(src); goto GET_U_END; -get_u_s24s: sample = swab32(as_u32(src) ^ 0x800000); goto GET_U_END; -get_u_u24s: sample = swab32(as_u32(src)); goto GET_U_END; -get_u_s32h: sample = as_u32(src) ^ 0x80000000; goto GET_U_END; -get_u_u32h: sample = as_u32(src); goto GET_U_END; -get_u_s32s: sample = swab32(as_u32(src) ^ 0x80); goto GET_U_END; -get_u_u32s: sample = swab32(as_u32(src)); goto GET_U_END; -} -#endif - -#if 0 -#ifdef PUT_LABELS -/* width endswap unsigned */ -static void *put_labels[4 * 2 * 2] = { - &&put_s8, /* s8 -> s8 */ - &&put_u8, /* u8 -> s8 */ - &&put_s8, /* s8 -> s8 */ - &&put_u8, /* u8 -> s8 */ - &&put_s16h, /* s16h -> s16h */ - &&put_u16h, /* u16h -> s16h */ - &&put_s16s, /* s16s -> s16h */ - &&put_u16s, /* u16s -> s16h */ - &&put_s24h, /* s24h -> s32h */ - &&put_u24h, /* u24h -> s32h */ - &&put_s24s, /* s24s -> s32h */ - &&put_u24s, /* u24s -> s32h */ - &&put_s32h, /* s32h -> s32h */ - &&put_u32h, /* u32h -> s32h */ - &&put_s32s, /* s32s -> s32h */ - &&put_u32s, /* u32s -> s32h */ -}; -#endif - -#ifdef PUT_END -put_s8: as_s8(dst) = sample; goto PUT_END; -put_u8: as_u8(dst) = sample ^ 0x80; goto PUT_END; -put_s16h: as_s16(dst) = sample; goto PUT_END; -put_u16h: as_u16(dst) = sample ^ 0x8000; goto PUT_END; -put_s16s: as_s16(dst) = swab16(sample); goto PUT_END; -put_u16s: as_u16(dst) = swab16(sample ^ 0x80); goto PUT_END; -put_s24h: as_s24(dst) = sample & 0xffffff; goto PUT_END; -put_u24h: as_u24(dst) = sample ^ 0x80000000; goto PUT_END; -put_s24s: as_s24(dst) = swab32(sample & 0xffffff); goto PUT_END; -put_u24s: as_u24(dst) = swab32(sample ^ 0x80); goto PUT_END; -put_s32h: as_s32(dst) = sample; goto PUT_END; -put_u32h: as_u32(dst) = sample ^ 0x80000000; goto PUT_END; -put_s32s: as_s32(dst) = swab32(sample); goto PUT_END; -put_u32s: as_u32(dst) = swab32(sample ^ 0x80); goto PUT_END; -#endif -#endif - #undef as_u8 #undef as_u16 #undef as_u32 diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 4854cef6fb4..18d8a0f4e81 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -20,6 +20,9 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> @@ -47,7 +50,6 @@ struct rate_priv { unsigned int pitch; unsigned int pos; rate_f func; - int get, put; snd_pcm_sframes_t old_src_frames, old_dst_frames; struct rate_channel channels[0]; }; @@ -71,21 +73,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, unsigned int pos = 0; signed int val; signed short S1, S2; - char *src, *dst; + signed short *src, *dst; unsigned int channel; int src_step, dst_step; int src_frames1, dst_frames1; struct rate_priv *data = (struct rate_priv *)plugin->extra_data; struct rate_channel *rchannels = data->channels; - -#define GET_S16_LABELS -#define PUT_S16_LABELS -#include "plugin_ops.h" -#undef GET_S16_LABELS -#undef PUT_S16_LABELS - void *get = get_s16_labels[data->get]; - void *put = put_s16_labels[data->put]; - signed short sample = 0; for (channel = 0; channel < plugin->src_format.channels; channel++) { pos = data->pos; @@ -98,10 +91,12 @@ static void resample_expand(struct snd_pcm_plugin *plugin, continue; } dst_channels[channel].enabled = 1; - src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; - dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; - src_step = src_channels[channel].area.step / 8; - dst_step = dst_channels[channel].area.step / 8; + src = (signed short *)src_channels[channel].area.addr + + src_channels[channel].area.first / 8 / 2; + dst = (signed short *)dst_channels[channel].area.addr + + dst_channels[channel].area.first / 8 / 2; + src_step = src_channels[channel].area.step / 8 / 2; + dst_step = dst_channels[channel].area.step / 8 / 2; src_frames1 = src_frames; dst_frames1 = dst_frames; while (dst_frames1-- > 0) { @@ -109,12 +104,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, pos &= R_MASK; S1 = S2; if (src_frames1-- > 0) { - goto *get; -#define GET_S16_END after_get -#include "plugin_ops.h" -#undef GET_S16_END - after_get: - S2 = sample; + S2 = *src; src += src_step; } } @@ -123,12 +113,7 @@ static void resample_expand(struct snd_pcm_plugin *plugin, val = -32768; else if (val > 32767) val = 32767; - sample = val; - goto *put; -#define PUT_S16_END after_put -#include "plugin_ops.h" -#undef PUT_S16_END - after_put: + *dst = val; dst += dst_step; pos += data->pitch; } @@ -147,21 +132,12 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, unsigned int pos = 0; signed int val; signed short S1, S2; - char *src, *dst; + signed short *src, *dst; unsigned int channel; int src_step, dst_step; int src_frames1, dst_frames1; struct rate_priv *data = (struct rate_priv *)plugin->extra_data; struct rate_channel *rchannels = data->channels; - -#define GET_S16_LABELS -#define PUT_S16_LABELS -#include "plugin_ops.h" -#undef GET_S16_LABELS -#undef PUT_S16_LABELS - void *get = get_s16_labels[data->get]; - void *put = put_s16_labels[data->put]; - signed short sample = 0; for (channel = 0; channel < plugin->src_format.channels; ++channel) { pos = data->pos; @@ -174,21 +150,18 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, continue; } dst_channels[channel].enabled = 1; - src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8; - dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8; - src_step = src_channels[channel].area.step / 8; - dst_step = dst_channels[channel].area.step / 8; + src = (signed short *)src_channels[channel].area.addr + + src_channels[channel].area.first / 8 / 2; + dst = (signed short *)dst_channels[channel].area.addr + + dst_channels[channel].area.first / 8 / 2; + src_step = src_channels[channel].area.step / 8 / 2; + dst_step = dst_channels[channel].area.step / 8 / 2; src_frames1 = src_frames; dst_frames1 = dst_frames; while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { - goto *get; -#define GET_S16_END after_get -#include "plugin_ops.h" -#undef GET_S16_END - after_get: - S2 = sample; + S1 = *src; src += src_step; } if (pos & ~R_MASK) { @@ -198,12 +171,7 @@ static void resample_shrink(struct snd_pcm_plugin *plugin, val = -32768; else if (val > 32767) val = 32767; - sample = val; - goto *put; -#define PUT_S16_END after_put -#include "plugin_ops.h" -#undef PUT_S16_END - after_put: + *dst = val; dst += dst_step; dst_frames1--; } @@ -343,8 +311,8 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, snd_assert(src_format->channels == dst_format->channels, return -ENXIO); snd_assert(src_format->channels > 0, return -ENXIO); - snd_assert(snd_pcm_format_linear(src_format->format) != 0, return -ENXIO); - snd_assert(snd_pcm_format_linear(dst_format->format) != 0, return -ENXIO); + snd_assert(src_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); + snd_assert(dst_format->format == SNDRV_PCM_FORMAT_S16, return -ENXIO); snd_assert(src_format->rate != dst_format->rate, return -ENXIO); err = snd_pcm_plugin_build(plug, "rate conversion", @@ -355,11 +323,6 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, if (err < 0) return err; data = (struct rate_priv *)plugin->extra_data; - data->get = getput_index(src_format->format); - snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); - data->put = getput_index(dst_format->format); - snd_assert(data->put >= 0 && data->put < 4*2*2, return -EINVAL); - if (src_format->rate < dst_format->rate) { data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; data->func = resample_expand; @@ -377,3 +340,5 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index 726c5caa3fd..46917dc0196 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c @@ -1,5 +1,5 @@ /* - * Attenuated route Plug-In + * Route Plug-In * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * * @@ -20,502 +20,93 @@ */ #include <sound/driver.h> + +#ifdef CONFIG_SND_PCM_OSS_PLUGINS + #include <linux/slab.h> #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> #include "pcm_plugin.h" -/* The best possible hack to support missing optimization in gcc 2.7.2.3 */ -#if ROUTE_PLUGIN_RESOLUTION & (ROUTE_PLUGIN_RESOLUTION - 1) != 0 -#define div(a) a /= ROUTE_PLUGIN_RESOLUTION -#elif ROUTE_PLUGIN_RESOLUTION == 16 -#define div(a) a >>= 4 -#else -#error "Add some code here" -#endif - -struct ttable_dst; - -typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *dst_channel, - struct ttable_dst *ttable, snd_pcm_uframes_t frames); - -struct ttable_src { - int channel; - int as_int; -}; - -struct ttable_dst { - int att; /* Attenuated */ - unsigned int nsrcs; - struct ttable_src *srcs; - route_channel_f func; -}; - -struct route_priv { - enum {R_UINT32=0, R_UINT64=1} sum_type; - int get, put; - int conv; - int src_sample_size; - struct ttable_dst ttable[0]; -}; - -union sum { - u_int32_t as_uint32; - u_int64_t as_uint64; -}; - - -static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *dst_channel, - struct ttable_dst *ttable, - snd_pcm_uframes_t frames) -{ - if (dst_channel->wanted) - snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format); - dst_channel->enabled = 0; -} - -static void route_to_channel_from_one(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *dst_channel, - struct ttable_dst *ttable, - snd_pcm_uframes_t frames) +static void zero_areas(struct snd_pcm_plugin_channel *dvp, int ndsts, + snd_pcm_uframes_t frames, int format) { -#define CONV_LABELS -#include "plugin_ops.h" -#undef CONV_LABELS - struct route_priv *data = (struct route_priv *)plugin->extra_data; - void *conv; - const struct snd_pcm_plugin_channel *src_channel = NULL; - unsigned int srcidx; - char *src, *dst; - int src_step, dst_step; - for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) { - src_channel = &src_channels[ttable->srcs[srcidx].channel]; - if (src_channel->area.addr != NULL) - break; - } - if (srcidx == ttable->nsrcs) { - route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); - return; - } - - dst_channel->enabled = 1; - conv = conv_labels[data->conv]; - src = src_channel->area.addr + src_channel->area.first / 8; - src_step = src_channel->area.step / 8; - dst = dst_channel->area.addr + dst_channel->area.first / 8; - dst_step = dst_channel->area.step / 8; - while (frames-- > 0) { - goto *conv; -#define CONV_END after -#include "plugin_ops.h" -#undef CONV_END - after: - src += src_step; - dst += dst_step; + int dst = 0; + for (; dst < ndsts; ++dst) { + if (dvp->wanted) + snd_pcm_area_silence(&dvp->area, 0, frames, format); + dvp->enabled = 0; + dvp++; } } -static void route_to_channel(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, +static inline void copy_area(const struct snd_pcm_plugin_channel *src_channel, struct snd_pcm_plugin_channel *dst_channel, - struct ttable_dst *ttable, snd_pcm_uframes_t frames) + snd_pcm_uframes_t frames, int format) { -#define GET_U_LABELS -#define PUT_U32_LABELS -#include "plugin_ops.h" -#undef GET_U_LABELS -#undef PUT_U32_LABELS - static void *zero_labels[2] = { &&zero_int32, &&zero_int64 }; - /* sum_type att */ - static void *add_labels[2 * 2] = { &&add_int32_noatt, &&add_int32_att, - &&add_int64_noatt, &&add_int64_att, - }; - /* sum_type att shift */ - static void *norm_labels[2 * 2 * 4] = { NULL, - &&norm_int32_8_noatt, - &&norm_int32_16_noatt, - &&norm_int32_24_noatt, - NULL, - &&norm_int32_8_att, - &&norm_int32_16_att, - &&norm_int32_24_att, - &&norm_int64_0_noatt, - &&norm_int64_8_noatt, - &&norm_int64_16_noatt, - &&norm_int64_24_noatt, - &&norm_int64_0_att, - &&norm_int64_8_att, - &&norm_int64_16_att, - &&norm_int64_24_att, - }; - struct route_priv *data = (struct route_priv *)plugin->extra_data; - void *zero, *get, *add, *norm, *put_u32; - int nsrcs = ttable->nsrcs; - char *dst; - int dst_step; - char *srcs[nsrcs]; - int src_steps[nsrcs]; - struct ttable_src src_tt[nsrcs]; - u_int32_t sample = 0; - int srcidx, srcidx1 = 0; - for (srcidx = 0; srcidx < nsrcs; ++srcidx) { - const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel]; - if (!src_channel->enabled) - continue; - srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8; - src_steps[srcidx1] = src_channel->area.step / 8; - src_tt[srcidx1] = ttable->srcs[srcidx]; - srcidx1++; - } - nsrcs = srcidx1; - if (nsrcs == 0) { - route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames); - return; - } else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) { - route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames); - return; - } - dst_channel->enabled = 1; - zero = zero_labels[data->sum_type]; - get = get_u_labels[data->get]; - add = add_labels[data->sum_type * 2 + ttable->att]; - norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size]; - put_u32 = put_u32_labels[data->put]; - dst = dst_channel->area.addr + dst_channel->area.first / 8; - dst_step = dst_channel->area.step / 8; - - while (frames-- > 0) { - struct ttable_src *ttp = src_tt; - union sum sum; - - /* Zero sum */ - goto *zero; - zero_int32: - sum.as_uint32 = 0; - goto zero_end; - zero_int64: - sum.as_uint64 = 0; - goto zero_end; - zero_end: - for (srcidx = 0; srcidx < nsrcs; ++srcidx) { - char *src = srcs[srcidx]; - - /* Get sample */ - goto *get; -#define GET_U_END after_get -#include "plugin_ops.h" -#undef GET_U_END - after_get: - - /* Sum */ - goto *add; - add_int32_att: - sum.as_uint32 += sample * ttp->as_int; - goto after_sum; - add_int32_noatt: - if (ttp->as_int) - sum.as_uint32 += sample; - goto after_sum; - add_int64_att: - sum.as_uint64 += (u_int64_t) sample * ttp->as_int; - goto after_sum; - add_int64_noatt: - if (ttp->as_int) - sum.as_uint64 += sample; - goto after_sum; - after_sum: - srcs[srcidx] += src_steps[srcidx]; - ttp++; - } - - /* Normalization */ - goto *norm; - norm_int32_8_att: - sum.as_uint64 = sum.as_uint32; - norm_int64_8_att: - sum.as_uint64 <<= 8; - norm_int64_0_att: - div(sum.as_uint64); - goto norm_int; - - norm_int32_16_att: - sum.as_uint64 = sum.as_uint32; - norm_int64_16_att: - sum.as_uint64 <<= 16; - div(sum.as_uint64); - goto norm_int; - - norm_int32_24_att: - sum.as_uint64 = sum.as_uint32; - norm_int64_24_att: - sum.as_uint64 <<= 24; - div(sum.as_uint64); - goto norm_int; - - norm_int32_8_noatt: - sum.as_uint64 = sum.as_uint32; - norm_int64_8_noatt: - sum.as_uint64 <<= 8; - goto norm_int; - - norm_int32_16_noatt: - sum.as_uint64 = sum.as_uint32; - norm_int64_16_noatt: - sum.as_uint64 <<= 16; - goto norm_int; - - norm_int32_24_noatt: - sum.as_uint64 = sum.as_uint32; - norm_int64_24_noatt: - sum.as_uint64 <<= 24; - goto norm_int; - - norm_int64_0_noatt: - norm_int: - if (sum.as_uint64 > (u_int32_t)0xffffffff) - sample = (u_int32_t)0xffffffff; - else - sample = sum.as_uint64; - goto after_norm; - - after_norm: - - /* Put sample */ - goto *put_u32; -#define PUT_U32_END after_put_u32 -#include "plugin_ops.h" -#undef PUT_U32_END - after_put_u32: - - dst += dst_step; - } -} - -static int route_src_channels_mask(struct snd_pcm_plugin *plugin, - unsigned long *dst_vmask, - unsigned long **src_vmask) -{ - struct route_priv *data = (struct route_priv *)plugin->extra_data; - int schannels = plugin->src_format.channels; - int dchannels = plugin->dst_format.channels; - unsigned long *vmask = plugin->src_vmask; - int channel; - struct ttable_dst *dp = data->ttable; - bitmap_zero(vmask, schannels); - for (channel = 0; channel < dchannels; channel++, dp++) { - unsigned int src; - struct ttable_src *sp; - if (!test_bit(channel, dst_vmask)) - continue; - sp = dp->srcs; - for (src = 0; src < dp->nsrcs; src++, sp++) - set_bit(sp->channel, vmask); - } - *src_vmask = vmask; - return 0; -} - -static int route_dst_channels_mask(struct snd_pcm_plugin *plugin, - unsigned long *src_vmask, - unsigned long **dst_vmask) -{ - struct route_priv *data = (struct route_priv *)plugin->extra_data; - int dchannels = plugin->dst_format.channels; - unsigned long *vmask = plugin->dst_vmask; - int channel; - struct ttable_dst *dp = data->ttable; - bitmap_zero(vmask, dchannels); - for (channel = 0; channel < dchannels; channel++, dp++) { - unsigned int src; - struct ttable_src *sp; - sp = dp->srcs; - for (src = 0; src < dp->nsrcs; src++, sp++) { - if (test_bit(sp->channel, src_vmask)) { - set_bit(channel, vmask); - break; - } - } - } - *dst_vmask = vmask; - return 0; -} - -static void route_free(struct snd_pcm_plugin *plugin) -{ - struct route_priv *data = (struct route_priv *)plugin->extra_data; - unsigned int dst_channel; - for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { - kfree(data->ttable[dst_channel].srcs); - } -} - -static int route_load_ttable(struct snd_pcm_plugin *plugin, - const int *src_ttable) -{ - struct route_priv *data; - unsigned int src_channel, dst_channel; - const int *sptr; - struct ttable_dst *dptr; - if (src_ttable == NULL) - return 0; - data = (struct route_priv *)plugin->extra_data; - dptr = data->ttable; - sptr = src_ttable; - plugin->private_free = route_free; - for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) { - int t = 0; - int att = 0; - int nsrcs = 0; - struct ttable_src srcs[plugin->src_format.channels]; - for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) { - snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO); - if (*sptr != 0) { - srcs[nsrcs].channel = src_channel; - srcs[nsrcs].as_int = *sptr; - if (*sptr != FULL) - att = 1; - t += *sptr; - nsrcs++; - } - sptr++; - } - dptr->att = att; - dptr->nsrcs = nsrcs; - if (nsrcs == 0) - dptr->func = route_to_channel_from_zero; - else if (nsrcs == 1 && !att) - dptr->func = route_to_channel_from_one; - else - dptr->func = route_to_channel; - if (nsrcs > 0) { - int srcidx; - dptr->srcs = kcalloc(nsrcs, sizeof(*srcs), GFP_KERNEL); - for(srcidx = 0; srcidx < nsrcs; srcidx++) - dptr->srcs[srcidx] = srcs[srcidx]; - } else - dptr->srcs = NULL; - dptr++; - } - return 0; + snd_pcm_area_copy(&src_channel->area, 0, &dst_channel->area, 0, frames, format); } static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, - const struct snd_pcm_plugin_channel *src_channels, - struct snd_pcm_plugin_channel *dst_channels, - snd_pcm_uframes_t frames) + const struct snd_pcm_plugin_channel *src_channels, + struct snd_pcm_plugin_channel *dst_channels, + snd_pcm_uframes_t frames) { - struct route_priv *data; - int src_nchannels, dst_nchannels; - int dst_channel; - struct ttable_dst *ttp; + int nsrcs, ndsts, dst; struct snd_pcm_plugin_channel *dvp; + int format; snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); if (frames == 0) return 0; - data = (struct route_priv *)plugin->extra_data; - src_nchannels = plugin->src_format.channels; - dst_nchannels = plugin->dst_format.channels; + nsrcs = plugin->src_format.channels; + ndsts = plugin->dst_format.channels; -#ifdef CONFIG_SND_DEBUG - { - int src_channel; - for (src_channel = 0; src_channel < src_nchannels; ++src_channel) { - snd_assert(src_channels[src_channel].area.first % 8 == 0 || - src_channels[src_channel].area.step % 8 == 0, - return -ENXIO); - } - for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { - snd_assert(dst_channels[dst_channel].area.first % 8 == 0 || - dst_channels[dst_channel].area.step % 8 == 0, - return -ENXIO); + format = plugin->dst_format.format; + dvp = dst_channels; + if (nsrcs <= 1) { + /* expand to all channels */ + for (dst = 0; dst < ndsts; ++dst) { + copy_area(src_channels, dvp, frames, format); + dvp++; } + return frames; } -#endif - ttp = data->ttable; - dvp = dst_channels; - for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) { - ttp->func(plugin, src_channels, dvp, ttp, frames); + for (dst = 0; dst < ndsts && dst < nsrcs; ++dst) { + copy_area(src_channels, dvp, frames, format); dvp++; - ttp++; + src_channels++; } + if (dst < ndsts) + zero_areas(dvp, ndsts - dst, frames, format); return frames; } -int getput_index(int format) -{ - int sign, width, endian; - sign = !snd_pcm_format_signed(format); - width = snd_pcm_format_width(format) / 8 - 1; - if (width < 0 || width > 3) { - snd_printk(KERN_ERR "snd-pcm-oss: invalid format %d\n", format); - width = 0; - } -#ifdef SNDRV_LITTLE_ENDIAN - endian = snd_pcm_format_big_endian(format); -#else - endian = snd_pcm_format_little_endian(format); -#endif - if (endian < 0) - endian = 0; - return width * 4 + endian * 2 + sign; -} - int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format *src_format, struct snd_pcm_plugin_format *dst_format, - int *ttable, struct snd_pcm_plugin **r_plugin) { - struct route_priv *data; struct snd_pcm_plugin *plugin; int err; snd_assert(r_plugin != NULL, return -ENXIO); *r_plugin = NULL; snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(snd_pcm_format_linear(src_format->format) != 0 && - snd_pcm_format_linear(dst_format->format) != 0, - return -ENXIO); + snd_assert(src_format->format == dst_format->format, return -ENXIO); - err = snd_pcm_plugin_build(plug, "attenuated route conversion", - src_format, dst_format, - sizeof(struct route_priv) + - sizeof(data->ttable[0]) * dst_format->channels, - &plugin); + err = snd_pcm_plugin_build(plug, "route conversion", + src_format, dst_format, 0, &plugin); if (err < 0) return err; - data = (struct route_priv *)plugin->extra_data; - - data->get = getput_index(src_format->format); - snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); - data->put = getput_index(dst_format->format); - snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL); - data->conv = conv_index(src_format->format, dst_format->format); - - if (snd_pcm_format_width(src_format->format) == 32) - data->sum_type = R_UINT64; - else - data->sum_type = R_UINT32; - data->src_sample_size = snd_pcm_format_width(src_format->format) / 8; - - if ((err = route_load_ttable(plugin, ttable)) < 0) { - snd_pcm_plugin_free(plugin); - return err; - } plugin->transfer = route_transfer; - plugin->src_channels_mask = route_src_channels_mask; - plugin->dst_channels_mask = route_dst_channels_mask; *r_plugin = plugin; return 0; } + +#endif diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 28ca61eb0b0..3da6a38c2d0 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/pcm.h> @@ -35,7 +36,7 @@ MODULE_LICENSE("GPL"); static LIST_HEAD(snd_pcm_devices); static LIST_HEAD(snd_pcm_notify_list); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static int snd_pcm_free(struct snd_pcm *pcm); static int snd_pcm_dev_free(struct snd_device *device); @@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_PCM_DEVICES) { if (snd_pcm_search(card, device)) @@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } if (device == SNDRV_PCM_DEVICES) device = -1; - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (put_user(device, (int __user *)arg)) return -EFAULT; return 0; @@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, return -EINVAL; if (get_user(subdevice, &info->subdevice)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); pcm = snd_pcm_search(card, device); if (pcm == NULL) { err = -ENXIO; @@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } err = snd_pcm_info_user(substream, info); _error: - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: @@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card, } return -ENOIOCTLCMD; } + +#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS) + #define STATE(v) [SNDRV_PCM_STATE_##v] = #v #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v #define READY(v) [SNDRV_PCM_READY_##v] = #v @@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format) return snd_pcm_format_names[format]; } -#ifdef CONFIG_PROC_FS static char *snd_pcm_stream_names[] = { STREAM(PLAYBACK), STREAM(CAPTURE), @@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state) #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) #include <linux/soundcard.h> + static const char *snd_pcm_oss_format_name(int format) { switch (format) { @@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) struct snd_pcm_substream *substream, *prev; #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) - init_MUTEX(&pstr->oss.setup_mutex); + mutex_init(&pstr->oss.setup_mutex); #endif pstr->stream = stream; pstr->pcm = pcm; @@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, snd_pcm_free(pcm); return err; } - init_MUTEX(&pcm->open_mutex); + mutex_init(&pcm->open_mutex); init_waitqueue_head(&pcm->open_wait); if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { snd_pcm_free(pcm); @@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device) struct snd_pcm *pcm = device->device_data; snd_assert(pcm != NULL && device != NULL, return -ENXIO); - down(®ister_mutex); + mutex_lock(®ister_mutex); if (snd_pcm_search(pcm->card, pcm->device)) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } list_add_tail(&pcm->list, &snd_pcm_devices); @@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device) pcm, str)) < 0) { list_del(&pcm->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) @@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_register(pcm); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) struct snd_pcm_substream *substream; int cidx; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del_init(&pcm->list); for (cidx = 0; cidx < 2; cidx++) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) @@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_disconnect(pcm); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) struct snd_pcm *pcm = device->device_data; snd_assert(pcm != NULL, return -ENXIO); - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del(&pcm->list); for (cidx = 0; cidx < 2; cidx++) { devtype = -1; @@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) notify = list_entry(list, struct snd_pcm_notify, list); notify->n_unregister(pcm); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return snd_pcm_free(pcm); } @@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) struct list_head *p; snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); - down(®ister_mutex); + mutex_lock(®ister_mutex); if (nfree) { list_del(¬ify->list); list_for_each(p, &snd_pcm_devices) @@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) list_for_each(p, &snd_pcm_devices) notify->n_register(list_entry(p, struct snd_pcm, list)); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, struct list_head *p; struct snd_pcm *pcm; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_for_each(p, &snd_pcm_devices) { pcm = list_entry(p, struct snd_pcm, list); snd_iprintf(buffer, "%02i-%02i: %s : %s", @@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); snd_iprintf(buffer, "\n"); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); } static struct snd_info_entry *snd_pcm_proc_entry = NULL; @@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream); EXPORT_SYMBOL(snd_pcm_notify); EXPORT_SYMBOL(snd_pcm_open_substream); EXPORT_SYMBOL(snd_pcm_release_substream); -EXPORT_SYMBOL(snd_pcm_format_name); /* pcm_native.c */ EXPORT_SYMBOL(snd_pcm_link_rwlock); #ifdef CONFIG_PM diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f3d5de7b55a..01f150f0990 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2112,7 +2112,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) } init_waitqueue_entry(&wait, current); add_wait_queue(&pcm->open_wait, &wait); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); while (1) { err = snd_pcm_open_file(file, pcm, stream, &pcm_file); if (err >= 0) @@ -2125,16 +2125,16 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) } else break; set_current_state(TASK_INTERRUPTIBLE); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); schedule(); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&pcm->open_wait, &wait); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); if (err < 0) goto __error; return err; @@ -2160,9 +2160,9 @@ static int snd_pcm_release(struct inode *inode, struct file *file) pcm = substream->pcm; snd_pcm_drop(substream); fasync_helper(-1, file, 0, &substream->runtime->fasync); - down(&pcm->open_mutex); + mutex_lock(&pcm->open_mutex); snd_pcm_release_file(pcm_file); - up(&pcm->open_mutex); + mutex_unlock(&pcm->open_mutex); wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); @@ -2539,6 +2539,14 @@ static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream, return snd_pcm_drain(substream); case SNDRV_PCM_IOCTL_DROP: return snd_pcm_drop(substream); + case SNDRV_PCM_IOCTL_PAUSE: + { + int res; + snd_pcm_stream_lock_irq(substream); + res = snd_pcm_pause(substream, (int)(unsigned long)arg); + snd_pcm_stream_unlock_irq(substream); + return res; + } } snd_printd("unknown ioctl = 0x%x\n", cmd); return -ENOTTY; @@ -2619,14 +2627,6 @@ static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream, __put_user(result, _frames); return result < 0 ? result : 0; } - case SNDRV_PCM_IOCTL_PAUSE: - { - int res; - snd_pcm_stream_lock_irq(substream); - res = snd_pcm_pause(substream, (int)(unsigned long)arg); - snd_pcm_stream_unlock_irq(substream); - return res; - } } return snd_pcm_common_ioctl1(substream, cmd, arg); } diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index d4d124e2192..6b7a3677429 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/time.h> #include <linux/wait.h> +#include <linux/mutex.h> #include <linux/moduleparam.h> #include <linux/delay.h> #include <linux/wait.h> @@ -57,7 +58,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device); static int snd_rawmidi_dev_unregister(struct snd_device *device); static LIST_HEAD(snd_rawmidi_devices); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) { @@ -237,9 +238,9 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, if (rfile) rfile->input = rfile->output = NULL; - down(®ister_mutex); + mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, device); - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (rmidi == NULL) { err = -ENODEV; goto __error1; @@ -249,7 +250,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, goto __error1; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (mode & SNDRV_RAWMIDI_LFLG_INPUT) { if (!(rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT)) { err = -ENXIO; @@ -359,7 +360,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, soutput = NULL; } if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); if (rfile) { rfile->rmidi = rmidi; rfile->input = sinput; @@ -374,7 +375,7 @@ int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, snd_rawmidi_runtime_free(soutput); module_put(rmidi->card->module); if (!(mode & SNDRV_RAWMIDI_LFLG_NOOPENLOCK)) - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); __error1: return err; } @@ -422,7 +423,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } init_waitqueue_entry(&wait, current); add_wait_queue(&rmidi->open_wait, &wait); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); while (1) { subdevice = -1; down_read(&card->controls_rwsem); @@ -446,9 +447,9 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); schedule(); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; @@ -467,7 +468,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) snd_card_file_remove(card, file); kfree(rawmidi_file); } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); return err; } @@ -480,7 +481,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) snd_assert(rfile != NULL, return -ENXIO); snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); rmidi = rfile->rmidi; - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (rfile->input != NULL) { substream = rfile->input; rfile->input = NULL; @@ -514,7 +515,7 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) } rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substream_opened--; } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); module_put(rmidi->card->module); return 0; } @@ -576,9 +577,9 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info struct snd_rawmidi_substream *substream; struct list_head *list; - down(®ister_mutex); + mutex_lock(®ister_mutex); rmidi = snd_rawmidi_search(card, info->device); - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (!rmidi) return -ENXIO; if (info->stream < 0 || info->stream > 1) @@ -818,7 +819,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)argp)) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); device = device < 0 ? 0 : device + 1; while (device < SNDRV_RAWMIDI_DEVICES) { if (snd_rawmidi_search(card, device)) @@ -827,7 +828,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, } if (device == SNDRV_RAWMIDI_DEVICES) device = -1; - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (put_user(device, (int __user *)argp)) return -EFAULT; return 0; @@ -1314,7 +1315,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, rmidi = entry->private_data; snd_iprintf(buffer, "%s\n\n", rmidi->name); - down(&rmidi->open_mutex); + mutex_lock(&rmidi->open_mutex); if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) { list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) { substream = list_entry(list, struct snd_rawmidi_substream, list); @@ -1355,7 +1356,7 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry, } } } - up(&rmidi->open_mutex); + mutex_unlock(&rmidi->open_mutex); } /* @@ -1436,7 +1437,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, } rmidi->card = card; rmidi->device = device; - init_MUTEX(&rmidi->open_mutex); + mutex_init(&rmidi->open_mutex); init_waitqueue_head(&rmidi->open_wait); if (id != NULL) strlcpy(rmidi->id, id, sizeof(rmidi->id)); @@ -1507,9 +1508,9 @@ static int snd_rawmidi_dev_register(struct snd_device *device) if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) return -ENOMEM; - down(®ister_mutex); + mutex_lock(®ister_mutex); if (snd_rawmidi_search(rmidi->card, rmidi->device)) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } list_add_tail(&rmidi->list, &snd_rawmidi_devices); @@ -1519,14 +1520,14 @@ static int snd_rawmidi_dev_register(struct snd_device *device) &snd_rawmidi_f_ops, rmidi, name)) < 0) { snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); list_del(&rmidi->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } if (rmidi->ops && rmidi->ops->dev_register && (err = rmidi->ops->dev_register(rmidi)) < 0) { snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); list_del(&rmidi->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } #ifdef CONFIG_SND_OSSEMUL @@ -1553,7 +1554,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) } } #endif /* CONFIG_SND_OSSEMUL */ - up(®ister_mutex); + mutex_unlock(®ister_mutex); sprintf(name, "midi%d", rmidi->device); entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); if (entry) { @@ -1583,9 +1584,9 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device) { struct snd_rawmidi *rmidi = device->device_data; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del_init(&rmidi->list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -1594,7 +1595,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) struct snd_rawmidi *rmidi = device->device_data; snd_assert(rmidi != NULL, return -ENXIO); - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del(&rmidi->list); if (rmidi->proc_entry) { snd_info_unregister(rmidi->proc_entry); @@ -1616,7 +1617,7 @@ static int snd_rawmidi_dev_unregister(struct snd_device *device) if (rmidi->ops && rmidi->ops->dev_unregister) rmidi->ops->dev_unregister(rmidi); snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); - up(®ister_mutex); + mutex_unlock(®ister_mutex); #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) if (rmidi->seq_dev) { snd_device_free(rmidi->card, rmidi->seq_dev); diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index c98f0ba1381..b9919785180 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/smp_lock.h> #include <linux/moduleparam.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/initval.h> @@ -124,7 +125,7 @@ module_exit(alsa_seq_oss_exit) * ALSA minor device interface */ -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static int odev_open(struct inode *inode, struct file *file) @@ -136,9 +137,9 @@ odev_open(struct inode *inode, struct file *file) else level = SNDRV_SEQ_OSS_MODE_SYNTH; - down(®ister_mutex); + mutex_lock(®ister_mutex); rc = snd_seq_oss_open(file, level); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return rc; } @@ -153,9 +154,9 @@ odev_release(struct inode *inode, struct file *file) snd_seq_oss_drain_write(dp); - down(®ister_mutex); + mutex_lock(®ister_mutex); snd_seq_oss_release(dp); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -224,13 +225,13 @@ register_device(void) { int rc; - down(®ister_mutex); + mutex_lock(®ister_mutex); if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0, &seq_oss_f_ops, NULL, SNDRV_SEQ_OSS_DEVNAME)) < 0) { snd_printk(KERN_ERR "can't register device seq\n"); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return rc; } if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, @@ -239,24 +240,24 @@ register_device(void) SNDRV_SEQ_OSS_DEVNAME)) < 0) { snd_printk(KERN_ERR "can't register device music\n"); snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return rc; } debug_printk(("device registered\n")); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } static void unregister_device(void) { - down(®ister_mutex); + mutex_lock(®ister_mutex); debug_printk(("device unregistered\n")); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, NULL, 0) < 0) snd_printk(KERN_ERR "error unregister device music\n"); if (snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0) < 0) snd_printk(KERN_ERR "error unregister device seq\n"); - up(®ister_mutex); + mutex_unlock(®ister_mutex); } /* @@ -270,12 +271,12 @@ static struct snd_info_entry *info_entry; static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) { - down(®ister_mutex); + mutex_lock(®ister_mutex); snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR); snd_seq_oss_system_info_read(buf); snd_seq_oss_synth_info_read(buf); snd_seq_oss_midi_info_read(buf); - up(®ister_mutex); + mutex_unlock(®ister_mutex); } diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index fd2032eae21..bb15d9ee884 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -67,7 +67,7 @@ #define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT) static DEFINE_SPINLOCK(clients_lock); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); /* * client table @@ -237,7 +237,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) client->type = NO_CLIENT; snd_use_lock_init(&client->use_lock); rwlock_init(&client->ports_lock); - init_MUTEX(&client->ports_mutex); + mutex_init(&client->ports_mutex); INIT_LIST_HEAD(&client->ports_list_head); /* find free slot in the client table */ @@ -290,7 +290,7 @@ static int seq_free_client1(struct snd_seq_client *client) static void seq_free_client(struct snd_seq_client * client) { - down(®ister_mutex); + mutex_lock(®ister_mutex); switch (client->type) { case NO_CLIENT: snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", @@ -306,7 +306,7 @@ static void seq_free_client(struct snd_seq_client * client) snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", client->number, client->type); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); snd_seq_system_client_ev_client_exit(client->number); } @@ -322,11 +322,11 @@ static int snd_seq_open(struct inode *inode, struct file *file) struct snd_seq_client *client; struct snd_seq_user_client *user; - if (down_interruptible(®ister_mutex)) + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; client = seq_create_client1(-1, SNDRV_SEQ_DEFAULT_EVENTS); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; /* failure code */ } @@ -346,14 +346,14 @@ static int snd_seq_open(struct inode *inode, struct file *file) if (user->fifo == NULL) { seq_free_client1(client); kfree(client); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } } usage_alloc(&client_usage, 1); client->type = USER_CLIENT; - up(®ister_mutex); + mutex_unlock(®ister_mutex); c = client->number; file->private_data = client; @@ -1743,7 +1743,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, if (queue == NULL) return -EINVAL; - if (down_interruptible(&queue->timer_mutex)) { + if (mutex_lock_interruptible(&queue->timer_mutex)) { queuefree(queue); return -ERESTARTSYS; } @@ -1756,7 +1756,7 @@ static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client, timer.u.alsa.id = tmr->alsa_id; timer.u.alsa.resolution = tmr->preferred_resolution; } - up(&queue->timer_mutex); + mutex_unlock(&queue->timer_mutex); queuefree(queue); if (copy_to_user(arg, &timer, sizeof(timer))) @@ -1785,7 +1785,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, q = queueptr(timer.queue); if (q == NULL) return -ENXIO; - if (down_interruptible(&q->timer_mutex)) { + if (mutex_lock_interruptible(&q->timer_mutex)) { queuefree(q); return -ERESTARTSYS; } @@ -1797,7 +1797,7 @@ static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client, tmr->preferred_resolution = timer.u.alsa.resolution; } result = snd_seq_queue_timer_open(timer.queue); - up(&q->timer_mutex); + mutex_unlock(&q->timer_mutex); queuefree(q); } else { return -EPERM; @@ -1866,8 +1866,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client, info.output_pool = cptr->pool->size; info.output_room = cptr->pool->room; info.output_free = info.output_pool; - if (cptr->pool) - info.output_free = snd_seq_unused_cells(cptr->pool); + info.output_free = snd_seq_unused_cells(cptr->pool); if (cptr->type == USER_CLIENT) { info.input_pool = cptr->data.user.fifo_pool_size; info.input_free = info.input_pool; @@ -2230,7 +2229,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS) return -EINVAL; - if (down_interruptible(®ister_mutex)) + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; if (card) { @@ -2243,7 +2242,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, /* empty write queue as default */ client = seq_create_client1(client_index, 0); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; /* failure code */ } usage_alloc(&client_usage, 1); @@ -2256,7 +2255,7 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, va_end(args); client->type = KERNEL_CLIENT; - up(®ister_mutex); + mutex_unlock(®ister_mutex); /* make others aware this new client */ snd_seq_system_client_ev_client_start(client->number); @@ -2464,7 +2463,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, { struct list_head *l; - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); snd_iprintf(buffer, " Port %3d : \"%s\" (%c%c%c%c)\n", @@ -2476,7 +2475,7 @@ static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer, snd_seq_info_dump_subscribers(buffer, &p->c_src, 1, " Connecting To: "); snd_seq_info_dump_subscribers(buffer, &p->c_dest, 0, " Connected From: "); } - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); } @@ -2550,16 +2549,16 @@ int __init snd_sequencer_device_init(void) { int err; - if (down_interruptible(®ister_mutex)) + if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, &snd_seq_f_ops, NULL, "seq")) < 0) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h index 450091ca153..5e04e20e239 100644 --- a/sound/core/seq/seq_clientmgr.h +++ b/sound/core/seq/seq_clientmgr.h @@ -58,7 +58,7 @@ struct snd_seq_client { int num_ports; /* number of ports */ struct list_head ports_list_head; rwlock_t ports_lock; - struct semaphore ports_mutex; + struct mutex ports_mutex; int convert32; /* convert 32->64bit */ /* output pool */ diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 9ece443fba5..d9a3e5a18d6 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -45,6 +45,7 @@ #include <sound/initval.h> #include <linux/kmod.h> #include <linux/slab.h> +#include <linux/mutex.h> MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); MODULE_DESCRIPTION("ALSA sequencer device management"); @@ -69,7 +70,7 @@ struct ops_list { struct list_head dev_list; /* list of devices */ int num_devices; /* number of associated devices */ int num_init_devices; /* number of initialized devices */ - struct semaphore reg_mutex; + struct mutex reg_mutex; struct list_head list; /* next driver */ }; @@ -77,7 +78,7 @@ struct ops_list { static LIST_HEAD(opslist); static int num_ops; -static DECLARE_MUTEX(ops_mutex); +static DEFINE_MUTEX(ops_mutex); #ifdef CONFIG_PROC_FS static struct snd_info_entry *info_entry = NULL; #endif @@ -108,7 +109,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, { struct list_head *head; - down(&ops_mutex); + mutex_lock(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); snd_iprintf(buffer, "snd-%s%s%s%s,%d\n", @@ -118,7 +119,7 @@ static void snd_seq_device_info(struct snd_info_entry *entry, ops->driver & DRIVER_LOCKED ? ",locked" : "", ops->num_devices); } - up(&ops_mutex); + mutex_unlock(&ops_mutex); } #endif @@ -154,20 +155,20 @@ void snd_seq_device_load_drivers(void) if (! current->fs->root) return; - down(&ops_mutex); + mutex_lock(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); if (! (ops->driver & DRIVER_LOADED) && ! (ops->driver & DRIVER_REQUESTED)) { ops->used++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); ops->driver |= DRIVER_REQUESTED; request_module("snd-%s", ops->id); - down(&ops_mutex); + mutex_lock(&ops_mutex); ops->used--; } } - up(&ops_mutex); + mutex_unlock(&ops_mutex); #endif } @@ -214,10 +215,10 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, dev->status = SNDRV_SEQ_DEVICE_FREE; /* add this device to the list */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); list_add_tail(&dev->list, &ops->dev_list); ops->num_devices++; - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); @@ -246,10 +247,10 @@ static int snd_seq_device_free(struct snd_seq_device *dev) return -ENXIO; /* remove the device from the list */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); list_del(&dev->list); ops->num_devices--; - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); free_device(dev, ops); if (dev->private_free) @@ -344,7 +345,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, return -EBUSY; } - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); /* copy driver operators */ ops->ops = *entry; ops->driver |= DRIVER_LOADED; @@ -355,7 +356,7 @@ int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); init_device(dev, ops); } - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); snd_seq_autoload_unlock(); @@ -378,17 +379,17 @@ static struct ops_list * create_driver(char *id) /* set up driver entry */ strlcpy(ops->id, id, sizeof(ops->id)); - init_MUTEX(&ops->reg_mutex); + mutex_init(&ops->reg_mutex); ops->driver = DRIVER_EMPTY; INIT_LIST_HEAD(&ops->dev_list); /* lock this instance */ ops->used = 1; /* register driver entry */ - down(&ops_mutex); + mutex_lock(&ops_mutex); list_add_tail(&ops->list, &opslist); num_ops++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); return ops; } @@ -414,7 +415,7 @@ int snd_seq_device_unregister_driver(char *id) } /* close and release all devices associated with this driver */ - down(&ops->reg_mutex); + mutex_lock(&ops->reg_mutex); ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */ list_for_each(head, &ops->dev_list) { struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list); @@ -425,7 +426,7 @@ int snd_seq_device_unregister_driver(char *id) if (ops->num_init_devices > 0) snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", ops->num_init_devices); - up(&ops->reg_mutex); + mutex_unlock(&ops->reg_mutex); unlock_driver(ops); @@ -443,7 +444,7 @@ static void remove_drivers(void) { struct list_head *head; - down(&ops_mutex); + mutex_lock(&ops_mutex); head = opslist.next; while (head != &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); @@ -456,7 +457,7 @@ static void remove_drivers(void) } else head = head->next; } - up(&ops_mutex); + mutex_unlock(&ops_mutex); } /* @@ -519,16 +520,16 @@ static struct ops_list * find_driver(char *id, int create_if_empty) { struct list_head *head; - down(&ops_mutex); + mutex_lock(&ops_mutex); list_for_each(head, &opslist) { struct ops_list *ops = list_entry(head, struct ops_list, list); if (strcmp(ops->id, id) == 0) { ops->used++; - up(&ops_mutex); + mutex_unlock(&ops_mutex); return ops; } } - up(&ops_mutex); + mutex_unlock(&ops_mutex); if (create_if_empty) return create_driver(id); return NULL; @@ -536,9 +537,9 @@ static struct ops_list * find_driver(char *id, int create_if_empty) static void unlock_driver(struct ops_list *ops) { - down(&ops_mutex); + mutex_lock(&ops_mutex); ops->used--; - up(&ops_mutex); + mutex_unlock(&ops_mutex); } diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c index 48745206396..f30d171b6d9 100644 --- a/sound/core/seq/seq_instr.c +++ b/sound/core/seq/seq_instr.c @@ -36,7 +36,7 @@ static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list) if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { spin_lock_irqsave(&list->ops_lock, list->ops_flags); } else { - down(&list->ops_mutex); + mutex_lock(&list->ops_mutex); } } @@ -45,7 +45,7 @@ static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list) if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) { spin_unlock_irqrestore(&list->ops_lock, list->ops_flags); } else { - up(&list->ops_mutex); + mutex_unlock(&list->ops_mutex); } } @@ -82,7 +82,7 @@ struct snd_seq_kinstr_list *snd_seq_instr_list_new(void) return NULL; spin_lock_init(&list->lock); spin_lock_init(&list->ops_lock); - init_MUTEX(&list->ops_mutex); + mutex_init(&list->ops_mutex); list->owner = -1; return list; } diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index ce0df86157d..9caa1372bec 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -32,7 +32,7 @@ Possible options for midisynth module: #include <linux/errno.h> #include <linux/string.h> #include <linux/moduleparam.h> -#include <asm/semaphore.h> +#include <linux/mutex.h> #include <sound/core.h> #include <sound/rawmidi.h> #include <sound/seq_kernel.h> @@ -70,7 +70,7 @@ struct seq_midisynth_client { }; static struct seq_midisynth_client *synths[SNDRV_CARDS]; -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); /* handle rawmidi input event (MIDI v1.0 stream) */ static void snd_midi_input_event(struct snd_rawmidi_substream *substream) @@ -308,13 +308,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) if (ports > (256 / SNDRV_RAWMIDI_DEVICES)) ports = 256 / SNDRV_RAWMIDI_DEVICES; - down(®ister_mutex); + mutex_lock(®ister_mutex); client = synths[card->number]; if (client == NULL) { newclient = 1; client = kzalloc(sizeof(*client), GFP_KERNEL); if (client == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); return -ENOMEM; } @@ -324,7 +324,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) (const char *)info->name : "External MIDI"); if (client->seq_client < 0) { kfree(client); - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); return -ENOMEM; } @@ -397,7 +397,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) client->num_ports++; if (newclient) synths[card->number] = client; - up(®ister_mutex); + mutex_unlock(®ister_mutex); kfree(info); kfree(port); return 0; /* success */ @@ -414,7 +414,7 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) } kfree(info); kfree(port); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } @@ -427,10 +427,10 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) struct snd_card *card = dev->card; int device = dev->device, p, ports; - down(®ister_mutex); + mutex_lock(®ister_mutex); client = synths[card->number]; if (client == NULL || client->ports[device] == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENODEV; } ports = client->ports_per_device[device]; @@ -446,7 +446,7 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev) synths[card->number] = NULL; kfree(client); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 2b384fd7967..41e078c938c 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -159,7 +159,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, port_subs_info_init(&new_port->c_dest); num = port >= 0 ? port : 0; - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); @@ -173,7 +173,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ write_unlock_irqrestore(&client->ports_lock, flags); - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); sprintf(new_port->name, "port-%d", num); return new_port; @@ -292,7 +292,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) struct list_head *l; struct snd_seq_client_port *found = NULL; - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); list_for_each(l, &client->ports_list_head) { struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list); @@ -305,7 +305,7 @@ int snd_seq_delete_port(struct snd_seq_client *client, int port) } } write_unlock_irqrestore(&client->ports_lock, flags); - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); if (found) return port_delete(client, found); else @@ -321,7 +321,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) /* move the port list to deleted_list, and * clear the port list in the client data. */ - down(&client->ports_mutex); + mutex_lock(&client->ports_mutex); write_lock_irqsave(&client->ports_lock, flags); if (! list_empty(&client->ports_list_head)) { __list_add(&deleted_list, @@ -341,7 +341,7 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port); port_delete(client, port); } - up(&client->ports_mutex); + mutex_unlock(&client->ports_mutex); return 0; } diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 9cf20f04554..9b87bb0c7f3 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -119,7 +119,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked) spin_lock_init(&q->owner_lock); spin_lock_init(&q->check_lock); - init_MUTEX(&q->timer_mutex); + mutex_init(&q->timer_mutex); snd_use_lock_init(&q->use_lock); q->queue = -1; @@ -516,7 +516,7 @@ int snd_seq_queue_use(int queueid, int client, int use) queue = queueptr(queueid); if (queue == NULL) return -EINVAL; - down(&queue->timer_mutex); + mutex_lock(&queue->timer_mutex); if (use) { if (!test_and_set_bit(client, queue->clients_bitmap)) queue->clients++; @@ -531,7 +531,7 @@ int snd_seq_queue_use(int queueid, int client, int use) } else { snd_seq_timer_close(queue); } - up(&queue->timer_mutex); + mutex_unlock(&queue->timer_mutex); queuefree(queue); return 0; } diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h index 88843859938..30c8111477f 100644 --- a/sound/core/seq/seq_queue.h +++ b/sound/core/seq/seq_queue.h @@ -54,7 +54,7 @@ struct snd_seq_queue { /* clients which uses this queue (bitmap) */ DECLARE_BITMAP(clients_bitmap, SNDRV_SEQ_MAX_CLIENTS); unsigned int clients; /* users of this queue */ - struct semaphore timer_mutex; + struct mutex timer_mutex; snd_use_lock_t use_lock; }; diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 14fd1a608e1..f4edec603b8 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -167,7 +167,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, return; /* ignored */ } if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } @@ -186,7 +186,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, pbuf += res; count -= res; if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { - if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, 0, 0) < 0) + if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) return; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } diff --git a/sound/core/sound.c b/sound/core/sound.c index a8eda02bcf1..4d28e521261 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -33,6 +33,7 @@ #include <sound/initval.h> #include <linux/kmod.h> #include <linux/devfs_fs_kernel.h> +#include <linux/mutex.h> #define SNDRV_OS_MINORS 256 @@ -61,7 +62,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); int snd_ecards_limit; static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; -static DECLARE_MUTEX(sound_mutex); +static DEFINE_MUTEX(sound_mutex); extern struct class *sound_class; @@ -120,15 +121,15 @@ void *snd_lookup_minor_data(unsigned int minor, int type) struct snd_minor *mreg; void *private_data; - if (minor > ARRAY_SIZE(snd_minors)) + if (minor >= ARRAY_SIZE(snd_minors)) return NULL; - down(&sound_mutex); + mutex_lock(&sound_mutex); mreg = snd_minors[minor]; if (mreg && mreg->type == type) private_data = mreg->private_data; else private_data = NULL; - up(&sound_mutex); + mutex_unlock(&sound_mutex); return private_data; } @@ -139,7 +140,7 @@ static int snd_open(struct inode *inode, struct file *file) struct file_operations *old_fops; int err = 0; - if (minor > ARRAY_SIZE(snd_minors)) + if (minor >= ARRAY_SIZE(snd_minors)) return -ENODEV; mptr = snd_minors[minor]; if (mptr == NULL) { @@ -256,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, preg->f_ops = f_ops; preg->private_data = private_data; strcpy(preg->name, name); - down(&sound_mutex); + mutex_lock(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS minor = snd_find_free_minor(); #else @@ -265,7 +266,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, minor = -EBUSY; #endif if (minor < 0) { - up(&sound_mutex); + mutex_unlock(&sound_mutex); kfree(preg); return minor; } @@ -276,7 +277,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, device = card->dev; class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name); - up(&sound_mutex); + mutex_unlock(&sound_mutex); return 0; } @@ -297,7 +298,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) struct snd_minor *mptr; cardnum = card ? card->number : -1; - down(&sound_mutex); + mutex_lock(&sound_mutex); for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) if ((mptr = snd_minors[minor]) != NULL && mptr->type == type && @@ -305,7 +306,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) mptr->device == dev) break; if (minor == ARRAY_SIZE(snd_minors)) { - up(&sound_mutex); + mutex_unlock(&sound_mutex); return -EINVAL; } @@ -315,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) class_device_destroy(sound_class, MKDEV(major, minor)); snd_minors[minor] = NULL; - up(&sound_mutex); + mutex_unlock(&sound_mutex); kfree(mptr); return 0; } @@ -354,7 +355,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu int minor; struct snd_minor *mptr; - down(&sound_mutex); + mutex_lock(&sound_mutex); for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) { if (!(mptr = snd_minors[minor])) continue; @@ -371,7 +372,7 @@ static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_bu snd_iprintf(buffer, "%3i: : %s\n", minor, snd_device_type_name(mptr->type)); } - up(&sound_mutex); + mutex_unlock(&sound_mutex); } int __init snd_minor_info_init(void) diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index d0be32b517c..4023d3b406d 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -34,26 +34,27 @@ #include <sound/minors.h> #include <sound/info.h> #include <linux/sound.h> +#include <linux/mutex.h> #define SNDRV_OSS_MINORS 128 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; -static DECLARE_MUTEX(sound_oss_mutex); +static DEFINE_MUTEX(sound_oss_mutex); void *snd_lookup_oss_minor_data(unsigned int minor, int type) { struct snd_minor *mreg; void *private_data; - if (minor > ARRAY_SIZE(snd_oss_minors)) + if (minor >= ARRAY_SIZE(snd_oss_minors)) return NULL; - down(&sound_oss_mutex); + mutex_lock(&sound_oss_mutex); mreg = snd_oss_minors[minor]; if (mreg && mreg->type == type) private_data = mreg->private_data; else private_data = NULL; - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); return private_data; } @@ -117,7 +118,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, preg->device = dev; preg->f_ops = f_ops; preg->private_data = private_data; - down(&sound_oss_mutex); + mutex_lock(&sound_oss_mutex); snd_oss_minors[minor] = preg; minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); switch (minor_unit) { @@ -143,7 +144,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, goto __end; snd_oss_minors[track2] = preg; } - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); return 0; __end: @@ -152,7 +153,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, if (register1 >= 0) unregister_sound_special(register1); snd_oss_minors[minor] = NULL; - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); kfree(preg); return -EBUSY; } @@ -168,10 +169,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) return 0; if (minor < 0) return minor; - down(&sound_oss_mutex); + mutex_lock(&sound_oss_mutex); mptr = snd_oss_minors[minor]; if (mptr == NULL) { - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); return -ENOENT; } unregister_sound_special(minor); @@ -191,7 +192,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) snd_oss_minors[track2] = NULL; } snd_oss_minors[minor] = NULL; - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); kfree(mptr); return 0; } @@ -229,7 +230,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, int minor; struct snd_minor *mptr; - down(&sound_oss_mutex); + mutex_lock(&sound_oss_mutex); for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) { if (!(mptr = snd_oss_minors[minor])) continue; @@ -241,7 +242,7 @@ static void snd_minor_info_oss_read(struct snd_info_entry *entry, snd_iprintf(buffer, "%3i: : %s\n", minor, snd_oss_device_type_name(mptr->type)); } - up(&sound_oss_mutex); + mutex_unlock(&sound_oss_mutex); } diff --git a/sound/core/timer.c b/sound/core/timer.c index 2425b971b24..cdeeb639b67 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -25,6 +25,7 @@ #include <linux/smp_lock.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/mutex.h> #include <linux/moduleparam.h> #include <linux/string.h> #include <sound/core.h> @@ -70,7 +71,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct semaphore tread_sem; + struct mutex tread_sem; }; /* list of timers */ @@ -82,7 +83,7 @@ static LIST_HEAD(snd_timer_slave_list); /* lock for slave active lists */ static DEFINE_SPINLOCK(slave_active_lock); -static DECLARE_MUTEX(register_mutex); +static DEFINE_MUTEX(register_mutex); static int snd_timer_free(struct snd_timer *timer); static int snd_timer_dev_free(struct snd_device *device); @@ -252,10 +253,10 @@ int snd_timer_open(struct snd_timer_instance **ti, snd_printd("invalid slave class %i\n", tid->dev_sclass); return -EINVAL; } - down(®ister_mutex); + mutex_lock(®ister_mutex); timeri = snd_timer_instance_new(owner, NULL); if (!timeri) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } timeri->slave_class = tid->dev_sclass; @@ -263,37 +264,37 @@ int snd_timer_open(struct snd_timer_instance **ti, timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; list_add_tail(&timeri->open_list, &snd_timer_slave_list); snd_timer_check_slave(timeri); - up(®ister_mutex); + mutex_unlock(®ister_mutex); *ti = timeri; return 0; } /* open a master instance */ - down(®ister_mutex); + mutex_lock(®ister_mutex); timer = snd_timer_find(tid); #ifdef CONFIG_KMOD if (timer == NULL) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); snd_timer_request(tid); - down(®ister_mutex); + mutex_lock(®ister_mutex); timer = snd_timer_find(tid); } #endif if (!timer) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENODEV; } if (!list_empty(&timer->open_list_head)) { timeri = list_entry(timer->open_list_head.next, struct snd_timer_instance, open_list); if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } } timeri = snd_timer_instance_new(owner, timer); if (!timeri) { - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -ENOMEM; } timeri->slave_class = tid->dev_sclass; @@ -302,7 +303,7 @@ int snd_timer_open(struct snd_timer_instance **ti, timer->hw.open(timer); list_add_tail(&timeri->open_list, &timer->open_list_head); snd_timer_check_master(timeri); - up(®ister_mutex); + mutex_unlock(®ister_mutex); *ti = timeri; return 0; } @@ -333,9 +334,9 @@ int snd_timer_close(struct snd_timer_instance *timeri) spin_lock_irq(&slave_active_lock); } spin_unlock_irq(&slave_active_lock); - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del(&timeri->open_list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); } else { timer = timeri->timer; /* wait, until the active callback is finished */ @@ -346,7 +347,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) spin_lock_irq(&timer->lock); } spin_unlock_irq(&timer->lock); - down(®ister_mutex); + mutex_lock(®ister_mutex); list_del(&timeri->open_list); if (timer && list_empty(&timer->open_list_head) && timer->hw.close) @@ -362,7 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) slave->timer = NULL; spin_unlock_irq(&slave_active_lock); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); } if (timeri->private_free) timeri->private_free(timeri); @@ -835,7 +836,7 @@ static int snd_timer_dev_register(struct snd_device *dev) !timer->hw.resolution && timer->hw.c_resolution == NULL) return -EINVAL; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_for_each(p, &snd_timer_list) { timer1 = list_entry(p, struct snd_timer, device_list); if (timer1->tmr_class > timer->tmr_class) @@ -857,11 +858,11 @@ static int snd_timer_dev_register(struct snd_device *dev) if (timer1->tmr_subdevice < timer->tmr_subdevice) continue; /* conflicts.. */ - up(®ister_mutex); + mutex_unlock(®ister_mutex); return -EBUSY; } list_add_tail(&timer->device_list, p); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return 0; } @@ -871,7 +872,7 @@ static int snd_timer_unregister(struct snd_timer *timer) struct snd_timer_instance *ti; snd_assert(timer != NULL, return -ENXIO); - down(®ister_mutex); + mutex_lock(®ister_mutex); if (! list_empty(&timer->open_list_head)) { snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); list_for_each_safe(p, n, &timer->open_list_head) { @@ -881,7 +882,7 @@ static int snd_timer_unregister(struct snd_timer *timer) } } list_del(&timer->device_list); - up(®ister_mutex); + mutex_unlock(®ister_mutex); return snd_timer_free(timer); } @@ -1065,7 +1066,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, struct snd_timer_instance *ti; struct list_head *p, *q; - down(®ister_mutex); + mutex_lock(®ister_mutex); list_for_each(p, &snd_timer_list) { timer = list_entry(p, struct snd_timer, device_list); switch (timer->tmr_class) { @@ -1105,7 +1106,7 @@ static void snd_timer_proc_read(struct snd_info_entry *entry, } spin_unlock_irqrestore(&timer->lock, flags); } - up(®ister_mutex); + mutex_unlock(®ister_mutex); } static struct snd_info_entry *snd_timer_proc_entry = NULL; @@ -1269,7 +1270,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - init_MUTEX(&tu->tread_sem); + mutex_init(&tu->tread_sem); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1325,7 +1326,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) if (copy_from_user(&id, _tid, sizeof(id))) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); if (id.dev_class < 0) { /* first item */ if (list_empty(&snd_timer_list)) snd_timer_user_zero_id(&id); @@ -1407,7 +1408,7 @@ static int snd_timer_user_next_device(struct snd_timer_id __user *_tid) snd_timer_user_zero_id(&id); } } - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (copy_to_user(_tid, &id, sizeof(*_tid))) return -EFAULT; return 0; @@ -1432,7 +1433,7 @@ static int snd_timer_user_ginfo(struct file *file, tid = ginfo->tid; memset(ginfo, 0, sizeof(*ginfo)); ginfo->tid = tid; - down(®ister_mutex); + mutex_lock(®ister_mutex); t = snd_timer_find(&tid); if (t != NULL) { ginfo->card = t->card ? t->card->number : -1; @@ -1451,7 +1452,7 @@ static int snd_timer_user_ginfo(struct file *file, } else { err = -ENODEV; } - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (err >= 0 && copy_to_user(_ginfo, ginfo, sizeof(*ginfo))) err = -EFAULT; kfree(ginfo); @@ -1467,7 +1468,7 @@ static int snd_timer_user_gparams(struct file *file, if (copy_from_user(&gparams, _gparams, sizeof(gparams))) return -EFAULT; - down(®ister_mutex); + mutex_lock(®ister_mutex); t = snd_timer_find(&gparams.tid); if (!t) { err = -ENODEV; @@ -1483,7 +1484,7 @@ static int snd_timer_user_gparams(struct file *file, } err = t->hw.set_period(t, gparams.period_num, gparams.period_den); _error: - up(®ister_mutex); + mutex_unlock(®ister_mutex); return err; } @@ -1500,7 +1501,7 @@ static int snd_timer_user_gstatus(struct file *file, tid = gstatus.tid; memset(&gstatus, 0, sizeof(gstatus)); gstatus.tid = tid; - down(®ister_mutex); + mutex_lock(®ister_mutex); t = snd_timer_find(&tid); if (t != NULL) { if (t->hw.c_resolution) @@ -1517,7 +1518,7 @@ static int snd_timer_user_gstatus(struct file *file, } else { err = -ENODEV; } - up(®ister_mutex); + mutex_unlock(®ister_mutex); if (err >= 0 && copy_to_user(_gstatus, &gstatus, sizeof(gstatus))) err = -EFAULT; return err; @@ -1532,7 +1533,7 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - down(&tu->tread_sem); + mutex_lock(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1576,7 +1577,7 @@ static int snd_timer_user_tselect(struct file *file, } __err: - up(&tu->tread_sem); + mutex_unlock(&tu->tread_sem); return err; } @@ -1797,17 +1798,17 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - down(&tu->tread_sem); + mutex_lock(&tu->tread_sem); if (tu->timeri) { /* too late */ - up(&tu->tread_sem); + mutex_unlock(&tu->tread_sem); return -EBUSY; } if (get_user(xarg, p)) { - up(&tu->tread_sem); + mutex_unlock(&tu->tread_sem); return -EFAULT; } tu->tread = xarg ? 1 : 0; - up(&tu->tread_sem); + mutex_unlock(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: |