diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/memalloc.c | 44 | ||||
-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 |
4 files changed, 46 insertions, 30 deletions
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 34250e6022ff..3cf5a87d69ea 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -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; 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; } |