diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-08-15 02:22:39 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-08-30 02:45:41 -0400 |
commit | b263a9bdf9394062a4fc4272ebed60de331c5490 (patch) | |
tree | 440f459eb1cd93ed015c38bf20e93e122d4a32e0 /sound/usb | |
parent | 99250872fc619bb5b5ddddcf1c58714a774526fc (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.c | 26 |
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 | ||