diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/control.c | 4 | ||||
-rw-r--r-- | sound/core/info.c | 3 | ||||
-rw-r--r-- | sound/core/info_oss.c | 3 | ||||
-rw-r--r-- | sound/core/memalloc.c | 201 | ||||
-rw-r--r-- | sound/core/memory.c | 41 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 3 | ||||
-rw-r--r-- | sound/core/oss/pcm_oss.c | 36 | ||||
-rw-r--r-- | sound/core/oss/pcm_plugin.c | 5 | ||||
-rw-r--r-- | sound/core/pcm.c | 3 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 52 | ||||
-rw-r--r-- | sound/core/pcm_memory.c | 1 | ||||
-rw-r--r-- | sound/core/pcm_misc.c | 16 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 74 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss_synth.c | 24 | ||||
-rw-r--r-- | sound/core/seq/seq_dummy.c | 5 | ||||
-rw-r--r-- | sound/core/seq/seq_midi.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_midi_event.c | 6 | ||||
-rw-r--r-- | sound/core/seq/seq_queue.c | 3 | ||||
-rw-r--r-- | sound/core/seq/seq_queue.h | 1 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.c | 3 | ||||
-rw-r--r-- | sound/core/seq/seq_timer.h | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_virmidi.c | 8 | ||||
-rw-r--r-- | sound/core/sound.c | 9 | ||||
-rw-r--r-- | sound/core/timer.c | 103 | ||||
-rw-r--r-- | sound/core/timer_compat.c | 5 |
25 files changed, 326 insertions, 287 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index f4ea6bff1dd..227f3cf0277 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -215,7 +215,7 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access) * * Returns the pointer of the newly generated instance, or NULL on failure. */ -snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data) +snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_data) { snd_kcontrol_t kctl; unsigned int access; @@ -1102,7 +1102,7 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg } } up_read(&snd_ioctl_rwsem); - snd_printd("unknown ioctl = 0x%x\n", cmd); + snd_printdd("unknown ioctl = 0x%x\n", cmd); return -ENOTTY; } diff --git a/sound/core/info.c b/sound/core/info.c index 31faffe01cb..5e122bbe7c9 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -24,6 +24,7 @@ #include <linux/vmalloc.h> #include <linux/time.h> #include <linux/smp_lock.h> +#include <linux/string.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> @@ -754,7 +755,7 @@ static snd_info_entry_t *snd_info_create_entry(const char *name) entry = kcalloc(1, sizeof(*entry), GFP_KERNEL); if (entry == NULL) return NULL; - entry->name = snd_kmalloc_strdup(name, GFP_KERNEL); + entry->name = kstrdup(name, GFP_KERNEL); if (entry->name == NULL) { kfree(entry); return NULL; diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c index f9e4ce44345..12107968d40 100644 --- a/sound/core/info_oss.c +++ b/sound/core/info_oss.c @@ -22,6 +22,7 @@ #include <sound/driver.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/string.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/info.h> @@ -51,7 +52,7 @@ int snd_oss_info_register(int dev, int num, char *string) x = NULL; } } else { - x = snd_kmalloc_strdup(string, GFP_KERNEL); + x = kstrdup(string, GFP_KERNEL); if (x == NULL) { up(&strings); return -ENOMEM; diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 344a83fd7c2..dbc23e35fa0 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -28,6 +28,7 @@ #include <linux/pci.h> #include <linux/slab.h> #include <linux/mm.h> +#include <asm/uaccess.h> #include <linux/dma-mapping.h> #include <linux/moduleparam.h> #include <asm/semaphore.h> @@ -46,13 +47,6 @@ MODULE_LICENSE("GPL"); #define SNDRV_CARDS 8 #endif -/* FIXME: so far only some PCI devices have the preallocation table */ -#ifdef CONFIG_PCI -static int enable[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable cards to allocate buffers."); -#endif - /* */ @@ -451,9 +445,13 @@ size_t snd_dma_get_reserved_buf(struct snd_dma_buffer *dmab, unsigned int id) list_for_each(p, &mem_list_head) { mem = list_entry(p, struct snd_mem_list, list); if (mem->id == id && - ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev))) { + (mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL || + ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) { + struct device *dev = dmab->dev.dev; list_del(p); *dmab = mem->buffer; + if (dmab->dev.dev == NULL) + dmab->dev.dev = dev; kfree(mem); up(&list_mutex); return dmab->bytes; @@ -508,91 +506,13 @@ static void free_all_reserved_pages(void) } - -/* - * allocation of buffers for pre-defined devices - */ - -#ifdef CONFIG_PCI -/* FIXME: for pci only - other bus? */ -struct prealloc_dev { - unsigned short vendor; - unsigned short device; - unsigned long dma_mask; - unsigned int size; - unsigned int buffers; -}; - -#define HAMMERFALL_BUFFER_SIZE (16*1024*4*(26+1)+0x10000) - -static struct prealloc_dev prealloc_devices[] __initdata = { - { - /* hammerfall */ - .vendor = 0x10ee, - .device = 0x3fc4, - .dma_mask = 0xffffffff, - .size = HAMMERFALL_BUFFER_SIZE, - .buffers = 2 - }, - { - /* HDSP */ - .vendor = 0x10ee, - .device = 0x3fc5, - .dma_mask = 0xffffffff, - .size = HAMMERFALL_BUFFER_SIZE, - .buffers = 2 - }, - { }, /* terminator */ -}; - -static void __init preallocate_cards(void) -{ - struct pci_dev *pci = NULL; - int card; - - card = 0; - - while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) { - struct prealloc_dev *dev; - unsigned int i; - if (card >= SNDRV_CARDS) - break; - for (dev = prealloc_devices; dev->vendor; dev++) { - if (dev->vendor == pci->vendor && dev->device == pci->device) - break; - } - if (! dev->vendor) - continue; - if (! enable[card++]) { - printk(KERN_DEBUG "snd-page-alloc: skipping card %d, device %04x:%04x\n", card, pci->vendor, pci->device); - continue; - } - - if (pci_set_dma_mask(pci, dev->dma_mask) < 0 || - pci_set_consistent_dma_mask(pci, dev->dma_mask) < 0) { - printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", dev->dma_mask, dev->vendor, dev->device); - continue; - } - for (i = 0; i < dev->buffers; i++) { - struct snd_dma_buffer dmab; - memset(&dmab, 0, sizeof(dmab)); - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), - dev->size, &dmab) < 0) - printk(KERN_WARNING "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", dev->size); - else - snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci)); - } - } -} -#else -#define preallocate_cards() /* NOP */ -#endif - - #ifdef CONFIG_PROC_FS /* * proc file interface */ +#define SND_MEM_PROC_FILE "driver/snd-page-alloc" +struct proc_dir_entry *snd_mem_proc; + static int snd_mem_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -621,6 +541,97 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, up(&list_mutex); return len; } + +/* FIXME: for pci only - other bus? */ +#ifdef CONFIG_PCI +#define gettoken(bufp) strsep(bufp, " \t\n") + +static int snd_mem_proc_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + char buf[128]; + char *token, *p; + + if (count > ARRAY_SIZE(buf) - 1) + count = ARRAY_SIZE(buf) - 1; + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + buf[ARRAY_SIZE(buf) - 1] = '\0'; + + p = buf; + token = gettoken(&p); + if (! token || *token == '#') + return (int)count; + if (strcmp(token, "add") == 0) { + char *endp; + int vendor, device, size, buffers; + long mask; + int i, alloced; + struct pci_dev *pci; + + if ((token = gettoken(&p)) == NULL || + (vendor = simple_strtol(token, NULL, 0)) <= 0 || + (token = gettoken(&p)) == NULL || + (device = simple_strtol(token, NULL, 0)) <= 0 || + (token = gettoken(&p)) == NULL || + (mask = simple_strtol(token, NULL, 0)) < 0 || + (token = gettoken(&p)) == NULL || + (size = memparse(token, &endp)) < 64*1024 || + size > 16*1024*1024 /* too big */ || + (token = gettoken(&p)) == NULL || + (buffers = simple_strtol(token, NULL, 0)) <= 0 || + buffers > 4) { + printk(KERN_ERR "snd-page-alloc: invalid proc write format\n"); + return (int)count; + } + vendor &= 0xffff; + device &= 0xffff; + + alloced = 0; + pci = NULL; + while ((pci = pci_find_device(vendor, device, pci)) != NULL) { + if (mask > 0 && mask < 0xffffffff) { + if (pci_set_dma_mask(pci, mask) < 0 || + pci_set_consistent_dma_mask(pci, mask) < 0) { + printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device); + return (int)count; + } + } + for (i = 0; i < buffers; i++) { + struct snd_dma_buffer dmab; + memset(&dmab, 0, sizeof(dmab)); + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), + size, &dmab) < 0) { + printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size); + return (int)count; + } + snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci)); + } + alloced++; + } + if (! alloced) { + for (i = 0; i < buffers; i++) { + struct snd_dma_buffer dmab; + memset(&dmab, 0, sizeof(dmab)); + /* FIXME: We can allocate only in ZONE_DMA + * without a device pointer! + */ + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, NULL, + size, &dmab) < 0) { + printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size); + break; + } + snd_dma_reserve_buf(&dmab, (unsigned int)((vendor << 16) | device)); + } + } + } else if (strcmp(token, "erase") == 0) + /* FIXME: need for releasing each buffer chunk? */ + free_all_reserved_pages(); + else + printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n"); + return (int)count; +} +#endif /* CONFIG_PCI */ #endif /* CONFIG_PROC_FS */ /* @@ -630,15 +641,21 @@ static int snd_mem_proc_read(char *page, char **start, off_t off, static int __init snd_mem_init(void) { #ifdef CONFIG_PROC_FS - create_proc_read_entry("driver/snd-page-alloc", 0, NULL, snd_mem_proc_read, NULL); + snd_mem_proc = create_proc_entry(SND_MEM_PROC_FILE, 0644, NULL); + if (snd_mem_proc) { + snd_mem_proc->read_proc = snd_mem_proc_read; +#ifdef CONFIG_PCI + snd_mem_proc->write_proc = snd_mem_proc_write; +#endif + } #endif - preallocate_cards(); return 0; } static void __exit snd_mem_exit(void) { - remove_proc_entry("driver/snd-page-alloc", NULL); + if (snd_mem_proc) + remove_proc_entry(SND_MEM_PROC_FILE, NULL); free_all_reserved_pages(); if (snd_allocated_pages > 0) printk(KERN_ERR "snd-malloc: Memory leak? pages not freed = %li\n", snd_allocated_pages); diff --git a/sound/core/memory.c b/sound/core/memory.c index 20860fec936..c1fb28e8433 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c @@ -184,6 +184,20 @@ void snd_hidden_vfree(void *obj) snd_wrapper_vfree(obj); } +char *snd_hidden_kstrdup(const char *s, int flags) +{ + int len; + char *buf; + + if (!s) return NULL; + + len = strlen(s) + 1; + buf = _snd_kmalloc(len, flags); + if (buf) + memcpy(buf, s, len); + return buf; +} + static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer) { snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc); @@ -214,36 +228,9 @@ int __exit snd_memory_info_done(void) return 0; } -#else - -#define _snd_kmalloc kmalloc - #endif /* CONFIG_SND_DEBUG_MEMORY */ /** - * snd_kmalloc_strdup - copy the string - * @string: the original string - * @flags: allocation conditions, GFP_XXX - * - * Allocates a memory chunk via kmalloc() and copies the string to it. - * - * Returns the pointer, or NULL if no enoguh memory. - */ -char *snd_kmalloc_strdup(const char *string, int flags) -{ - size_t len; - char *ptr; - - if (!string) - return NULL; - len = strlen(string) + 1; - ptr = _snd_kmalloc(len, flags); - if (ptr) - memcpy(ptr, string, len); - return ptr; -} - -/** * copy_to_user_fromio - copy data from mmio-space to user-space * @dst: the destination pointer on user-space * @src: the source pointer on mmio diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 98ed9a9f0da..98fc0766f88 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -24,6 +24,7 @@ #include <linux/smp_lock.h> #include <linux/slab.h> #include <linux/time.h> +#include <linux/string.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/control.h> @@ -1137,7 +1138,7 @@ static void snd_mixer_oss_proc_write(snd_info_entry_t *entry, goto __unlock; } tbl->oss_id = ch; - tbl->name = snd_kmalloc_strdup(str, GFP_KERNEL); + tbl->name = kstrdup(str, GFP_KERNEL); if (! tbl->name) { kfree(tbl); goto __unlock; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 1a805020f57..de7444c586f 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -33,6 +33,7 @@ #include <linux/time.h> #include <linux/vmalloc.h> #include <linux/moduleparam.h> +#include <linux/string.h> #include <sound/core.h> #include <sound/minors.h> #include <sound/pcm.h> @@ -125,17 +126,26 @@ int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin) static long snd_pcm_oss_bytes(snd_pcm_substream_t *substream, long frames) { snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream); - frames = frames_to_bytes(runtime, frames); + long buffer_size = snd_pcm_lib_buffer_bytes(substream); + long bytes = frames_to_bytes(runtime, frames); if (buffer_size == runtime->oss.buffer_bytes) - return frames; - return (runtime->oss.buffer_bytes * frames) / buffer_size; + return bytes; +#if BITS_PER_LONG >= 64 + return runtime->oss.buffer_bytes * bytes / buffer_size; +#else + { + u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes; + u32 rem; + div64_32(&bsize, buffer_size, &rem); + return (long)bsize; + } +#endif } static long snd_pcm_alsa_frames(snd_pcm_substream_t *substream, long bytes) { snd_pcm_runtime_t *runtime = substream->runtime; - snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream); + long buffer_size = snd_pcm_lib_buffer_bytes(substream); if (buffer_size == runtime->oss.buffer_bytes) return bytes_to_frames(runtime, bytes); return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); @@ -464,7 +474,8 @@ static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream) sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; sw_params->period_step = 1; sw_params->sleep_min = 0; - sw_params->avail_min = 1; + sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + 1 : runtime->period_size; sw_params->xfer_align = 1; if (atomic_read(&runtime->mmap_count) || (substream->oss.setup && substream->oss.setup->nosilence)) { @@ -1527,12 +1538,15 @@ static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, str snd_pcm_oss_simulate_fill(substream, delay); info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; } else { - delay = snd_pcm_oss_bytes(substream, delay) + fixup; - info.blocks = delay / runtime->oss.period_bytes; - if (stream == SNDRV_PCM_STREAM_PLAYBACK) + delay = snd_pcm_oss_bytes(substream, delay); + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes; info.bytes = (runtime->oss.bytes - delay) & INT_MAX; - else + } else { + delay += fixup; + info.blocks = delay / runtime->oss.period_bytes; info.bytes = (runtime->oss.bytes + delay) & INT_MAX; + } } if (copy_to_user(_info, &info, sizeof(info))) return -EFAULT; @@ -2347,7 +2361,7 @@ static void snd_pcm_oss_proc_write(snd_info_entry_t *entry, for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next); setup1->next = setup; } - template.task_name = snd_kmalloc_strdup(task_name, GFP_KERNEL); + template.task_name = kstrdup(task_name, GFP_KERNEL); } else { buffer->error = -ENOMEM; } diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 6bb31009f0b..6430410c6c0 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -663,10 +663,7 @@ static int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug, bitset_t *dstmask = bs; int err; bitset_one(dstmask, schannels); - if (plugin == NULL) { - bitset_and(client_vmask, dstmask, schannels); - return 0; - } + while (1) { err = plugin->src_channels_mask(plugin, dstmask, &srcmask); if (err < 0) diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 8d94325529a..9f4c9209b27 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -451,6 +451,7 @@ static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr) entry->c.text.read = snd_pcm_xrun_debug_read; entry->c.text.write_size = 64; entry->c.text.write = snd_pcm_xrun_debug_write; + entry->mode |= S_IWUSR; entry->private_data = pstr; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -1048,7 +1049,6 @@ EXPORT_SYMBOL(snd_pcm_release_substream); EXPORT_SYMBOL(snd_pcm_format_name); /* pcm_native.c */ EXPORT_SYMBOL(snd_pcm_link_rwlock); -EXPORT_SYMBOL(snd_pcm_start); #ifdef CONFIG_PM EXPORT_SYMBOL(snd_pcm_suspend); EXPORT_SYMBOL(snd_pcm_suspend_all); @@ -1068,6 +1068,7 @@ EXPORT_SYMBOL(snd_pcm_format_little_endian); EXPORT_SYMBOL(snd_pcm_format_big_endian); EXPORT_SYMBOL(snd_pcm_format_width); EXPORT_SYMBOL(snd_pcm_format_physical_width); +EXPORT_SYMBOL(snd_pcm_format_size); EXPORT_SYMBOL(snd_pcm_format_silence_64); EXPORT_SYMBOL(snd_pcm_format_set_silence); EXPORT_SYMBOL(snd_pcm_build_linear_format); diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 151fd99ca2c..c5bfd0918cf 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1143,7 +1143,8 @@ int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime, #define INT_MIN ((int)((unsigned int)INT_MAX+1)) #endif -void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var) +static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { if (hw_is_mask(var)) { snd_mask_any(hw_param_mask(params, var)); @@ -1160,6 +1161,7 @@ void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var) snd_BUG(); } +#if 0 /** * snd_pcm_hw_param_any */ @@ -1169,6 +1171,7 @@ int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, _snd_pcm_hw_param_any(params, var); return snd_pcm_hw_refine(pcm, params); } +#endif /* 0 */ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params) { @@ -1181,6 +1184,7 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params) params->info = ~0U; } +#if 0 /** * snd_pcm_hw_params_any * @@ -1191,6 +1195,7 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) _snd_pcm_hw_params_any(params); return snd_pcm_hw_refine(pcm, params); } +#endif /* 0 */ /** * snd_pcm_hw_param_value @@ -1198,8 +1203,8 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) * Return the value for field PAR if it's fixed in configuration space * defined by PARAMS. Return -EINVAL otherwise */ -int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { if (hw_is_mask(var)) { const snd_mask_t *mask = hw_param_mask_c(params, var); @@ -1296,6 +1301,7 @@ int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params, return changed; } +#if 0 /** * snd_pcm_hw_param_setinteger * @@ -1317,9 +1323,10 @@ int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, } return 0; } +#endif /* 0 */ -int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { int changed; if (hw_is_mask(var)) @@ -1345,9 +1352,9 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params, * values > minimum. Reduce configuration space accordingly. * Return the minimum. */ -int snd_pcm_hw_param_first(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +static int snd_pcm_hw_param_first(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { int changed = _snd_pcm_hw_param_first(params, var); if (changed < 0) @@ -1359,8 +1366,8 @@ int snd_pcm_hw_param_first(snd_pcm_t *pcm, return snd_pcm_hw_param_value(params, var, dir); } -int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var) +static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var) { int changed; if (hw_is_mask(var)) @@ -1386,9 +1393,9 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params, * values < maximum. Reduce configuration space accordingly. * Return the maximum. */ -int snd_pcm_hw_param_last(snd_pcm_t *pcm, - snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, int *dir) +static int snd_pcm_hw_param_last(snd_pcm_t *pcm, + snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, int *dir) { int changed = _snd_pcm_hw_param_last(params, var); if (changed < 0) @@ -1437,8 +1444,9 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params, * values < VAL. Reduce configuration space accordingly. * Return new minimum or -EINVAL if the configuration space is empty */ -int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, int *dir) +static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, + int *dir) { int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0); if (changed < 0) @@ -1451,8 +1459,9 @@ int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, return snd_pcm_hw_param_value_min(params, var, dir); } -int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, int dir) +static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, + int dir) { int changed; int open = 0; @@ -1490,8 +1499,9 @@ int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params, * values >= VAL + 1. Reduce configuration space accordingly. * Return new maximum or -EINVAL if the configuration space is empty */ -int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, unsigned int val, int *dir) +static int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, + snd_pcm_hw_param_t var, unsigned int val, + int *dir) { int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0); if (changed < 0) @@ -2564,9 +2574,6 @@ snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream, EXPORT_SYMBOL(snd_interval_refine); EXPORT_SYMBOL(snd_interval_list); EXPORT_SYMBOL(snd_interval_ratnum); -EXPORT_SYMBOL(snd_interval_muldivk); -EXPORT_SYMBOL(snd_interval_mulkdiv); -EXPORT_SYMBOL(snd_interval_div); EXPORT_SYMBOL(_snd_pcm_hw_params_any); EXPORT_SYMBOL(_snd_pcm_hw_param_min); EXPORT_SYMBOL(_snd_pcm_hw_param_set); @@ -2580,7 +2587,6 @@ EXPORT_SYMBOL(snd_pcm_hw_param_last); EXPORT_SYMBOL(snd_pcm_hw_param_near); EXPORT_SYMBOL(snd_pcm_hw_param_set); EXPORT_SYMBOL(snd_pcm_hw_refine); -EXPORT_SYMBOL(snd_pcm_hw_params); EXPORT_SYMBOL(snd_pcm_hw_constraints_init); EXPORT_SYMBOL(snd_pcm_hw_constraints_complete); EXPORT_SYMBOL(snd_pcm_hw_constraint_list); diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index f1d5f7a6ee0..9a174fb9656 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -204,6 +204,7 @@ static int snd_pcm_lib_preallocate_pages1(snd_pcm_substream_t *substream, entry->c.text.read = snd_pcm_lib_preallocate_proc_read; entry->c.text.write_size = 64; entry->c.text.write = snd_pcm_lib_preallocate_proc_write; + entry->mode |= S_IWUSR; entry->private_data = substream; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 422b8db1415..1453743e4da 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -270,22 +270,6 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format) } /** - * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian - * @format: the format to check - * - * Returns 1 if the given PCM format is CPU-endian, 0 if - * opposite, or a negative error code if endian not specified. - */ -int snd_pcm_format_cpu_endian(snd_pcm_format_t format) -{ -#ifdef SNDRV_LITTLE_ENDIAN - return snd_pcm_format_little_endian(format); -#else - return snd_pcm_format_big_endian(format); -#endif -} - -/** * snd_pcm_format_width - return the bit-width of the format * @format: the format to check * diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index cad9bbde998..10c2c983264 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -337,8 +337,8 @@ out: return err; } -int snd_pcm_hw_params(snd_pcm_substream_t *substream, - snd_pcm_hw_params_t *params) +static int snd_pcm_hw_params(snd_pcm_substream_t *substream, + snd_pcm_hw_params_t *params) { snd_pcm_runtime_t *runtime; int err; @@ -1368,43 +1368,32 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; - down_read(&snd_pcm_link_rwsem); snd_power_lock(card); if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile); - if (result < 0) - goto _unlock; + if (result < 0) { + snd_power_unlock(card); + return result; + } } /* allocate temporary record for drain sync */ + down_read(&snd_pcm_link_rwsem); if (snd_pcm_stream_linked(substream)) { drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL); if (! drec) { - result = -ENOMEM; - goto _unlock; + up_read(&snd_pcm_link_rwsem); + snd_power_unlock(card); + return -ENOMEM; } } else drec = &drec_tmp; - snd_pcm_stream_lock_irq(substream); - /* resume pause */ - if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) - snd_pcm_pause(substream, 0); - - /* pre-start/stop - all running streams are changed to DRAINING state */ - result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); - if (result < 0) - goto _end; - - /* check streams with PLAYBACK & DRAINING */ + /* count only playback streams */ num_drecs = 0; snd_pcm_group_for_each(pos, substream) { snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos); runtime = s->runtime; - if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) { - runtime->status->state = SNDRV_PCM_STATE_SETUP; - continue; - } if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { d = &drec[num_drecs++]; d->substream = s; @@ -1418,9 +1407,21 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = runtime->buffer_size; } } - + up_read(&snd_pcm_link_rwsem); if (! num_drecs) - goto _end; + goto _error; + + snd_pcm_stream_lock_irq(substream); + /* resume pause */ + if (runtime->status->state == SNDRV_PCM_STATE_PAUSED) + snd_pcm_pause(substream, 0); + + /* pre-start/stop - all running streams are changed to DRAINING state */ + result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0); + if (result < 0) { + snd_pcm_stream_unlock_irq(substream); + goto _error; + } for (;;) { long tout; @@ -1428,6 +1429,15 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) result = -ERESTARTSYS; break; } + /* all finished? */ + for (i = 0; i < num_drecs; i++) { + runtime = drec[i].substream->runtime; + if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) + break; + } + if (i == num_drecs) + break; /* yes, all drained */ + set_current_state(TASK_INTERRUPTIBLE); snd_pcm_stream_unlock_irq(substream); snd_power_unlock(card); @@ -1444,15 +1454,11 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) } break; } - /* all finished? */ - for (i = 0; i < num_drecs; i++) { - runtime = drec[i].substream->runtime; - if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) - break; - } - if (i == num_drecs) - break; } + + snd_pcm_stream_unlock_irq(substream); + + _error: for (i = 0; i < num_drecs; i++) { d = &drec[i]; runtime = d->substream->runtime; @@ -1460,13 +1466,9 @@ static int snd_pcm_drain(snd_pcm_substream_t *substream) runtime->stop_threshold = d->stop_threshold; } - _end: - snd_pcm_stream_unlock_irq(substream); if (drec != &drec_tmp) kfree(drec); - _unlock: |