aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-08-15 02:22:39 -0400
committerJaroslav Kysela <perex@suse.cz>2005-08-30 02:45:41 -0400
commitb263a9bdf9394062a4fc4272ebed60de331c5490 (patch)
tree440f459eb1cd93ed015c38bf20e93e122d4a32e0 /sound/usb
parent99250872fc619bb5b5ddddcf1c58714a774526fc (diff)
[ALSA] usb-audio: optimize handling of capture URBs
USB generic driver When preparing capture URBs, we don't need to stop when we cross a period boundary because we now never handle more than one millisecond of data per URB anyway. When handling captured data, use an extra flag to call snd_pcm_period_elapsed() no more than once. This allows us to move the period boundary checking code before the copying of the data which avoids a second locking of the substream's lock. Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/usbaudio.c26
1 files changed, 8 insertions, 18 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index a62d1313da17..a703d96bfcb4 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -311,27 +311,18 @@ static int prepare_capture_urb(snd_usb_substream_t *subs,
311 struct urb *urb) 311 struct urb *urb)
312{ 312{
313 int i, offs; 313 int i, offs;
314 unsigned long flags;
315 snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; 314 snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
316 315
317 offs = 0; 316 offs = 0;
318 urb->dev = ctx->subs->dev; /* we need to set this at each time */ 317 urb->dev = ctx->subs->dev; /* we need to set this at each time */
319 urb->number_of_packets = 0;
320 spin_lock_irqsave(&subs->lock, flags);
321 for (i = 0; i < ctx->packets; i++) { 318 for (i = 0; i < ctx->packets; i++) {
322 urb->iso_frame_desc[i].offset = offs; 319 urb->iso_frame_desc[i].offset = offs;
323 urb->iso_frame_desc[i].length = subs->curpacksize; 320 urb->iso_frame_desc[i].length = subs->curpacksize;
324 offs += subs->curpacksize; 321 offs += subs->curpacksize;
325 urb->number_of_packets++;
326 subs->transfer_sched += subs->curframesize;
327 if (subs->transfer_sched >= runtime->period_size) {
328 subs->transfer_sched -= runtime->period_size;
329 break;
330 }
331 } 322 }
332 spin_unlock_irqrestore(&subs->lock, flags);
333 urb->transfer_buffer = ctx->buf; 323 urb->transfer_buffer = ctx->buf;
334 urb->transfer_buffer_length = offs; 324 urb->transfer_buffer_length = offs;
325 urb->number_of_packets = ctx->packets;
335#if 0 // for check 326#if 0 // for check
336 if (! urb->bandwidth) { 327 if (! urb->bandwidth) {
337 int bustime; 328 int bustime;
@@ -359,6 +350,7 @@ static int retire_capture_urb(snd_usb_substream_t *subs,
359 unsigned char *cp; 350 unsigned char *cp;
360 int i; 351 int i;
361 unsigned int stride, len, oldptr; 352 unsigned int stride, len, oldptr;
353 int period_elapsed = 0;
362 354
363 stride = runtime->frame_bits >> 3; 355 stride = runtime->frame_bits >> 3;
364 356
@@ -378,6 +370,10 @@ static int retire_capture_urb(snd_usb_substream_t *subs,
378 if (subs->hwptr_done >= runtime->buffer_size) 370 if (subs->hwptr_done >= runtime->buffer_size)
379 subs->hwptr_done -= runtime->buffer_size; 371 subs->hwptr_done -= runtime->buffer_size;
380 subs->transfer_done += len; 372 subs->transfer_done += len;
373 if (subs->transfer_done >= runtime->period_size) {
374 subs->transfer_done -= runtime->period_size;
375 period_elapsed = 1;
376 }
381 spin_unlock_irqrestore(&subs->lock, flags); 377 spin_unlock_irqrestore(&subs->lock, flags);
382 /* copy a data chunk */ 378 /* copy a data chunk */
383 if (oldptr + len > runtime->buffer_size) { 379 if (oldptr + len > runtime->buffer_size) {
@@ -388,15 +384,9 @@ static int retire_capture_urb(snd_usb_substream_t *subs,
388 } else { 384 } else {
389 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride); 385 memcpy(runtime->dma_area + oldptr * stride, cp, len * stride);
390 } 386 }
391 /* update the pointer, call callback if necessary */
392 spin_lock_irqsave(&subs->lock, flags);
393 if (subs->transfer_done >= runtime->period_size) {
394 subs->transfer_done -= runtime->period_size;
395 spin_unlock_irqrestore(&subs->lock, flags);
396 snd_pcm_period_elapsed(subs->pcm_substream);
397 } else
398 spin_unlock_irqrestore(&subs->lock, flags);
399 } 387 }
388 if (period_elapsed)
389 snd_pcm_period_elapsed(subs->pcm_substream);
400 return 0; 390 return 0;
401} 391}
402 392