diff options
Diffstat (limited to 'sound/core')
45 files changed, 885 insertions, 430 deletions
diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 335d45ecde6..66348c92f88 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -12,6 +12,12 @@ config SND_HWDEP config SND_RAWMIDI tristate +# To be effective this also requires INPUT - users should say: +# select SND_JACK if INPUT=y || INPUT=SND +# to avoid having to force INPUT on. +config SND_JACK + bool + config SND_SEQUENCER tristate "Sequencer support" select SND_TIMER @@ -38,6 +44,7 @@ config SND_SEQ_DUMMY will be called snd-seq-dummy. config SND_OSSEMUL + select SOUND_OSS_CORE bool config SND_MIXER_OSS @@ -101,6 +108,9 @@ config SND_RTCTIMER To compile this driver as a module, choose M here: the module will be called snd-rtctimer. + Note that this option is exclusive with the new RTC drivers + (CONFIG_RTC_CLASS) since this requires the old API. + config SND_SEQ_RTCTIMER_DEFAULT bool "Use RTC as default sequencer timer" depends on SND_RTCTIMER && SND_SEQUENCER diff --git a/sound/core/Makefile b/sound/core/Makefile index da8e685eef9..d57125a5687 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -7,6 +7,7 @@ snd-y := sound.o init.o memory.o info.o control.o misc.o device.o snd-$(CONFIG_ISA_DMA_API) += isadma.o snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o snd-$(CONFIG_SND_VMASTER) += vmaster.o +snd-$(CONFIG_SND_JACK) += jack.o snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ pcm_memory.o diff --git a/sound/core/control.c b/sound/core/control.c index 281b2e2ef0e..6d71f9a7ccb 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -139,7 +139,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, struct snd_ctl_file *ctl; struct snd_kctl_event *ev; - snd_assert(card != NULL && id != NULL, return); + if (snd_BUG_ON(!card || !id)) + return; read_lock(&card->ctl_files_rwlock); #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) card->mixer_oss_change_count++; @@ -188,8 +189,8 @@ static struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, struct snd_kcontrol *kctl; unsigned int idx; - snd_assert(control != NULL, return NULL); - snd_assert(control->count > 0, return NULL); + if (snd_BUG_ON(!control || !control->count)) + return NULL; kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL); if (kctl == NULL) { snd_printk(KERN_ERR "Cannot allocate control instance\n"); @@ -218,8 +219,8 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, struct snd_kcontrol kctl; unsigned int access; - snd_assert(ncontrol != NULL, return NULL); - snd_assert(ncontrol->info != NULL, return NULL); + if (snd_BUG_ON(!ncontrol || !ncontrol->info)) + return NULL; memset(&kctl, 0, sizeof(kctl)); kctl.id.iface = ncontrol->iface; kctl.id.device = ncontrol->device; @@ -315,8 +316,8 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) if (! kcontrol) return err; - snd_assert(card != NULL, goto error); - snd_assert(kcontrol->info != NULL, goto error); + if (snd_BUG_ON(!card || !kcontrol->info)) + goto error; id = kcontrol->id; down_write(&card->controls_rwsem); if (snd_ctl_find_id(card, &id)) { @@ -367,7 +368,8 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) struct snd_ctl_elem_id id; unsigned int idx; - snd_assert(card != NULL && kcontrol != NULL, return -EINVAL); + if (snd_BUG_ON(!card || !kcontrol)) + return -EINVAL; list_del(&kcontrol->list); card->controls_count -= kcontrol->count; id = kcontrol->id; @@ -487,7 +489,8 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi { struct snd_kcontrol *kctl; - snd_assert(card != NULL && numid != 0, return NULL); + if (snd_BUG_ON(!card || !numid)) + return NULL; list_for_each_entry(kctl, &card->controls, list) { if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) return kctl; @@ -514,7 +517,8 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, { struct snd_kcontrol *kctl; - snd_assert(card != NULL && id != NULL, return NULL); + if (snd_BUG_ON(!card || !id)) + return NULL; if (id->numid != 0) return snd_ctl_find_numid(card, id->numid); list_for_each_entry(kctl, &card->controls, list) { @@ -647,7 +651,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl, #endif result = kctl->info(kctl, info); if (result >= 0) { - snd_assert(info->access == 0, ); + snd_BUG_ON(info->access); index_offset = snd_ctl_get_ioff(kctl, &info->id); vd = &kctl->vd[index_offset]; snd_ctl_build_ioff(&info->id, kctl, index_offset); @@ -1160,7 +1164,8 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg ctl = file->private_data; card = ctl->card; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; switch (cmd) { case SNDRV_CTL_IOCTL_PVERSION: return put_user(SNDRV_CTL_VERSION, ip) ? -EFAULT : 0; @@ -1222,7 +1227,8 @@ static ssize_t snd_ctl_read(struct file *file, char __user *buffer, ssize_t result = 0; ctl = file->private_data; - snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO); + if (snd_BUG_ON(!ctl || !ctl->card)) + return -ENXIO; if (!ctl->subscribed) return -EBADFD; if (count < sizeof(struct snd_ctl_event)) @@ -1328,7 +1334,8 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, { struct snd_kctl_ioctl *p; - snd_assert(fcn != NULL, return -EINVAL); + if (snd_BUG_ON(!fcn)) + return -EINVAL; down_write(&snd_ioctl_rwsem); list_for_each_entry(p, lists, list) { if (p->fioctl == fcn) { @@ -1404,9 +1411,11 @@ static int snd_ctl_dev_register(struct snd_device *device) int err, cardnum; char name[16]; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; cardnum = card->number; - snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); + if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS)) + return -ENXIO; sprintf(name, "controlC%i", cardnum); if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1, &snd_ctl_f_ops, card, name)) < 0) @@ -1423,16 +1432,18 @@ static int snd_ctl_dev_disconnect(struct snd_device *device) struct snd_ctl_file *ctl; int err, cardnum; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; cardnum = card->number; - snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); + if (snd_BUG_ON(cardnum < 0 || cardnum >= SNDRV_CARDS)) + return -ENXIO; - down_read(&card->controls_rwsem); + read_lock(&card->ctl_files_rwlock); list_for_each_entry(ctl, &card->ctl_files, list) { wake_up(&ctl->change_sleep); kill_fasync(&ctl->fasync, SIGIO, POLL_ERR); } - up_read(&card->controls_rwsem); + read_unlock(&card->ctl_files_rwlock); if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1)) < 0) @@ -1469,7 +1480,8 @@ int snd_ctl_create(struct snd_card *card) .dev_disconnect = snd_ctl_dev_disconnect, }; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; return snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops); } diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 6101259ad86..368dc9c4aef 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -398,7 +398,8 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns int err; ctl = file->private_data; - snd_assert(ctl && ctl->card, return -ENXIO); + if (snd_BUG_ON(!ctl || !ctl->card)) + return -ENXIO; switch (cmd) { case SNDRV_CTL_IOCTL_PVERSION: diff --git a/sound/core/device.c b/sound/core/device.c index 202dac0e4d8..c58d8227254 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -45,9 +45,8 @@ int snd_device_new(struct snd_card *card, snd_device_type_t type, { struct snd_device *dev; - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); - snd_assert(ops != NULL, return -ENXIO); + if (snd_BUG_ON(!card || !device_data || !ops)) + return -ENXIO; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { snd_printk(KERN_ERR "Cannot allocate device\n"); @@ -80,8 +79,8 @@ int snd_device_free(struct snd_card *card, void *device_data) { struct snd_device *dev; - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); + if (snd_BUG_ON(!card || !device_data)) + return -ENXIO; list_for_each_entry(dev, &card->devices, list) { if (dev->device_data != device_data) continue; @@ -123,8 +122,8 @@ int snd_device_disconnect(struct snd_card *card, void *device_data) { struct snd_device *dev; - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); + if (snd_BUG_ON(!card || !device_data)) + return -ENXIO; list_for_each_entry(dev, &card->devices, list) { if (dev->device_data != device_data) continue; @@ -159,8 +158,8 @@ int snd_device_register(struct snd_card *card, void *device_data) struct snd_device *dev; int err; - snd_assert(card != NULL, return -ENXIO); - snd_assert(device_data != NULL, return -ENXIO); + if (snd_BUG_ON(!card || !device_data)) + return -ENXIO; list_for_each_entry(dev, &card->devices, list) { if (dev->device_data != device_data) continue; @@ -188,7 +187,8 @@ int snd_device_register_all(struct snd_card *card) struct snd_device *dev; int err; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; list_for_each_entry(dev, &card->devices, list) { if (dev->state == SNDRV_DEV_BUILD && dev->ops->dev_register) { if ((err = dev->ops->dev_register(dev)) < 0) @@ -208,7 +208,8 @@ int snd_device_disconnect_all(struct snd_card *card) struct snd_device *dev; int err = 0; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; list_for_each_entry(dev, &card->devices, list) { if (snd_device_disconnect(card, dev->device_data) < 0) err = -ENXIO; @@ -226,7 +227,8 @@ int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd) int err; unsigned int range_low, range_high; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; range_low = cmd * SNDRV_DEV_TYPE_RANGE_SIZE; range_high = range_low + SNDRV_DEV_TYPE_RANGE_SIZE - 1; __again: diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 6d6589f9389..195cafc5a55 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -353,9 +353,10 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, .dev_disconnect = snd_hwdep_dev_disconnect, }; - snd_assert(rhwdep != NULL, return -EINVAL); - *rhwdep = NULL; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; + if (rhwdep) + *rhwdep = NULL; hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL); if (hwdep == NULL) { snd_printk(KERN_ERR "hwdep: cannot allocate\n"); @@ -374,13 +375,15 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, } init_waitqueue_head(&hwdep->open_wait); mutex_init(&hwdep->open_mutex); - *rhwdep = hwdep; + if (rhwdep) + *rhwdep = hwdep; return 0; } static int snd_hwdep_free(struct snd_hwdep *hwdep) { - snd_assert(hwdep != NULL, return -ENXIO); + if (!hwdep) + return 0; if (hwdep->private_free) hwdep->private_free(hwdep); kfree(hwdep); @@ -440,7 +443,8 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) { struct snd_hwdep *hwdep = device->device_data; - snd_assert(hwdep != NULL, return -ENXIO); + if (snd_BUG_ON(!hwdep)) + return -ENXIO; mutex_lock(®ister_mutex); if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { mutex_unlock(®ister_mutex); diff --git a/sound/core/info.c b/sound/core/info.c index c67773ad929..527b207462b 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -217,7 +217,8 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, loff_t pos; data = file->private_data; - snd_assert(data != NULL, return -ENXIO); + if (snd_BUG_ON(!data)) + return -ENXIO; pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; @@ -258,7 +259,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer loff_t pos; data = file->private_data; - snd_assert(data != NULL, return -ENXIO); + if (snd_BUG_ON(!data)) + return -ENXIO; entry = data->entry; pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) @@ -614,7 +616,8 @@ int snd_info_card_create(struct snd_card *card) char str[8]; struct snd_info_entry *entry; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; sprintf(str, "card%i", card->number); if ((entry = snd_info_create_module_entry(card->module, str, NULL)) == NULL) @@ -636,7 +639,8 @@ int snd_info_card_register(struct snd_card *card) { struct proc_dir_entry *p; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; if (!strcmp(card->id, card->proc_root->name)) return 0; @@ -654,7 +658,8 @@ int snd_info_card_register(struct snd_card *card) */ void snd_info_card_disconnect(struct snd_card *card) { - snd_assert(card != NULL, return); + if (!card) + return; mutex_lock(&info_mutex); if (card->proc_root_link) { snd_remove_proc_entry(snd_proc_root, card->proc_root_link); @@ -671,7 +676,8 @@ void snd_info_card_disconnect(struct snd_card *card) */ int snd_info_card_free(struct snd_card *card) { - snd_assert(card != NULL, return -ENXIO); + if (!card) + return 0; snd_info_free_entry(card->proc_root); card->proc_root = NULL; return 0; @@ -849,7 +855,7 @@ static void snd_info_disconnect(struct snd_info_entry *entry) return; list_del_init(&entry->list); root = entry->parent == NULL ? snd_proc_root : entry->parent->p; - snd_assert(root, return); + snd_BUG_ON(!root); snd_remove_proc_entry(root, entry->p); entry->p = NULL; } @@ -947,7 +953,8 @@ int snd_info_register(struct snd_info_entry * entry) { struct proc_dir_entry *root, *p = NULL; - snd_assert(entry != NULL, return -ENXIO); + if (snd_BUG_ON(!entry)) + return -ENXIO; root = entry->parent == NULL ? snd_proc_root : entry->parent->p; mutex_lock(&info_mutex); p = snd_create_proc_entry(entry->name, entry->mode, root); diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index e35789a9275..e4af138d651 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c @@ -43,8 +43,10 @@ int snd_oss_info_register(int dev, int num, char *string) { char *x; - snd_assert(dev >= 0 && dev < SNDRV_OSS_INFO_DEV_COUNT, return -ENXIO); - snd_assert(num >= 0 && num < SNDRV_CARDS, return -ENXIO); + if (snd_BUG_ON(dev < 0 || dev >= SNDRV_OSS_INFO_DEV_COUNT)) + return -ENXIO; + if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS)) + return -ENXIO; mutex_lock(&strings); if (string == NULL) { if ((x = snd_sndstat_strings[num][dev]) != NULL) { diff --git a/sound/core/init.c b/sound/core/init.c index df46bbc25dc..8af467df924 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -545,7 +545,8 @@ int snd_card_register(struct snd_card *card) { int err; - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; #ifndef CONFIG_SYSFS_DEPRECATED if (!card->card_dev) { card->card_dev = device_create_drvdata(sound_class, card->dev, diff --git a/sound/core/jack.c b/sound/core/jack.c new file mode 100644 index 00000000000..8133a2b173a --- /dev/null +++ b/sound/core/jack.c @@ -0,0 +1,163 @@ +/* + * Jack abstraction layer + * + * Copyright 2008 Wolfson Microelectronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/input.h> +#include <sound/jack.h> +#include <sound/core.h> + +static int snd_jack_dev_free(struct snd_device *device) +{ + struct snd_jack *jack = device->device_data; + + /* If the input device is registered with the input subsystem + * then we need to use a different deallocator. */ + if (jack->registered) + input_unregister_device(jack->input_dev); + else + input_free_device(jack->input_dev); + + kfree(jack); + + return 0; +} + +static int snd_jack_dev_register(struct snd_device *device) +{ + struct snd_jack *jack = device->device_data; + struct snd_card *card = device->card; + int err; + + snprintf(jack->name, sizeof(jack->name), "%s %s", + card->longname, jack->id); + jack->input_dev->name = jack->name; + + /* Default to the sound card device. */ + if (!jack->input_dev->dev.parent) + jack->input_dev->dev.parent = card->dev; + + err = input_register_device(jack->input_dev); + if (err == 0) + jack->registered = 1; + + return err; +} + +/** + * snd_jack_new - Create a new jack + * @card: the card instance + * @id: an identifying string for this jack + * @type: a bitmask of enum snd_jack_type values that can be detected by + * this jack + * @jjack: Used to provide the allocated jack object to the caller. + * + * Creates a new jack object. + * + * Returns zero if successful, or a negative error code on failure. + * On success jjack will be initialised. + */ +int snd_jack_new(struct snd_card *card, const char *id, int type, + struct snd_jack **jjack) +{ + struct snd_jack *jack; + int err; + static struct snd_device_ops ops = { + .dev_free = snd_jack_dev_free, + .dev_register = snd_jack_dev_register, + }; + + jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL); + if (jack == NULL) + return -ENOMEM; + + jack->id = id; + + jack->input_dev = input_allocate_device(); + if (jack->input_dev == NULL) { + err = -ENOMEM; + goto fail_input; + } + + jack->input_dev->phys = "ALSA"; + + jack->type = type; + + if (type & SND_JACK_HEADPHONE) + input_set_capability(jack->input_dev, EV_SW, + SW_HEADPHONE_INSERT); + if (type & SND_JACK_MICROPHONE) + input_set_capability(jack->input_dev, EV_SW, + SW_MICROPHONE_INSERT); + + err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); + if (err < 0) + goto fail_input; + + *jjack = jack; + + return 0; + +fail_input: + input_free_device(jack->input_dev); + kfree(jack); + return err; +} +EXPORT_SYMBOL(snd_jack_new); + +/** + * snd_jack_set_parent - Set the parent device for a jack + * + * @jack: The jack to configure + * @parent: The device to set as parent for the jack. + * + * Set the parent for the jack input device in the device tree. This + * function is only valid prior to registration of the jack. If no + * parent is configured then the parent device will be the sound card. + */ +void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) +{ + WARN_ON(jack->registered); + + jack->input_dev->dev.parent = parent; +} +EXPORT_SYMBOL(snd_jack_set_parent); + +/** + * snd_jack_report - Report the current status of a jack + * + * @jack: The jack to report status for + * @status: The current status of the jack + */ +void snd_jack_report(struct snd_jack *jack, int status) +{ + if (jack->type & SND_JACK_HEADPHONE) + input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, + status & SND_JACK_HEADPHONE); + if (jack->type & SND_JACK_MICROPHONE) + input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT, + status & SND_JACK_MICROPHONE); + + input_sync(jack->input_dev); +} +EXPORT_SYMBOL(snd_jack_report); + +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_DESCRIPTION("Jack detection support for ALSA"); +MODULE_LICENSE("GPL"); diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index f5d6d8d1297..a7b46ec72f3 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -46,14 +46,6 @@ MODULE_LICENSE("GPL"); /* */ -void *snd_malloc_sgbuf_pages(struct device *device, - size_t size, struct snd_dma_buffer *dmab, - size_t *res_size); -int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab); - -/* - */ - static DEFINE_MUTEX(list_mutex); static LIST_HEAD(mem_list_head); @@ -67,18 +59,6 @@ struct snd_mem_list { /* id for pre-allocated buffers */ #define SNDRV_DMA_DEVICE_UNUSED (unsigned int)-1 -#ifdef CONFIG_SND_DEBUG -#define __ASTRING__(x) #x -#define snd_assert(expr, args...) do {\ - if (!(expr)) {\ - printk(KERN_ERR "snd-malloc: BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\ - args;\ - }\ -} while (0) -#else -#define snd_assert(expr, args...) /**/ -#endif - /* * * Generic memory allocators @@ -111,8 +91,10 @@ void *snd_malloc_pages(size_t size, gfp_t gfp_flags) int pg; void *res; - snd_assert(size > 0, return NULL); - snd_assert(gfp_flags != 0, return NULL); + if (WARN_ON(!size)) + return NULL; + if (WARN_ON(!gfp_flags)) + 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) @@ -152,8 +134,8 @@ static void *snd_malloc_dev_pages(struct device *dev, size_t size, dma_addr_t *d void *res; gfp_t gfp_flags; - snd_assert(size > 0, return NULL); - snd_assert(dma != NULL, return NULL); + if (WARN_ON(!dma)) + return NULL; pg = get_order(size); gfp_flags = GFP_KERNEL | __GFP_COMP /* compound page lets parts be mapped */ @@ -189,8 +171,8 @@ static void *snd_malloc_sbus_pages(struct device *dev, size_t size, int pg; void *res; - snd_assert(size > 0, return NULL); - snd_assert(dma_addr != NULL, return NULL); + if (WARN_ON(!dma_addr)) + return NULL; pg = get_order(size); res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr); if (res != NULL) @@ -236,8 +218,10 @@ static void snd_free_sbus_pages(struct device *dev, size_t size, int snd_dma_alloc_pages(int type, struct device *device, size_t size, struct snd_dma_buffer *dmab) { - snd_assert(size > 0, return -ENXIO); - snd_assert(dmab != NULL, return -ENXIO); + if (WARN_ON(!size)) + return -ENXIO; + if (WARN_ON(!dmab)) + return -ENXIO; dmab->dev.type = type; dmab->dev.dev = device; @@ -292,15 +276,17 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size, { int err; - snd_assert(size > 0, return -ENXIO); - snd_assert(dmab != NULL, return -ENXIO); - while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) { + size_t aligned_size; if (err != -ENOMEM) return err; - size >>= 1; if (size <= PAGE_SIZE) return -ENOMEM; + aligned_size = PAGE_SIZE << get_order(size); + if (size != aligned_size) + size = aligned_size; + else + size >>= 1; } if (! dmab->area) return -ENOMEM; @@ -353,7 +339,8 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) { struct snd_mem_list *mem; - snd_assert(dmab, return 0); + if (WARN_ON(!dmab)) + return 0; mutex_lock(&list_mutex); list_for_each_entry(mem, &mem_list_head, list) { @@ -387,7 +374,8 @@ int snd_dma_reserve_buf(struct snd_dma_buffer *dmab, unsigned int id) { struct snd_mem_list *mem; - snd_assert(dmab, return -EINVAL); + if (WARN_ON(!dmab)) + return -EINVAL; mem = kmalloc(sizeof(*mem), GFP_KERNEL); if (! mem) return -ENOMEM; diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c index 9ded30d0e97..05b58d4fc2b 100644 --- a/sound/core/oss/copy.c +++ b/sound/core/oss/copy.c @@ -32,17 +32,18 @@ static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin, unsigned int channel; unsigned int nchannels; - snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) + return -ENXIO; if (frames == 0) return 0; nchannels = plugin->src_format.channels; for (channel = 0; channel < nchannels; channel++) { - snd_assert(src_channels->area.first % 8 == 0 && - src_channels->area.step % 8 == 0, - return -ENXIO); - snd_assert(dst_channels->area.first % 8 == 0 && - dst_channels->area.step % 8 == 0, - return -ENXIO); + if (snd_BUG_ON(src_channels->area.first % 8 || + src_channels->area.step % 8)) + return -ENXIO; + if (snd_BUG_ON(dst_channels->area.first % 8 || + dst_channels->area.step % 8)) + return -ENXIO; if (!src_channels->enabled) { if (dst_channels->wanted) snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format); @@ -66,15 +67,20 @@ int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug, struct snd_pcm_plugin *plugin; int width; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(src_format->format == dst_format->format, return -ENXIO); - snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(src_format->channels == dst_format->channels, return -ENXIO); + if (snd_BUG_ON(src_format->format != dst_format->format)) + return -ENXIO; + if (snd_BUG_ON(src_format->rate != dst_format->rate)) + return -ENXIO; + if (snd_BUG_ON(src_format->channels != dst_format->channels)) + return -ENXIO; width = snd_pcm_format_physical_width(src_format->format); - snd_assert(width > 0, return -ENXIO); + if (snd_BUG_ON(width <= 0)) + return -ENXIO; err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format, 0, &plugin); diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index f874f6ca365..6faa1d71920 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c @@ -39,14 +39,17 @@ static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin, struct snd_pcm_plugin_channel *dst_channels, snd_pcm_uframes_t frames) { - snd_assert(plugin != NULL, return -ENXIO); - snd_assert(src_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin)) + return -ENXIO; + if (snd_BUG_ON(!src_channels)) + return -ENXIO; if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { return pcm_write(plugin->plug, src_channels->area.addr, frames); } else { int channel, channels = plugin->dst_format.channels; void **bufs = (void**)plugin->extra_data; - snd_assert(bufs != NULL, return -ENXIO); + if (snd_BUG_ON(!bufs)) + return -ENXIO; for (channel = 0; channel < channels; channel++) { if (src_channels[channel].enabled) bufs[channel] = src_channels[channel].area.addr; @@ -62,14 +65,17 @@ static snd_pcm_sframes_t io_capture_transfer(struct snd_pcm_plugin *plugin, struct snd_pcm_plugin_channel *dst_channels, snd_pcm_uframes_t frames) { - snd_assert(plugin != NULL, return -ENXIO); - snd_assert(dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin)) + return -ENXIO; + if (snd_BUG_ON(!dst_channels)) + return -ENXIO; if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) { return pcm_read(plugin->plug, dst_channels->area.addr, frames); } else { int channel, channels = plugin->dst_format.channels; void **bufs = (void**)plugin->extra_data; - snd_assert(bufs != NULL, return -ENXIO); + if (snd_BUG_ON(!bufs)) + return -ENXIO; for (channel = 0; channel < channels; channel++) { if (dst_channels[channel].enabled) bufs[channel] = dst_channels[channel].area.addr; @@ -107,9 +113,11 @@ int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format format; struct snd_pcm_plugin *plugin; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(plug != NULL && params != NULL, return -ENXIO); + if (snd_BUG_ON(!plug || !params)) + return -ENXIO; format.format = params_format(params); format.rate = params_rate(params); format.channels = params_channels(params); diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index da3dbd41669..4c1d1682719 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c @@ -92,7 +92,8 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, { struct linear_priv *data; - snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) + return -ENXIO; data = (struct linear_priv *)plugin->extra_data; if (frames == 0) return 0; @@ -100,12 +101,12 @@ static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin, { unsigned int channel; for (channel = 0; channel < plugin->src_format.channels; channel++) { - snd_assert(src_channels[channel].area.first % 8 == 0 && - src_channels[channel].area.step % 8 == 0, - return -ENXIO); - snd_assert(dst_channels[channel].area.first % 8 == 0 && - dst_channels[channel].area.step % 8 == 0, - return -ENXIO); + if (snd_BUG_ON(src_channels[channel].area.first % 8 || + src_channels[channel].area.step % 8)) + return -ENXIO; + if (snd_BUG_ON(dst_channels[channel].area.first % 8 || + dst_channels[channel].area.step % 8)) + return -ENXIO; } } #endif @@ -154,13 +155,17 @@ int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug, struct linear_priv *data; struct snd_pcm_plugin *plugin; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(src_format->channels == dst_format->channels, return -ENXIO); - snd_assert(snd_pcm_format_linear(src_format->format) && - snd_pcm_format_linear(dst_format->format), return -ENXIO); + if (snd_BUG_ON(src_format->rate != dst_format->rate)) + return -ENXIO; + if (snd_BUG_ON(src_format->channels != dst_format->channels)) + return -ENXIO; + if (snd_BUG_ON(!snd_pcm_format_linear(src_format->format) || + !snd_pcm_format_linear(dst_format->format))) + return -ENXIO; err = snd_pcm_plugin_build(plug, "linear format conversion", src_format, dst_format, diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 581aa2c60e6..4690b8b5681 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -257,8 +257,10 @@ static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot) result = pslot->get_volume(fmixer, pslot, &left, &right); if (!pslot->stereo) right = left; - snd_assert(left >= 0 && left <= 100, return -EIO); - snd_assert(right >= 0 && right <= 100, return -EIO); + if (snd_BUG_ON(left < 0 || left > 100)) + return -EIO; + if (snd_BUG_ON(right < 0 || right > 100)) + return -EIO; if (result >= 0) { pslot->volume[0] = left; pslot->volume[1] = right; @@ -298,7 +300,8 @@ static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int int __user *p = argp; int tmp; - snd_assert(fmixer != NULL, return -ENXIO); + if (snd_BUG_ON(!fmixer)) + return -ENXIO; if (((cmd >> 8) & 0xff) == 'M') { switch (cmd) { case SOUND_MIXER_INFO: @@ -368,7 +371,8 @@ int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned l { struct snd_mixer_oss_file fmixer; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; if (card->mixer_oss == NULL) return -ENXIO; memset(&fmixer, 0, sizeof(fmixer)); @@ -1284,9 +1288,11 @@ static int snd_mixer_oss_free1(void *private) struct snd_card *card; int idx; - snd_assert(mixer != NULL, return -ENXIO); + if (!mixer) + return 0; card = mixer->card; - snd_assert(mixer == card->mixer_oss, return -ENXIO); + if (snd_BUG_ON(mixer != card->mixer_oss)) + return -ENXIO; card->mixer_oss = NULL; for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) { struct snd_mixer_oss_slot *chn = &mixer->slots[idx]; diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c index 77f96194a0e..f7649d4d950 100644 --- a/sound/core/oss/mulaw.c +++ b/sound/core/oss/mulaw.c @@ -252,19 +252,20 @@ static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin, { struct mulaw_priv *data; - snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) + return -ENXIO; if (frames == 0) return 0; #ifdef CONFIG_SND_DEBUG { unsigned int channel; for (channel = 0; channel < plugin->src_format.channels; channel++) { - snd_assert(src_channels[channel].area.first % 8 == 0 && - src_channels[channel].area.step % 8 == 0, - return -ENXIO); - snd_assert(dst_channels[channel].area.first % 8 == 0 && - dst_channels[channel].area.step % 8 == 0, - return -ENXIO); + if (snd_BUG_ON(src_channels[channel].area.first % 8 || + src_channels[channel].area.step % 8)) + return -ENXIO; + if (snd_BUG_ON(dst_channels[channel].area.first % 8 || + dst_channels[channel].area.step % 8)) + return -ENXIO; } } #endif @@ -305,11 +306,14 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, struct snd_pcm_plugin_format *format; mulaw_f func; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(src_format->channels == dst_format->channels, return -ENXIO); + if (snd_BUG_ON(src_format->rate != dst_format->rate)) + return -ENXIO; + if (snd_BUG_ON(src_format->channels != dst_format->channels)) + return -ENXIO; if (dst_format->format == SNDRV_PCM_FORMAT_MU_LAW) { format = src_format; @@ -323,7 +327,8 @@ int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug, snd_BUG(); return -EINVAL; } - snd_assert(snd_pcm_format_linear(format->format) != 0, return -ENXIO); + if (snd_BUG_ON(!snd_pcm_format_linear(format->format))) + return -ENXIO; err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion", src_format, dst_format, diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 4c601b192dd..1af62b8b86c 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -452,7 +452,8 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, } else { *params = *save; max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); - snd_assert(max >= 0, return -EINVAL); + if (max < 0) + return max; last = 1; } _end: @@ -461,7 +462,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, v = snd_pcm_hw_param_last(pcm, params, var, dir); else v = snd_pcm_hw_param_first(pcm, params, var, dir); - snd_assert(v >= 0, return -EINVAL); + snd_BUG_ON(v < 0); return v; } @@ -778,7 +779,8 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, while (oss_period_size * oss_periods > oss_buffer_size) oss_period_size /= 2; - snd_assert(oss_period_size >= 16, return -EINVAL); + if (oss_period_size < 16) + return -EINVAL; runtime->oss.period_bytes = oss_period_size; runtime->oss.period_frames = 1; runtime->oss.periods = oss_periods; @@ -895,7 +897,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) } } err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, sformat, 0); - snd_assert(err >= 0, goto failure); + if (err < 0) + goto failure; if (direct) { memcpy(params, sparams, sizeof(*params)); @@ -958,11 +961,13 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); - snd_assert(err >= 0, goto failure); + if (err < 0) + goto failure; err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, runtime->oss.periods, NULL); - snd_assert(err >= 0, goto failure); + if (err < 0) + goto failure; snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); @@ -1006,7 +1011,10 @@ 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); + if (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); @@ -1017,7 +1025,10 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) oss_period_size *= oss_frame_size; oss_buffer_size = oss_period_size * runtime->oss.periods; - snd_assert(oss_buffer_size >= 0, err = -EINVAL; goto failure); + if (oss_buffer_size < 0) { + err = -EINVAL; + goto failure; + } runtime->oss.period_bytes = oss_period_size; runtime->oss.buffer_bytes = oss_buffer_size; @@ -1069,7 +1080,8 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil return err; } } - snd_assert(asubstream != NULL, return -EIO); + if (!asubstream) + return -EIO; if (r_substream) *r_substream = asubstream; return 0; @@ -1764,7 +1776,8 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) err = snd_pcm_hw_refine(substream, params); format_mask = *hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); kfree(params); - snd_assert(err >= 0, return err); + if (err < 0) + return err; for (fmt = 0; fmt < 32; ++fmt) { if (snd_mask_test(&format_mask, fmt)) { int f = snd_pcm_oss_format_to(fmt); @@ -2250,7 +2263,8 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) { int cidx; - snd_assert(pcm_oss_file != NULL, return -ENXIO); + if (!pcm_oss_file) + return 0; for (cidx = 0; cidx < 2; ++cidx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; if (substream) @@ -2271,8 +2285,8 @@ static int snd_pcm_oss_open_file(struct file *file, struct snd_pcm_substream *substream; unsigned int f_mode = file->f_mode; - snd_assert(rpcm_oss_file != NULL, return -EINVAL); - *rpcm_oss_file = NULL; + if (rpcm_oss_file) + *rpcm_oss_file = NULL; pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL); if (pcm_oss_file == NULL) @@ -2312,7 +2326,8 @@ static int snd_pcm_oss_open_file(struct file *file, } file->private_data = pcm_oss_file; - *rpcm_oss_file = pcm_oss_file; + if (rpcm_oss_file) + *rpcm_oss_file = pcm_oss_file; return 0; } @@ -2321,7 +2336,8 @@ static int snd_task_name(struct task_struct *task, char *name, size_t size) { unsigned int idx; - snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL); + if (snd_BUG_ON(!task || !name || size < 2)) + return -EINVAL; for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++) name[idx] = task->comm[idx]; name[idx] = '\0'; @@ -2415,7 +2431,8 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; if (substream == NULL) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; - snd_assert(substream != NULL, return -ENXIO); + if (snd_BUG_ON(!substream)) + return -ENXIO; pcm = substream->pcm; if (!pcm->card->shutdown) snd_pcm_oss_sync(pcm_oss_file); @@ -2448,7 +2465,8 @@ static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long if (substream != NULL) break; } - snd_assert(substream != NULL, return -ENXIO); + if (snd_BUG_ON(idx >= 2)) + return -ENXIO; return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg); } #endif diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index bec94138205..6751daa3bb5 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -62,7 +62,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t if ((width = snd_pcm_format_physical_width(format->format)) < 0) return width; size = frames * format->channels * width; - snd_assert((size % 8) == 0, return -ENXIO); + if (snd_BUG_ON(size % 8)) + return -ENXIO; size /= 8; if (plugin->buf_frames < frames) { vfree(plugin->buf); @@ -84,7 +85,8 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t c->area.step = format->channels * width; } } else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) { - snd_assert((size % format->channels) == 0,); + if (snd_BUG_ON(size % format->channels)) + return -EINVAL; size /= format->channels; for (channel = 0; channel < format->channels; channel++, c++) { c->frames = frames; @@ -102,13 +104,15 @@ static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames) { int err; - snd_assert(snd_pcm_plug_first(plug) != NULL, return -ENXIO); + if (snd_BUG_ON(!snd_pcm_plug_first(plug))) + return -ENXIO; if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) { struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug); while (plugin->next) { if (plugin->dst_frames) frames = plugin->dst_frames(plugin, frames); - snd_assert(frames > 0, return -ENXIO); + if (snd_BUG_ON(frames <= 0)) + return -ENXIO; plugin = plugin->next; err = snd_pcm_plugin_alloc(plugin, frames); if (err < 0) @@ -119,7 +123,8 @@ int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames) while (plugin->prev) { if (plugin->src_frames) frames = plugin->src_frames(plugin, frames); - snd_assert(frames > 0, return -ENXIO); + if (snd_BUG_ON(frames <= 0)) + return -ENXIO; plugin = plugin->prev; err = snd_pcm_plugin_alloc(plugin, frames); if (err < 0) @@ -148,8 +153,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, struct snd_pcm_plugin *plugin; unsigned int channels; - snd_assert(plug != NULL, return -ENXIO); - snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO); + if (snd_BUG_ON(!plug)) + return -ENXIO; + if (snd_BUG_ON(!src_format || !dst_format)) + return -ENXIO; plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL); if (plugin == NULL) return -ENOMEM; @@ -159,10 +166,10 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; plugin->src_format = *src_format; plugin->src_width = snd_pcm_format_physical_width(src_format->format); - snd_assert(plugin->src_width > 0, ); + snd_BUG_ON(plugin->src_width <= 0); plugin->dst_format = *dst_format; plugin->dst_width = snd_pcm_format_physical_width(dst_format->format); - snd_assert(plugin->dst_width > 0, ); + snd_BUG_ON(plugin->dst_width <= 0); if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) channels = src_format->channels; else @@ -194,7 +201,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next; int stream = snd_pcm_plug_stream(plug); - snd_assert(plug != NULL, return -ENXIO); + if (snd_BUG_ON(!plug)) + return -ENXIO; if (drv_frames == 0) return 0; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -224,7 +232,8 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc snd_pcm_sframes_t frames; int stream = snd_pcm_plug_stream(plug); - snd_assert(plug != NULL, return -ENXIO); + if (snd_BUG_ON(!plug)) + return -ENXIO; if (clt_frames == 0) return 0; frames = clt_frames; @@ -540,7 +549,8 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu int width, nchannels, channel; int stream = snd_pcm_plug_stream(plug); - snd_assert(buf != NULL, return -ENXIO); + if (snd_BUG_ON(!buf)) + return -ENXIO; if (stream == SNDRV_PCM_STREAM_PLAYBACK) { plugin = snd_pcm_plug_first(plug); format = &plugin->src_format; @@ -553,7 +563,9 @@ snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plu if ((width = snd_pcm_format_physical_width(format->format)) < 0) return width; nchannels = format->channels; - snd_assert(plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || format->channels <= 1, return -ENXIO); + if (snd_BUG_ON(plugin->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && + format->channels > 1)) + return -ENXIO; for (channel = 0; channel < nchannels; channel++, v++) { v->frames = count; v->enabled = 1; diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index 14dfb3175d8..a466443c4a2 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -185,7 +185,8 @@ static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_ struct rate_priv *data; snd_pcm_sframes_t res; - snd_assert(plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin)) + return -ENXIO; if (frames == 0) return 0; data = (struct rate_priv *)plugin->extra_data; @@ -217,7 +218,8 @@ static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_ struct rate_priv *data; snd_pcm_sframes_t res; - snd_assert(plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin)) + return -ENXIO; if (frames == 0) return 0; data = (struct rate_priv *)plugin->extra_data; @@ -252,19 +254,20 @@ static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames; struct rate_priv *data; - snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) + return -ENXIO; if (frames == 0) return 0; #ifdef CONFIG_SND_DEBUG { unsigned int channel; for (channel = 0; channel < plugin->src_format.channels; channel++) { - snd_assert(src_channels[channel].area.first % 8 == 0 && - src_channels[channel].area.step % 8 == 0, - return -ENXIO); - snd_assert(dst_channels[channel].area.first % 8 == 0 && - dst_channels[channel].area.step % 8 == 0, - return -ENXIO); + if (snd_BUG_ON(src_channels[channel].area.first % 8 || + src_channels[channel].area.step % 8)) + return -ENXIO; + if (snd_BUG_ON(dst_channels[channel].area.first % 8 || + dst_channels[channel].area.step % 8)) + return -ENXIO; } } #endif @@ -281,7 +284,8 @@ static int rate_action(struct snd_pcm_plugin *plugin, enum snd_pcm_plugin_action action, unsigned long udata) { - snd_assert(plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin)) + return -ENXIO; switch (action) { case INIT: case PREPARE: @@ -302,14 +306,20 @@ int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug, struct rate_priv *data; struct snd_pcm_plugin *plugin; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(src_format->channels == dst_format->channels, return -ENXIO); - snd_assert(src_format->channels > 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); + if (snd_BUG_ON(src_format->channels != dst_format->channels)) + return -ENXIO; + if (snd_BUG_ON(src_format->channels <= 0)) + return -ENXIO; + if (snd_BUG_ON(src_format->format != SNDRV_PCM_FORMAT_S16)) + return -ENXIO; + if (snd_BUG_ON(dst_format->format != SNDRV_PCM_FORMAT_S16)) + return -ENXIO; + if (snd_BUG_ON(src_format->rate == dst_format->rate)) + return -ENXIO; err = snd_pcm_plugin_build(plug, "rate conversion", src_format, dst_format, diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index da7ab7a3e82..0dcc2870d53 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c @@ -54,7 +54,8 @@ static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin, struct snd_pcm_plugin_channel *dvp; int format; - snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO); + if (snd_BUG_ON(!plugin || !src_channels || !dst_channels)) + return -ENXIO; if (frames == 0) return 0; @@ -90,10 +91,13 @@ int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug, struct snd_pcm_plugin *plugin; int err; - snd_assert(r_plugin != NULL, return -ENXIO); + if (snd_BUG_ON(!r_plugin)) + return -ENXIO; *r_plugin = NULL; - snd_assert(src_format->rate == dst_format->rate, return -ENXIO); - snd_assert(src_format->format == dst_format->format, return -ENXIO); + if (snd_BUG_ON(src_format->rate != dst_format->rate)) + return -ENXIO; + if (snd_BUG_ON(src_format->format != dst_format->format)) + return -ENXIO; err = snd_pcm_plugin_build(plug, "route conversion", src_format, dst_format, 0, &plugin); diff --git a/sound/core/pcm.c b/sound/core/pcm.c index ece25c718e9..192a433a240 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -42,7 +42,7 @@ static int snd_pcm_dev_free(struct snd_device *device); static int snd_pcm_dev_register(struct snd_device *device); static int snd_pcm_dev_disconnect(struct snd_device *device); -static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) +static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device) { struct snd_pcm *pcm; @@ -53,6 +53,37 @@ static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) return NULL; } +static int snd_pcm_next(struct snd_card *card, int device) +{ + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { + if (pcm->card == card && pcm->device > device) + return pcm->device; + else if (pcm->card->number > card->number) + return -1; + } + return -1; +} + +static int snd_pcm_add(struct snd_pcm *newpcm) +{ + struct snd_pcm *pcm; + + list_for_each_entry(pcm, &snd_pcm_devices, list) { + if (pcm->card == newpcm->card && pcm->device == newpcm->device) + return -EBUSY; + if (pcm->card->number > newpcm->card->number || + (pcm->card == newpcm->card && + pcm->device > newpcm->device)) { + list_add(&newpcm->list, pcm->list.prev); + return 0; + } + } + list_add_tail(&newpcm->list, &snd_pcm_devices); + return 0; +} + static int snd_pcm_control_ioctl(struct snd_card *card, struct snd_ctl_file *control, unsigned int cmd, unsigned long arg) @@ -65,14 +96,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, if (get_user(device, (int __user *)arg)) return -EFAULT; mutex_lock(®ister_mutex); - device = device < 0 ? 0 : device + 1; - while (device < SNDRV_PCM_DEVICES) { - if (snd_pcm_search(card, device)) - break; - device++; - } - if (device == SNDRV_PCM_DEVICES) - device = -1; + device = snd_pcm_next(card, device); mutex_unlock(®ister_mutex); if (put_user(device, (int __user *)arg)) return -EFAULT; @@ -98,7 +122,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, if (get_user(subdevice, &info->subdevice)) return -EFAULT; mutex_lock(®ister_mutex); - pcm = snd_pcm_search(card, device); + pcm = snd_pcm_get(card, device); if (pcm == NULL) { err = -ENXIO; goto _error; @@ -232,7 +256,6 @@ static char *snd_pcm_tstamp_mode_names[] = { static const char *snd_pcm_stream_name(int stream) { - snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL); return snd_pcm_stream_names[stream]; } @@ -248,7 +271,6 @@ static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat) static const char *snd_pcm_tstamp_mode_name(int mode) { - snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL); return snd_pcm_tstamp_mode_names[mode]; } @@ -682,9 +704,10 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, .dev_disconnect = snd_pcm_dev_disconnect, }; - snd_assert(rpcm != NULL, return -EINVAL); - *rpcm = NULL; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; + if (rpcm) + *rpcm = NULL; pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); if (pcm == NULL) { snd_printk(KERN_ERR "Cannot allocate PCM\n"); @@ -708,7 +731,8 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, snd_pcm_free(pcm); return err; } - *rpcm = pcm; + if (rpcm) + *rpcm = pcm; return 0; } @@ -742,7 +766,8 @@ static int snd_pcm_free(struct snd_pcm *pcm) { struct snd_pcm_notify *notify; - snd_assert(pcm != NULL, return -ENXIO); + if (!pcm) + return 0; list_for_each_entry(notify, &snd_pcm_notify_list, list) { notify->n_unregister(pcm); } @@ -773,9 +798,9 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, int prefer_subdevice = -1; size_t size; - snd_assert(rsubstream != NULL, return -EINVAL); + if (snd_BUG_ON(!pcm || !rsubstream)) + return -ENXIO; *rsubstream = NULL; - snd_assert(pcm != NULL, return -ENXIO); pstr = &pcm->streams[stream]; if (pstr->substream == NULL || pstr->substream_count == 0) return -ENODEV; @@ -883,8 +908,9 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; + if (PCM_RUNTIME_CHECK(substream)) + return; runtime = substream->runtime; - snd_assert(runtime != NULL, return); if (runtime->private_free != NULL) runtime->private_free(runtime); snd_free_pages((void*)runtime->status, @@ -929,13 +955,14 @@ static int snd_pcm_dev_register(struct snd_device *device) struct snd_pcm *pcm = device->device_data; struct device *dev; - snd_assert(pcm != NULL && device != NULL, return -ENXIO); + if (snd_BUG_ON(!pcm || !device)) + return -ENXIO; mutex_lock(®ister_mutex); - if (snd_pcm_search(pcm->card, pcm->device)) { + err = snd_pcm_add(pcm); + if (err) { mutex_unlock(®ister_mutex); - return -EBUSY; + return err; } - list_add_tail(&pcm->list, &snd_pcm_devices); for (cidx = 0; cidx < 2; cidx++) { int devtype = -1; if (pcm->streams[cidx].substream == NULL) @@ -1019,10 +1046,11 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) { struct snd_pcm *pcm; - snd_assert(notify != NULL && - notify->n_register != NULL && - notify->n_unregister != NULL && - notify->n_disconnect, return -EINVAL); + if (snd_BUG_ON(!notify || + !notify->n_register || + !notify->n_unregister || + !notify->n_disconnect)) + return -EINVAL; mutex_lock(®ister_mutex); if (nfree) { list_del(¬ify->list); diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 49aa693fba8..36d7a599823 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -397,7 +397,8 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream, snd_pcm_uframes_t boundary; int err; - snd_assert(runtime, return -EINVAL); + if (snd_BUG_ON(!runtime)) + return -EINVAL; if (get_user(sflags, &src->flags) || get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) || diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 1533f0379e9..6ea5cfb8399 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -85,7 +85,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram } frames = runtime->buffer_size - runtime->silence_filled; } - snd_assert(frames <= runtime->buffer_size, return); + if (snd_BUG_ON(frames > runtime->buffer_size)) + return; if (frames == 0) return; ofs = runtime->silence_start % runtime->buffer_size; @@ -96,7 +97,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram if (substream->ops->silence) { int err; err = substream->ops->silence(substream, -1, ofs, transfer); - snd_assert(err >= 0, ); + snd_BUG_ON(err < 0); } else { char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs); snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels); @@ -108,7 +109,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram for (c = 0; c < channels; ++c) { int err; err = substream->ops->silence(substream, c, ofs, transfer); - snd_assert(err >= 0, ); + snd_BUG_ON(err < 0); } } else { size_t dma_csize = runtime->dma_bytes / channels; @@ -354,7 +355,7 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, { u_int64_t n = (u_int64_t) a * b; if (c == 0) { - snd_assert(n > 0, ); + snd_BUG_ON(!n); *r = 0; return UINT_MAX; } @@ -380,7 +381,8 @@ static inline unsigned int muldiv32(unsigned int a, unsigned int b, int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v) { int changed = 0; - snd_assert(!snd_interval_empty(i), return -EINVAL); + if (snd_BUG_ON(snd_interval_empty(i))) + return -EINVAL; if (i->min < v->min) { i->min = v->min; i->openmin = v->openmin; @@ -423,7 +425,8 @@ EXPORT_SYMBOL(snd_interval_refine); static int snd_interval_refine_first(struct snd_interval *i) { - snd_assert(!snd_interval_empty(i), return -EINVAL); + if (snd_BUG_ON(snd_interval_empty(i))) + return -EINVAL; if (snd_interval_single(i)) return 0; i->max = i->min; @@ -435,7 +438,8 @@ static int snd_interval_refine_first(struct snd_interval *i) static int snd_interval_refine_last(struct snd_interval *i) { - snd_assert(!snd_interval_empty(i), return -EINVAL); + if (snd_BUG_ON(snd_interval_empty(i))) + return -EINVAL; if (snd_interval_single(i)) return 0; i->min = i->max; @@ -889,7 +893,8 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, c->private = private; k = 0; while (1) { - snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL); + if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) + return -EINVAL; c->deps[k++] = dep; if (dep < 0) break; @@ -1285,7 +1290,8 @@ int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, return changed; if (params->rmask) { int err = snd_pcm_hw_refine(pcm, params); - snd_assert(err >= 0, return err); + if (snd_BUG_ON(err < 0)) + return err; } return snd_pcm_hw_param_value(params, var, dir); } @@ -1330,7 +1336,8 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, return changed; if (params->rmask) { int err = snd_pcm_hw_refine(pcm, params); - snd_assert(err >= 0, return err); + if (snd_BUG_ON(err < 0)) + return err; } return snd_pcm_hw_param_value(params, var, dir); } @@ -1368,7 +1375,8 @@ int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, err = snd_pcm_hw_param_first(pcm, params, *v, NULL); else err = snd_pcm_hw_param_last(pcm, params, *v, NULL); - snd_assert(err >= 0, return err); + if (snd_BUG_ON(err < 0)) + return err; } return 0; } @@ -1466,9 +1474,9 @@ void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime; unsigned long flags; - snd_assert(substream != NULL, return); + if (PCM_RUNTIME_CHECK(substream)) + return; runtime = substream->runtime; - snd_assert(runtime != NULL, return); if (runtime->transfer_ack_begin) runtime->transfer_ack_begin(substream); @@ -1567,7 +1575,6 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, return err; } else { char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); - snd_assert(runtime->dma_area, return -EFAULT); if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) return -EFAULT; } @@ -1629,7 +1636,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; if (frames > cont) frames = cont; - snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); + if (snd_BUG_ON(!frames)) { + snd_pcm_stream_unlock_irq(substream); + return -EINVAL; + } appl_ptr = runtime->control->appl_ptr; appl_ofs = appl_ptr % runtime->buffer_size; snd_pcm_stream_unlock_irq(substream); @@ -1669,18 +1679,30 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } -snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) +/* sanity-check for read/write methods */ +static int pcm_sanity_check(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; - int nonblock; - - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); - snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); + if (snd_BUG_ON(!substream->ops->copy && !runtime->dma_area)) + return -EINVAL; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; + return 0; +} + +snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) +{ + struct snd_pcm_runtime *runtime; + int nonblock; + int err; + err = pcm_sanity_check(substream); + if (err < 0) + return err; + runtime = substream->runtime; nonblock = !!(substream->f_flags & O_NONBLOCK); if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED && @@ -1703,7 +1725,8 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, int channels = runtime->channels; int c; if (substream->ops->copy) { - snd_assert(substream->ops->silence != NULL, return -EINVAL); + if (snd_BUG_ON(!substream->ops->silence)) + return -EINVAL; for (c = 0; c < channels; ++c, ++bufs) { if (*bufs == NULL) { if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0) @@ -1717,7 +1740,6 @@ static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, } else { /* default transfer behaviour */ size_t dma_csize = runtime->dma_bytes / channels; - snd_assert(runtime->dma_area, return -EFAULT); for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); if (*bufs == NULL) { @@ -1738,14 +1760,12 @@ snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime; int nonblock; + int err; - snd_assert(substream != NULL, return -ENXIO); + err = pcm_sanity_check(substream); + if (err < 0) + return err; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); - snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - nonblock = !!(substream->f_flags & O_NONBLOCK); if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) @@ -1769,7 +1789,6 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, return err; } else { char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff); - snd_assert(runtime->dma_area, return -EFAULT); if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) return -EFAULT; } @@ -1841,7 +1860,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size; if (frames > cont) frames = cont; - snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL); + if (snd_BUG_ON(!frames)) { + snd_pcm_stream_unlock_irq(substream); + return -EINVAL; + } appl_ptr = runtime->control->appl_ptr; appl_ofs = appl_ptr % runtime->buffer_size; snd_pcm_stream_unlock_irq(substream); @@ -1879,14 +1901,12 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u { struct snd_pcm_runtime *runtime; int nonblock; + int err; - snd_assert(substream != NULL, return -ENXIO); + err = pcm_sanity_check(substream); + if (err < 0) + return err; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); - snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - nonblock = !!(substream->f_flags & O_NONBLOCK); if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED) return -EINVAL; @@ -1916,7 +1936,6 @@ static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, } } else { snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; - snd_assert(runtime->dma_area, return -EFAULT); for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf; char __user *buf; @@ -1938,11 +1957,12 @@ snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime; int nonblock; + int err; - snd_assert(substream != NULL, return -ENXIO); + err = pcm_sanity_check(substream); + if (err < 0) + return err; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); - snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL); if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index ff07b4a9992..a6d42808828 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -50,8 +50,6 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz struct snd_dma_buffer *dmab = &substream->dma_buffer; int err; - snd_assert(size > 0, return -EINVAL); - /* already reserved? */ if (snd_dma_get_reserved_buf(dmab, substream->dma_buf_id) > 0) { if (dmab->bytes >= size) @@ -326,6 +324,32 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigne EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page); +/* + * compute the max chunk size with continuous pages on sg-buffer + */ +unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, + unsigned int ofs, unsigned int size) +{ + struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream); + unsigned int start, end, pg; + + start = ofs >> PAGE_SHIFT; + end = (ofs + size - 1) >> PAGE_SHIFT; + /* check page continuity */ + pg = sg->table[start].addr >> PAGE_SHIFT; + for (;;) { + start++; + if (start > end) + break; + pg++; + if ((sg->table[start].addr >> PAGE_SHIFT) != pg) + return (start << PAGE_SHIFT) - ofs; + } + /* ok, all on continuous pages */ + return size; +} +EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size); + /** * snd_pcm_lib_malloc_pages - allocate the DMA buffer * @substream: the substream to allocate the DMA buffer to @@ -342,10 +366,12 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) struct snd_pcm_runtime *runtime; struct snd_dma_buffer *dmab = NULL; - snd_assert(substream->dma_buffer.dev.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL); - snd_assert(substream != NULL, return -EINVAL); + if (PCM_RUNTIME_CHECK(substream)) + return -EINVAL; + if (snd_BUG_ON(substream->dma_buffer.dev.type == + SNDRV_DMA_TYPE_UNKNOWN)) + return -EINVAL; runtime = substream->runtime; - snd_assert(runtime != NULL, return -EINVAL); if (runtime->dma_buffer_p) { /* perphaps, we might free the large DMA memory region @@ -391,9 +417,9 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; - snd_assert(substream != NULL, return -EINVAL); + if (PCM_RUNTIME_CHECK(substream)) + return -EINVAL; runtime = substream->runtime; - snd_assert(runtime != NULL, return -EINVAL); if (runtime->dma_area == NULL) return 0; if (runtime->dma_buffer_p != &substream->dma_buffer) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c487025d345..e61e12506de 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -95,7 +95,6 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) struct snd_pcm *pcm = substream->pcm; struct snd_pcm_str *pstr = substream->pstr; - snd_assert(substream != NULL, return -ENXIO); memset(info, 0, sizeof(*info)); info->card = pcm->card->number; info->device = pcm->device; @@ -370,9 +369,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, unsigned int bits; snd_pcm_uframes_t frames; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); snd_pcm_stream_lock_irq(substream); switch (runtime->status->state) { case SNDRV_PCM_STATE_OPEN: @@ -490,9 +489,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime; int result = 0; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); snd_pcm_stream_lock_irq(substream); switch (runtime->status->state) { case SNDRV_PCM_STATE_SETUP: @@ -518,9 +517,9 @@ static int snd_pcm_sw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - snd_assert(runtime != NULL, return -ENXIO); snd_pcm_stream_lock_irq(substream); if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { snd_pcm_stream_unlock_irq(substream); @@ -622,11 +621,8 @@ static int snd_pcm_status_user(struct snd_pcm_substream *substream, struct snd_pcm_status __user * _status) { struct snd_pcm_status status; - struct snd_pcm_runtime *runtime; int res; - snd_assert(substream != NULL, return -ENXIO); - runtime = substream->runtime; memset(&status, 0, sizeof(status)); res = snd_pcm_status(substream, &status); if (res < 0) @@ -642,7 +638,6 @@ static int snd_pcm_channel_info(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime; unsigned int channel; - snd_assert(substream != NULL, return -ENXIO); channel = info->channel; runtime = substream->runtime; snd_pcm_stream_lock_irq(substream); @@ -1250,7 +1245,6 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state) int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL); if (err < 0) return err; - // snd_assert(runtime->status->hw_ptr < runtime->buffer_size, ); runtime->hw_ptr_base = 0; runtime->hw_ptr_interrupt = runtime->status->hw_ptr - runtime->status->hw_ptr % runtime->period_size; @@ -1421,7 +1415,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) int i, num_drecs; struct drain_rec *drec, drec_tmp, *d; - snd_assert(substream != NULL, return -ENXIO); card = substream->pcm->card; runtime = substream->runtime; @@ -1541,7 +1534,8 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream) struct snd_card *card; int result = 0; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; card = substream->pcm->card; @@ -1934,33 +1928,41 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX; } err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, hw->channels_min, hw->channels_max); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, hw->rate_min, hw->rate_max); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, hw->period_bytes_min, hw->period_bytes_max); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS, hw->periods_min, hw->periods_max); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, hw->period_bytes_min, hw->buffer_bytes_max); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return err; err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, snd_pcm_hw_rule_buffer_bytes_max, substream, @@ -1971,7 +1973,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) /* FIXME: remove */ if (runtime->dma_bytes) { err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes); - snd_assert(err >= 0, return -EINVAL); + if (err < 0) + return -EINVAL; } if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) { @@ -2067,8 +2070,8 @@ static int snd_pcm_open_file(struct file *file, struct snd_pcm_str *str; int err; - snd_assert(rpcm_file != NULL, return -EINVAL); - *rpcm_file = NULL; + if (rpcm_file) + *rpcm_file = NULL; err = snd_pcm_open_substream(pcm, stream, file, &substream); if (err < 0) @@ -2086,7 +2089,8 @@ static int snd_pcm_open_file(struct file *file, substream->pcm_release = pcm_release_private; } file->private_data = pcm_file; - *rpcm_file = pcm_file; + if (rpcm_file) + *rpcm_file = pcm_file; return 0; } @@ -2170,7 +2174,8 @@ static int snd_pcm_release(struct inode *inode, struct file *file) pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (snd_BUG_ON(!substream)) + return -ENXIO; pcm = substream->pcm; fasync_helper(-1, file, 0, &substream->runtime->fasync); mutex_lock(&pcm->open_mutex); @@ -2493,8 +2498,6 @@ static int snd_pcm_common_ioctl1(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { - snd_assert(substream != NULL, return -ENXIO); - switch (cmd) { case SNDRV_PCM_IOCTL_PVERSION: return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; @@ -2563,8 +2566,10 @@ static int snd_pcm_playback_ioctl1(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { - snd_assert(substream != NULL, return -ENXIO); - snd_assert(substream->stream == SNDRV_PCM_STREAM_PLAYBACK, return -EINVAL); + if (snd_BUG_ON(!substream)) + return -ENXIO; + if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) + return -EINVAL; switch (cmd) { case SNDRV_PCM_IOCTL_WRITEI_FRAMES: { @@ -2643,8 +2648,10 @@ static int snd_pcm_capture_ioctl1(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { - snd_assert(substream != NULL, return -ENXIO); - snd_assert(substream->stream == SNDRV_PCM_STREAM_CAPTURE, return -EINVAL); + if (snd_BUG_ON(!substream)) + return -ENXIO; + if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) + return -EINVAL; switch (cmd) { case SNDRV_PCM_IOCTL_READI_FRAMES: { @@ -2783,7 +2790,8 @@ static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; @@ -2806,21 +2814,17 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf, pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, result = -ENXIO; goto end); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { - result = -EBADFD; - goto end; - } - if (!frame_aligned(runtime, count)) { - result = -EINVAL; - goto end; - } + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + if (!frame_aligned(runtime, count)) + return -EINVAL; count = bytes_to_frames(runtime, count); result = snd_pcm_lib_write(substream, buf, count); if (result > 0) result = frames_to_bytes(runtime, result); - end: return result; } @@ -2838,7 +2842,8 @@ static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov, pcm_file = iocb->ki_filp->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; @@ -2872,17 +2877,14 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, pcm_file = iocb->ki_filp->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, result = -ENXIO; goto end); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { - result = -EBADFD; - goto end; - } + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; if (nr_segs > 128 || nr_segs != runtime->channels || - !frame_aligned(runtime, iov->iov_len)) { - result = -EINVAL; - goto end; - } + !frame_aligned(runtime, iov->iov_len)) + return -EINVAL; frames = bytes_to_samples(runtime, iov->iov_len); bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL); if (bufs == NULL) @@ -2893,7 +2895,6 @@ static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov, if (result > 0) result = frames_to_bytes(runtime, result); kfree(bufs); - end: return result; } @@ -2908,7 +2909,8 @@ static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait) pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; poll_wait(file, &runtime->sleep, wait); @@ -2946,7 +2948,8 @@ static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait) pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; runtime = substream->runtime; poll_wait(file, &runtime->sleep, wait); @@ -3016,7 +3019,6 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file if (!(area->vm_flags & VM_READ)) return -EINVAL; runtime = substream->runtime; - snd_assert(runtime != NULL, return -EAGAIN); size = area->vm_end - area->vm_start; if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status))) return -EINVAL; @@ -3056,7 +3058,6 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file if (!(area->vm_flags & VM_READ)) return -EINVAL; runtime = substream->runtime; - snd_assert(runtime != NULL, return -EAGAIN); size = area->vm_end - area->vm_start; if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control))) return -EINVAL; @@ -3188,7 +3189,6 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, return -EINVAL; } runtime = substream->runtime; - snd_assert(runtime != NULL, return -EAGAIN); if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) @@ -3220,7 +3220,8 @@ static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area) pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, return -ENXIO); + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; offset = area->vm_pgoff << PAGE_SHIFT; switch (offset) { @@ -3248,9 +3249,9 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) lock_kernel(); pcm_file = file->private_data; substream = pcm_file->substream; - snd_assert(substream != NULL, goto out); + if (PCM_RUNTIME_CHECK(substream)) + goto out; runtime = substream->runtime; - err = fasync_helper(fd, file, on, &runtime->fasync); out: unlock_kernel(); @@ -3384,6 +3385,17 @@ out: } #endif /* CONFIG_SND_SUPPORT_OLD_API */ +#ifndef CONFIG_MMU +unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + return 0; +} +#else +# define dummy_get_unmapped_area NULL +#endif + /* * Register section */ @@ -3400,6 +3412,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, + .get_unmapped_area = dummy_get_unmapped_area, }, { .owner = THIS_MODULE, @@ -3412,5 +3425,6 @@ const struct file_operations snd_pcm_f_ops[2] = { .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, + .get_unmapped_area = dummy_get_unmapped_area, } }; diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c index 033a024d153..2c89c04f291 100644 --- a/sound/core/pcm_timer.c +++ b/sound/core/pcm_timer.c @@ -51,12 +51,14 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) mult = 1000000000; rate = runtime->rate; - snd_assert(rate != 0, return); + if (snd_BUG_ON(!rate)) + return; l = gcd(mult, rate); mult /= l; rate /= l; fsize = runtime->period_size; - snd_assert(fsize != 0, return); + if (snd_BUG_ON(!fsize)) + return; l = gcd(rate, fsize); rate /= l; fsize /= l; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index b917a9f981c..c4995c9f573 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -470,8 +470,8 @@ int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile) struct snd_rawmidi_substream *substream; struct snd_rawmidi_runtime *runtime; - snd_assert(rfile != NULL, return -ENXIO); - snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO); + if (snd_BUG_ON(!rfile)) + return -ENXIO; rmidi = rfile->rmidi; mutex_lock(&rmidi->open_mutex); if (rfile->input != NULL) { @@ -1100,7 +1100,7 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count) return -EINVAL; } spin_lock_irqsave(&runtime->lock, flags); - snd_assert(runtime->avail + count <= runtime->buffer_size, ); + snd_BUG_ON(runtime->avail + count > runtime->buffer_size); runtime->hw_ptr += count; runtime->hw_ptr %= runtime->buffer_size; runtime->avail += count; @@ -1141,8 +1141,10 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream, long count1, result; struct snd_rawmidi_runtime *runtime = substream->runtime; - snd_assert(kernelbuf != NULL || userbuf != NULL, return -EINVAL); - snd_assert(runtime->buffer != NULL, return -EINVAL); + if (snd_BUG_ON(!kernelbuf && !userbuf)) + return -EINVAL; + if (snd_BUG_ON(!runtime->buffer)) + return -EINVAL; result = 0; spin_lock_irqsave(&runtime->lock, flags); @@ -1420,9 +1422,10 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, .dev_disconnect = snd_rawmidi_dev_disconnect, }; - snd_assert(rrawmidi != NULL, return -EINVAL); - *rrawmidi = NULL; - snd_assert(card != NULL, return -ENXIO); + if (snd_BUG_ON(!card)) + return -ENXIO; + if (rrawmidi) + *rrawmidi = NULL; rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); if (rmidi == NULL) { snd_printk(KERN_ERR "rawmidi: cannot allocate\n"); @@ -1455,7 +1458,8 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, snd_rawmidi_free(rmidi); return err; } - *rrawmidi = rmidi; + if (rrawmidi) + *rrawmidi = rmidi; return 0; } @@ -1472,7 +1476,8 @@ static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream) static int snd_rawmidi_free(struct snd_rawmidi *rmidi) { - snd_assert(rmidi != NULL, return -ENXIO); + if (!rmidi) + return 0; snd_info_free_entry(rmidi->proc_entry); rmidi->proc_entry = NULL; diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index 97b30fb4c36..51e64e30dd3 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c @@ -91,7 +91,8 @@ static int rtctimer_start(struct snd_timer *timer) { rtc_task_t *rtc = timer->private_data; - snd_assert(rtc != NULL, return -EINVAL); + if (snd_BUG_ON(!rtc)) + return -EINVAL; rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); rtc_control(rtc, RTC_PIE_ON, 0); return 0; @@ -101,7 +102,8 @@ static int rtctimer_stop(struct snd_timer *timer) { rtc_task_t *rtc = timer->private_data; - snd_assert(rtc != NULL, return -EINVAL); + if (snd_BUG_ON(!rtc)) + return -EINVAL; rtc_control(rtc, RTC_PIE_OFF, 0); return 0; } diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index 777796e9449..f25e3cc7ddf 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c @@ -164,7 +164,8 @@ odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_read(dp, buf, count); } @@ -174,7 +175,8 @@ odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offs { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_write(dp, buf, count, file); } @@ -183,7 +185,8 @@ odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return -EIO); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_ioctl(dp, cmd, arg); } @@ -198,7 +201,8 @@ odev_poll(struct file *file, poll_table * wait) { struct seq_oss_devinfo *dp; dp = file->private_data; - snd_assert(dp != NULL, return 0); + if (snd_BUG_ON(!dp)) + return -ENXIO; return snd_seq_oss_poll(dp, file, wait); } diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index e024e4588b8..945a27c34a9 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -308,7 +308,8 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp) struct seq_oss_synth *rec; struct seq_oss_synthinfo *info; - snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return); + if (snd_BUG_ON(dp->max_synthdev >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS)) + return; for (i = 0; i < dp->max_synthdev; i++) { info = &dp->synths[i]; if (! info->opened) @@ -402,7 +403,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev) struct seq_oss_synth *rec; struct seq_oss_synthinfo *info; - snd_assert(dev >= 0 && dev < dp->max_synthdev, return); + if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev)) + return; info = &dp->synths[dev]; if (! info->opened) return; diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 7a1545d2d95..8ca2be339f3 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -266,7 +266,8 @@ static int seq_free_client1(struct snd_seq_client *client) { unsigned long flags; - snd_assert(client != NULL, return -EINVAL); + if (!client) + return 0; snd_seq_delete_all_ports(client); snd_seq_queue_client_leave(client->number); spin_lock_irqsave(&clients_lock, flags); @@ -403,7 +404,8 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, return -EFAULT; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if (!client->accept_input || (fifo = client->data.user.fifo) == NULL) return -ENXIO; @@ -825,7 +827,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop) struct snd_seq_client *client; int result; - snd_assert(cell != NULL, return -EINVAL); + if (snd_BUG_ON(!cell)) + return -EINVAL; client = snd_seq_client_use_ptr(cell->event.source.client); if (client == NULL) { @@ -994,7 +997,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf, return -ENXIO; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if (!client->accept_output || client->pool == NULL) return -ENXIO; @@ -1076,7 +1080,8 @@ static unsigned int snd_seq_poll(struct file *file, poll_table * wait) unsigned int mask = 0; /* check client structures are in place */ - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; if ((snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT) && client->data.user.fifo) { @@ -2195,7 +2200,8 @@ static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg { struct snd_seq_client *client = file->private_data; - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; return snd_seq_do_ioctl(client, cmd, (void __user *) arg); } @@ -2216,7 +2222,8 @@ int snd_seq_create_kernel_client(struct snd_card *card, int client_index, struct snd_seq_client *client; va_list args; - snd_assert(! in_interrupt(), return -EBUSY); + if (snd_BUG_ON(in_interrupt())) + return -EBUSY; if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD) return -EINVAL; @@ -2265,7 +2272,8 @@ int snd_seq_delete_kernel_client(int client) { struct snd_seq_client *ptr; - snd_assert(! in_interrupt(), return -EBUSY); + if (snd_BUG_ON(in_interrupt())) + return -EBUSY; ptr = clientptr(client); if (ptr == NULL) @@ -2288,7 +2296,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev, struct snd_seq_client *cptr; int result; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; if (ev->type == SNDRV_SEQ_EVENT_NONE) return 0; /* ignore this */ @@ -2354,7 +2363,8 @@ int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev, struct snd_seq_client *cptr; int result; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; /* fill in client number */ ev->queue = SNDRV_SEQ_QUEUE_DIRECT; diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index 9628c06e4ea..38693f47c26 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c @@ -92,7 +92,8 @@ static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned l struct snd_seq_client *client = file->private_data; void __user *argp = compat_ptr(arg); - snd_assert(client != NULL, return -ENXIO); + if (snd_BUG_ON(!client)) + return -ENXIO; switch (cmd) { case SNDRV_SEQ_IOCTL_PVERSION: diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c index 05410e536a4..1f997675c89 100644 --- a/sound/core/seq/seq_device.c +++ b/sound/core/seq/seq_device.c @@ -187,7 +187,8 @@ int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, if (result) *result = NULL; - snd_assert(id != NULL, return -EINVAL); + if (snd_BUG_ON(!id)) + return -EINVAL; ops = find_driver(id, 1); if (ops == NULL) @@ -232,7 +233,8 @@ static int snd_seq_device_free(struct snd_seq_device *dev) { struct ops_list *ops; - snd_assert(dev != NULL, return -EINVAL); + if (snd_BUG_ON(!dev)) + return -EINVAL; ops = find_driver(dev->id, 0); if (ops == NULL) diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 3a94ed021bd..0d75afa786b 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -65,9 +65,11 @@ void snd_seq_fifo_delete(struct snd_seq_fifo **fifo) { struct snd_seq_fifo *f; - snd_assert(fifo != NULL, return); + if (snd_BUG_ON(!fifo)) + return; f = *fifo; - snd_assert(f != NULL, return); + if (snd_BUG_ON(!f)) + return; *fifo = NULL; snd_seq_fifo_clear(f); @@ -116,7 +118,8 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f, unsigned long flags; int err; - snd_assert(f != NULL, return -EINVAL); + if (snd_BUG_ON(!f)) + return -EINVAL; snd_use_lock_use(&f->use_lock); err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ @@ -174,7 +177,8 @@ int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, unsigned long flags; wait_queue_t wait; - snd_assert(f != NULL, return -EINVAL); + if (snd_BUG_ON(!f)) + return -EINVAL; *cellp = NULL; init_waitqueue_entry(&wait, current); @@ -233,7 +237,8 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize) struct snd_seq_pool *newpool, *oldpool; struct snd_seq_event_cell *cell, *next, *oldhead; - snd_assert(f != NULL && f->pool != NULL, return -EINVAL); + if (snd_BUG_ON(!f || !f->pool)) + return -EINVAL; /* allocate new pool */ newpool = snd_seq_pool_new(poolsize); diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index 0cf6ac47731..7fb55436287 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -187,9 +187,11 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) unsigned long flags; struct snd_seq_pool *pool; - snd_assert(cell != NULL, return); + if (snd_BUG_ON(!cell)) + return; pool = cell->pool; - snd_assert(pool != NULL, return); + if (snd_BUG_ON(!pool)) + return; spin_lock_irqsave(&pool->lock, flags); free_cell(pool, cell); @@ -378,7 +380,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) struct snd_seq_event_cell *cellptr; unsigned long flags; - snd_assert(pool != NULL, return -EINVAL); + if (snd_BUG_ON(!pool)) + return -EINVAL; if (pool->ptr) /* should be atomic? */ return 0; @@ -414,7 +417,8 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) struct snd_seq_event_cell *ptr; int max_count = 5 * HZ; - snd_assert(pool != NULL, return -EINVAL); + if (snd_BUG_ON(!pool)) + return -EINVAL; /* wait for closing all threads */ spin_lock_irqsave(&pool->lock, flags); diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 99b35360c50..4d26146a62c 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -116,7 +116,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i struct snd_rawmidi_runtime *runtime; int tmp; - snd_assert(substream != NULL || buf != NULL, return -EINVAL); + if (snd_BUG_ON(!substream || !buf)) + return -EINVAL; runtime = substream->runtime; if ((tmp = runtime->avail) < count) { snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); @@ -135,7 +136,8 @@ static int event_process_midi(struct snd_seq_event *ev, int direct, struct snd_rawmidi_substream *substream; int len; - snd_assert(msynth != NULL, return -EINVAL); + if (snd_BUG_ON(!msynth)) + return -EINVAL; substream = msynth->output_rfile.output; if (substream == NULL) return -ENODEV; @@ -210,7 +212,8 @@ static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscri int err; struct seq_midisynth *msynth = private_data; - snd_assert(msynth->input_rfile.input != NULL, return -EINVAL); + if (snd_BUG_ON(!msynth->input_rfile.input)) + return -EINVAL; err = snd_rawmidi_kernel_release(&msynth->input_rfile); return err; } @@ -247,7 +250,8 @@ static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *in struct seq_midisynth *msynth = private_data; unsigned char buf = 0xff; /* MIDI reset */ - snd_assert(msynth->output_rfile.output != NULL, return -EINVAL); + if (snd_BUG_ON(!msynth->output_rfile.output)) + return -EINVAL; /* sending single MIDI reset message to shut the device up */ snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1); snd_rawmidi_drain_output(msynth->output_rfile.output); @@ -285,7 +289,8 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) int device = dev->device; unsigned int input_count = 0, output_count = 0; - snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL); + if (snd_BUG_ON(!card || device < 0 || device >= SNDRV_RAWMIDI_DEVICES)) + return -EINVAL; info = kmalloc(sizeof(*info), GFP_KERNEL); if (! info) return -ENOMEM; diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 1c32a53d6bd..3bf7d73ac52 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -130,7 +130,8 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int num = -1; /* sanity check */ - snd_assert(client, return NULL); + if (snd_BUG_ON(!client)) + return NULL; if (client->num_ports >= SNDRV_SEQ_MAX_PORTS - 1) { snd_printk(KERN_WARNING "too many ports for client %d\n", client->number); @@ -268,8 +269,8 @@ static int port_delete(struct snd_seq_client *client, if (port->private_free) port->private_free(port->private_data); - snd_assert(port->c_src.count == 0,); - snd_assert(port->c_dest.count == 0,); + snd_BUG_ON(port->c_src.count != 0); + snd_BUG_ON(port->c_dest.count != 0); kfree(port); return 0; @@ -336,7 +337,8 @@ int snd_seq_delete_all_ports(struct snd_seq_client *client) int snd_seq_set_port_info(struct snd_seq_client_port * port, struct snd_seq_port_info * info) { - snd_assert(port && info, return -EINVAL); + if (snd_BUG_ON(!port || !info)) + return -EINVAL; /* set port name */ if (info->name[0]) @@ -365,7 +367,8 @@ int snd_seq_set_port_info(struct snd_seq_client_port * port, int snd_seq_get_port_info(struct snd_seq_client_port * port, struct snd_seq_port_info * info) { - snd_assert(port && info, return -EINVAL); + if (snd_BUG_ON(!port || !info)) + return -EINVAL; /* get port name */ strlcpy(info->name, port->name, sizeof(info->name)); diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c index 85969db576c..0101a8b99b7 100644 --- a/sound/core/seq/seq_prioq.c +++ b/sound/core/seq/seq_prioq.c @@ -153,8 +153,8 @@ int snd_seq_prioq_cell_in(struct snd_seq_prioq * f, int count; int prior; - snd_assert(f, return -EINVAL); - snd_assert(cell, return -EINVAL); + if (snd_BUG_ON(!f || !cell)) + return -EINVAL; /* check flags */ prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK); diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 4a48c6ee8ee..e7a8e9e4edb 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -315,7 +315,8 @@ int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop) int dest, err; struct snd_seq_queue *q; - snd_assert(cell != NULL, return -EINVAL); + if (snd_BUG_ON(!cell)) + return -EINVAL; dest = cell->event.queue; /* destination queue */ q = queueptr(dest); if (q == NULL) @@ -734,7 +735,8 @@ int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop) { struct snd_seq_queue *q; - snd_assert(ev != NULL, return -EINVAL); + if (snd_BUG_ON(!ev)) + return -EINVAL; q = queueptr(ev->data.queue.queue); if (q == NULL) diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index d8fcd62e400..f745c317d6a 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -173,7 +173,8 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tempo <= 0) return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); @@ -190,7 +191,8 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (ppq <= 0) return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); @@ -214,7 +216,8 @@ int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; spin_lock_irqsave(&tmr->lock, flags); tmr->tick.cur_tick = position; @@ -229,7 +232,8 @@ int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; snd_seq_sanity_real_time(&position); spin_lock_irqsave(&tmr->lock, flags); @@ -244,7 +248,8 @@ int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, { unsigned long flags; - snd_assert(tmr, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; /* FIXME */ if (base != SKEW_BASE) { @@ -265,7 +270,8 @@ int snd_seq_timer_open(struct snd_seq_queue *q) int err; tmr = q->timer; - snd_assert(tmr != NULL, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tmr->timeri) return -EBUSY; sprintf(str, "sequencer queue %i", q->queue); @@ -302,7 +308,8 @@ int snd_seq_timer_close(struct snd_seq_queue *q) struct snd_seq_timer *tmr; tmr = q->timer; - snd_assert(tmr != NULL, return -EINVAL); + if (snd_BUG_ON(!tmr)) + return -EINVAL; if (tmr->timeri) { snd_timer_stop(tmr->timeri); snd_timer_close(tmr->timeri); @@ -328,7 +335,8 @@ static int initialize_timer(struct snd_seq_timer *tmr) unsigned long freq; t = tmr->timeri->timer; - snd_assert(t, return -EINVAL); + if (snd_BUG_ON(!t)) + return -EINVAL; freq = tmr->preferred_resolution; if (!freq) diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index cefd228cd2a..d4564edd61d 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c @@ -41,9 +41,11 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { + if (!(sgbuf->table[i].addr & ~PAGE_MASK)) + continue; /* continuous pages */ tmpb.area = sgbuf->table[i].buf; - tmpb.addr = sgbuf->table[i].addr; - tmpb.bytes = PAGE_SIZE; + tmpb.addr = sgbuf->table[i].addr & PAGE_MASK; + tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; snd_dma_free_pages(&tmpb); } if (dmab->area) @@ -58,13 +60,17 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) return 0; } +#define MAX_ALLOC_PAGES 32 + void *snd_malloc_sgbuf_pages(struct device *device, size_t size, struct snd_dma_buffer *dmab, size_t *res_size) { struct snd_sg_buf *sgbuf; - unsigned int i, pages; + unsigned int i, pages, chunk, maxpages; struct snd_dma_buffer tmpb; + struct snd_sg_page *table; + struct page **pgtable; dmab->area = NULL; dmab->addr = 0; @@ -74,31 +80,55 @@ void *snd_malloc_sgbuf_pages(struct device *device, sgbuf->dev = device; pages = snd_sgbuf_aligned_pages(size); sgbuf->tblsize = sgbuf_align_table(pages); - sgbuf->table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->table), GFP_KERNEL); - if (! sgbuf->table) + table = kcalloc(sgbuf->tblsize, sizeof(*table), GFP_KERNEL); + if (!table) goto _failed; - sgbuf->page_table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->page_table), GFP_KERNEL); - if (! sgbuf->page_table) + sgbuf->table = table; + pgtable = kcalloc(sgbuf->tblsize, sizeof(*pgtable), GFP_KERNEL); + if (!pgtable) goto _failed; + sgbuf->page_table = pgtable; - /* allocate each page */ - for (i = 0; i < pages; i++) { - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, device, PAGE_SIZE, &tmpb) < 0) { - if (res_size == NULL) + /* allocate pages */ + maxpages = MAX_ALLOC_PAGES; + while (pages > 0) { + chunk = pages; + /* don't be too eager to take a huge chunk */ + if (chunk > maxpages) + chunk = maxpages; + chunk <<= PAGE_SHIFT; + if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device, + chunk, &tmpb) < 0) { + if (!sgbuf->pages) + return NULL; + if (!res_size) goto _failed; - *res_size = size = sgbuf->pages * PAGE_SIZE; + size = sgbuf->pages * PAGE_SIZE; break; } - sgbuf->table[i].buf = tmpb.area; - sgbuf->table[i].addr = tmpb.addr; - sgbuf->page_table[i] = virt_to_page(tmpb.area); - sgbuf->pages++; + chunk = tmpb.bytes >> PAGE_SHIFT; + for (i = 0; i < chunk; i++) { + table->buf = tmpb.area; + table->addr = tmpb.addr; + if (!i) + table->addr |= chunk; /* mark head */ + table++; + *pgtable++ = virt_to_page(tmpb.area); + tmpb.area += PAGE_SIZE; + tmpb.addr += PAGE_SIZE; + } + sgbuf->pages += chunk; + pages -= chunk; + if (chunk < maxpages) + maxpages = chunk; } sgbuf->size = size; dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, PAGE_KERNEL); if (! dmab->area) goto _failed; + if (res_size) + *res_size = sgbuf->size; return dmab->area; _failed: diff --git a/sound/core/sound.c b/sound/core/sound.c index 1003ae375d4..c0685e2f0af 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -34,8 +34,6 @@ #include <linux/kmod.h> #include <linux/mutex.h> -#define SNDRV_OS_MINORS 256 - static int major = CONFIG_SND_MAJOR; int snd_major; EXPORT_SYMBOL(snd_major); @@ -208,20 +206,23 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) minor = type; break; case SNDRV_DEVICE_TYPE_CONTROL: - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; minor = SNDRV_MINOR(card->number, type); break; case SNDRV_DEVICE_TYPE_HWDEP: case SNDRV_DEVICE_TYPE_RAWMIDI: case SNDRV_DEVICE_TYPE_PCM_PLAYBACK: case SNDRV_DEVICE_TYPE_PCM_CAPTURE: - snd_assert(card != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; minor = SNDRV_MINOR(card->number, type + dev); break; default: return -EINVAL; } - snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL); + if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OS_MINORS)) + return -EINVAL; return minor; } #endif @@ -249,7 +250,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, int minor; struct snd_minor *preg; - snd_assert(name, return -EINVAL); + if (snd_BUG_ON(!name)) + return -EINVAL; preg = kmalloc(sizeof *preg, GFP_KERNEL); if (preg == NULL) return -ENOMEM; diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index 7be51546eb9..7fe12264ff8 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -64,7 +64,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) switch (type) { case SNDRV_OSS_DEVICE_TYPE_MIXER: - snd_assert(card != NULL && dev <= 1, return -EINVAL); + if (snd_BUG_ON(!card || dev < 0 || dev > 1)) + return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIXER1 : SNDRV_MINOR_OSS_MIXER)); break; case SNDRV_OSS_DEVICE_TYPE_SEQUENCER: @@ -74,11 +75,13 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) minor = SNDRV_MINOR_OSS_MUSIC; break; case SNDRV_OSS_DEVICE_TYPE_PCM: - snd_assert(card != NULL && dev <= 1, return -EINVAL); + if (snd_BUG_ON(!card || dev < 0 || dev > 1)) + return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_PCM1 : SNDRV_MINOR_OSS_PCM)); break; case SNDRV_OSS_DEVICE_TYPE_MIDI: - snd_assert(card != NULL && dev <= 1, return -EINVAL); + if (snd_BUG_ON(!card || dev < 0 || dev > 1)) + return -EINVAL; minor = SNDRV_MINOR_OSS(card->number, (dev ? SNDRV_MINOR_OSS_MIDI1 : SNDRV_MINOR_OSS_MIDI)); break; case SNDRV_OSS_DEVICE_TYPE_DMFM: @@ -90,7 +93,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) default: return -EINVAL; } - snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL); + if (snd_BUG_ON(minor < 0 || minor >= SNDRV_OSS_MINORS)) + return -EINVAL; return minor; } diff --git a/sound/core/timer.c b/sound/core/timer.c index 0af337efc64..e582face89d 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -306,7 +306,8 @@ int snd_timer_close(struct snd_timer_instance *timeri) struct snd_timer *timer = NULL; struct snd_timer_instance *slave, *tmp; - snd_assert(timeri != NULL, return -ENXIO); + if (snd_BUG_ON(!timeri)) + return -ENXIO; /* force to stop the timer */ snd_timer_stop(timeri); @@ -385,8 +386,9 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) do_posix_clock_monotonic_gettime(&tstamp); else getnstimeofday(&tstamp); - snd_assert(event >= SNDRV_TIMER_EVENT_START && - event <= SNDRV_TIMER_EVENT_PAUSE, return); + if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_START || + event > SNDRV_TIMER_EVENT_PAUSE)) + return; if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) resolution = snd_timer_resolution(ti); @@ -474,7 +476,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri, struct snd_timer *timer; unsigned long flags; - snd_assert(timeri != NULL, return -ENXIO); + if (snd_BUG_ON(!timeri)) + return -ENXIO; if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { if (!keep_flag) { @@ -758,9 +761,10 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, .dev_disconnect = snd_timer_dev_disconnect, }; - snd_assert(tid != NULL, return -EINVAL); - snd_assert(rtimer != NULL, return -EINVAL); - *rtimer = NULL; + if (snd_BUG_ON(!tid)) + return -EINVAL; + if (rtimer) + *rtimer = NULL; timer = kzalloc(sizeof(*timer), GFP_KERNEL); if (timer == NULL) { snd_printk(KERN_ERR "timer: cannot allocate\n"); @@ -788,13 +792,15 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, return err; } } - *rtimer = timer; + if (rtimer) + *rtimer = timer; return 0; } static int snd_timer_free(struct snd_timer *timer) { - snd_assert(timer != NULL, return -ENXIO); + if (!timer) + return 0; mutex_lock(®ister_mutex); if (! list_empty(&timer->open_list_head)) { @@ -827,8 +833,8 @@ static int snd_timer_dev_register(struct snd_device *dev) struct snd_timer *timer = dev->device_data; struct snd_timer *timer1; - snd_assert(timer != NULL && timer->hw.start != NULL && - timer->hw.stop != NULL, return -ENXIO); + if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop)) + return -ENXIO; if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && !timer->hw.resolution && timer->hw.c_resolution == NULL) return -EINVAL; @@ -879,8 +885,9 @@ void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstam if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)) return; - snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && - event <= SNDRV_TIMER_EVENT_MRESUME, return); + if (snd_BUG_ON(event < SNDRV_TIMER_EVENT_MSTART || + event > SNDRV_TIMER_EVENT_MRESUME)) + return; spin_lock_irqsave(&timer->lock, flags); if (event == SNDRV_TIMER_EVENT_MSTART || event == SNDRV_TIMER_EVENT_MCONTINUE || diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c index 5512f5373c5..e05802ae6e1 100644 --- a/sound/core/timer_compat.c +++ b/sound/core/timer_compat.c @@ -40,9 +40,11 @@ static int snd_timer_user_info_compat(struct file *file, struct snd_timer *t; tu = file->private_data; - snd_assert(tu->timeri != NULL, return -ENXIO); + if (snd_BUG_ON(!tu->timeri)) + return -ENXIO; t = tu->timeri->timer; - snd_assert(t != NULL, return -ENXIO); + if (snd_BUG_ON(!t)) + return -ENXIO; memset(&info, 0, sizeof(info)); info.card = t->card ? t->card->number : -1; if (t->hw.flags & SNDRV_TIMER_HW_SLAVE) @@ -71,7 +73,8 @@ static int snd_timer_user_status_compat(struct file *file, struct snd_timer_status status; tu = file->private_data; - snd_assert(tu->timeri != NULL, return -ENXIO); + if (snd_BUG_ON(!tu->timeri)) + return -ENXIO; memset(&status, 0, sizeof(status)); status.tstamp = tu->tstamp; status.resolution = snd_timer_resolution(tu->timeri); |