diff options
Diffstat (limited to 'sound/core')
| -rw-r--r-- | sound/core/control.c | 23 | ||||
| -rw-r--r-- | sound/core/memalloc.c | 64 | ||||
| -rw-r--r-- | sound/core/pcm_native.c | 24 | ||||
| -rw-r--r-- | sound/core/pcm_trace.h | 6 | ||||
| -rw-r--r-- | sound/core/rawmidi.c | 2 | ||||
| -rw-r--r-- | sound/core/seq/seq_memory.c | 11 |
6 files changed, 86 insertions, 44 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index a7271927d875..50e7ba66f187 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -753,6 +753,29 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, } EXPORT_SYMBOL(snd_ctl_rename_id); +/** + * snd_ctl_rename - rename the control on the card + * @card: the card instance + * @kctl: the control to rename + * @name: the new name + * + * Renames the specified control on the card to the new name. + * + * Make sure to take the control write lock - down_write(&card->controls_rwsem). + */ +void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, + const char *name) +{ + remove_hash_entries(card, kctl); + + if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0) + pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n", + name, kctl->id.name); + + add_hash_entries(card, kctl); +} +EXPORT_SYMBOL(snd_ctl_rename); + #ifndef CONFIG_SND_CTL_FAST_LOOKUP static struct snd_kcontrol * snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 03cffe771366..3cf5a87d69ea 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -9,6 +9,7 @@ #include <linux/slab.h> #include <linux/mm.h> #include <linux/dma-mapping.h> +#include <linux/dma-map-ops.h> #include <linux/genalloc.h> #include <linux/highmem.h> #include <linux/vmalloc.h> @@ -20,7 +21,6 @@ #define DEFAULT_GFP \ (GFP_KERNEL | \ - __GFP_COMP | /* compound page lets parts be mapped */ \ __GFP_RETRY_MAYFAIL | /* don't trigger OOM-killer */ \ __GFP_NOWARN) /* no stack trace print - this call is non-critical */ @@ -542,18 +542,18 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size) void *p; sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir, - DEFAULT_GFP, 0); - if (!sgt) { + DEFAULT_GFP | __GFP_COMP, 0); #ifdef CONFIG_SND_DMA_SGBUF + if (!sgt && !get_dma_ops(dmab->dev.dev)) { if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; else dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; return snd_dma_sg_fallback_alloc(dmab, size); -#else - return NULL; -#endif } +#endif + if (!sgt) + return NULL; dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, sg_dma_address(sgt->sgl)); @@ -719,7 +719,6 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = { struct snd_dma_sg_fallback { size_t count; struct page **pages; - dma_addr_t *addrs; }; static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab, @@ -731,38 +730,49 @@ static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab, for (i = 0; i < sgbuf->count && sgbuf->pages[i]; i++) do_free_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc); kvfree(sgbuf->pages); - kvfree(sgbuf->addrs); kfree(sgbuf); } static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) { struct snd_dma_sg_fallback *sgbuf; - struct page **pages; - size_t i, count; + struct page **pagep, *curp; + size_t chunk, npages; + dma_addr_t addr; void *p; bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); if (!sgbuf) return NULL; - count = PAGE_ALIGN(size) >> PAGE_SHIFT; - pages = kvcalloc(count, sizeof(*pages), GFP_KERNEL); - if (!pages) - goto error; - sgbuf->pages = pages; - sgbuf->addrs = kvcalloc(count, sizeof(*sgbuf->addrs), GFP_KERNEL); - if (!sgbuf->addrs) + size = PAGE_ALIGN(size); + sgbuf->count = size >> PAGE_SHIFT; + sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL); + if (!sgbuf->pages) goto error; - for (i = 0; i < count; sgbuf->count++, i++) { - p = do_alloc_pages(dmab->dev.dev, PAGE_SIZE, &sgbuf->addrs[i], wc); - if (!p) - goto error; - sgbuf->pages[i] = virt_to_page(p); + pagep = sgbuf->pages; + chunk = size; + while (size > 0) { + chunk = min(size, chunk); + p = do_alloc_pages(dmab->dev.dev, chunk, &addr, wc); + if (!p) { + if (chunk <= PAGE_SIZE) + goto error; + chunk >>= 1; + chunk = PAGE_SIZE << get_order(chunk); + continue; + } + + size -= chunk; + /* fill pages */ + npages = chunk >> PAGE_SHIFT; + curp = virt_to_page(p); + while (npages--) + *pagep++ = curp++; } - p = vmap(pages, count, VM_MAP, PAGE_KERNEL); + p = vmap(sgbuf->pages, sgbuf->count, VM_MAP, PAGE_KERNEL); if (!p) goto error; dmab->private_data = sgbuf; @@ -810,7 +820,7 @@ static void *snd_dma_noncoherent_alloc(struct snd_dma_buffer *dmab, size_t size) void *p; p = dma_alloc_noncoherent(dmab->dev.dev, size, &dmab->addr, - dmab->dev.dir, DEFAULT_GFP); + dmab->dev.dir, DEFAULT_GFP | __GFP_COMP); if (p) dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->addr); return p; @@ -857,7 +867,7 @@ static const struct snd_malloc_ops snd_dma_noncoherent_ops = { /* * Entry points */ -static const struct snd_malloc_ops *dma_ops[] = { +static const struct snd_malloc_ops *snd_dma_ops[] = { [SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops, [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops, #ifdef CONFIG_HAS_DMA @@ -883,7 +893,7 @@ static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab) if (WARN_ON_ONCE(!dmab)) return NULL; if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN || - dmab->dev.type >= ARRAY_SIZE(dma_ops))) + dmab->dev.type >= ARRAY_SIZE(snd_dma_ops))) return NULL; - return dma_ops[dmab->dev.type]; + return snd_dma_ops[dmab->dev.type]; } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 33769ca78cc8..9c122e757efe 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -288,7 +288,7 @@ static int constrain_mask_params(struct snd_pcm_substream *substream, &substream->runtime->hw_constraints; struct snd_mask *m; unsigned int k; - struct snd_mask old_mask; + struct snd_mask old_mask __maybe_unused; int changed; for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) { @@ -324,7 +324,7 @@ static int constrain_interval_params(struct snd_pcm_substream *substream, &substream->runtime->hw_constraints; struct snd_interval *i; unsigned int k; - struct snd_interval old_interval; + struct snd_interval old_interval __maybe_unused; int changed; for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) { @@ -364,8 +364,8 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream, unsigned int stamp; struct snd_pcm_hw_rule *r; unsigned int d; - struct snd_mask old_mask; - struct snd_interval old_interval; + struct snd_mask old_mask __maybe_unused; + struct snd_interval old_interval __maybe_unused; bool again; int changed, err = 0; @@ -648,8 +648,8 @@ static int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, -1 }; const int *v; - struct snd_mask old_mask; - struct snd_interval old_interval; + struct snd_mask old_mask __maybe_unused; + struct snd_interval old_interval __maybe_unused; int changed; for (v = vars; *v != -1; v++) { @@ -1424,16 +1424,24 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, static int snd_pcm_do_start(struct snd_pcm_substream *substream, snd_pcm_state_t state) { + int err; + if (substream->runtime->trigger_master != substream) return 0; - return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); + err = substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START); + /* XRUN happened during the start */ + if (err == -EPIPE) + __snd_pcm_set_state(substream->runtime, SNDRV_PCM_STATE_XRUN); + return err; } static void snd_pcm_undo_start(struct snd_pcm_substream *substream, snd_pcm_state_t state) { - if (substream->runtime->trigger_master == substream) + if (substream->runtime->trigger_master == substream) { substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP); + substream->runtime->stop_operating = true; + } } static void snd_pcm_post_start(struct snd_pcm_substream *substream, diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h index f18da2050772..350b40b906ca 100644 --- a/sound/core/pcm_trace.h +++ b/sound/core/pcm_trace.h @@ -88,19 +88,19 @@ TRACE_EVENT(hw_ptr_error, __field( unsigned int, device ) __field( unsigned int, number ) __field( unsigned int, stream ) - __field( const char *, reason ) + __string( reason, why ) ), TP_fast_assign( __entry->card = (substream)->pcm->card->number; __entry->device = (substream)->pcm->device; __entry->number = (substream)->number; __entry->stream = (substream)->stream; - __entry->reason = (why); + __assign_str(reason, why); ), TP_printk("pcmC%dD%d%s/sub%d: ERROR: %s", __entry->card, __entry->device, __entry->stream == SNDRV_PCM_STREAM_PLAYBACK ? "p" : "c", - __entry->number, __entry->reason) + __entry->number, __get_str(reason)) ); TRACE_EVENT(applptr, diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index d8edb6055072..7147fda66d93 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -1050,7 +1050,6 @@ static int receive_with_tstamp_framing(struct snd_rawmidi_substream *substream, struct snd_rawmidi_runtime *runtime = substream->runtime; struct snd_rawmidi_framing_tstamp *dest_ptr; struct snd_rawmidi_framing_tstamp frame = { .tv_sec = tstamp->tv_sec, .tv_nsec = tstamp->tv_nsec }; - int dest_frames = 0; int orig_count = src_count; int frame_size = sizeof(struct snd_rawmidi_framing_tstamp); @@ -1077,7 +1076,6 @@ static int receive_with_tstamp_framing(struct snd_rawmidi_substream *substream, runtime->avail += frame_size; runtime->hw_ptr += frame_size; runtime->hw_ptr %= runtime->buffer_size; - dest_frames++; } return orig_count - src_count; } diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index b7aee23fc387..47ef6bc30c0e 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -113,15 +113,19 @@ EXPORT_SYMBOL(snd_seq_dump_var_event); * expand the variable length event to linear buffer space. */ -static int seq_copy_in_kernel(char **bufptr, const void *src, int size) +static int seq_copy_in_kernel(void *ptr, void *src, int size) { + char **bufptr = ptr; + memcpy(*bufptr, src, size); *bufptr += size; return 0; } -static int seq_copy_in_user(char __user **bufptr, const void *src, int size) +static int seq_copy_in_user(void *ptr, void *src, int size) { + char __user **bufptr = ptr; + if (copy_to_user(*bufptr, src, size)) return -EFAULT; *bufptr += size; @@ -151,8 +155,7 @@ int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char return newlen; } err = snd_seq_dump_var_event(event, - in_kernel ? (snd_seq_dump_func_t)seq_copy_in_kernel : - (snd_seq_dump_func_t)seq_copy_in_user, + in_kernel ? seq_copy_in_kernel : seq_copy_in_user, &buf); return err < 0 ? err : newlen; } |