aboutsummaryrefslogtreecommitdiff
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c4
-rw-r--r--sound/core/info.c3
-rw-r--r--sound/core/info_oss.c3
-rw-r--r--sound/core/memalloc.c201
-rw-r--r--sound/core/memory.c41
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/oss/pcm_oss.c36
-rw-r--r--sound/core/oss/pcm_plugin.c5
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_lib.c52
-rw-r--r--sound/core/pcm_memory.c1
-rw-r--r--sound/core/pcm_misc.c16
-rw-r--r--sound/core/pcm_native.c74
-rw-r--r--sound/core/seq/oss/seq_oss_synth.c24
-rw-r--r--sound/core/seq/seq_dummy.c5
-rw-r--r--sound/core/seq/seq_midi.c2
-rw-r--r--sound/core/seq/seq_midi_event.c6
-rw-r--r--sound/core/seq/seq_queue.c3
-rw-r--r--sound/core/seq/seq_queue.h1
-rw-r--r--sound/core/seq/seq_timer.c3
-rw-r--r--sound/core/seq/seq_timer.h2
-rw-r--r--sound/core/seq/seq_virmidi.c8
-rw-r--r--sound/core/sound.c9
-rw-r--r--sound/core/timer.c103
-rw-r--r--sound/core/timer_compat.c5
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: