diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-05-02 02:55:54 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2005-05-29 04:05:57 -0400 |
commit | ca81090a00e3e7152fe1f3d7398f11d57919428e (patch) | |
tree | ac134db42671da0ae343a72c1f48501aa7eb09bf /sound/usb/usbaudio.c | |
parent | 1149a64fe4916fe6fdc8938043a0dc9a6551ab63 (diff) |
[ALSA] usb-audio - use only one packet in synchronization feedback URBs
USB generic driver
Do not use more than one packet in synchronization feedback URBs because
it would be pointless to send or receive more than one value at the same
time.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/usb/usbaudio.c')
-rw-r--r-- | sound/usb/usbaudio.c | 93 |
1 files changed, 31 insertions, 62 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index e1a648d7ffff..a5e97d081c3b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -177,7 +177,7 @@ struct snd_usb_substream { | |||
177 | unsigned int nurbs; /* # urbs */ | 177 | unsigned int nurbs; /* # urbs */ |
178 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ | 178 | snd_urb_ctx_t dataurb[MAX_URBS]; /* data urb table */ |
179 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ | 179 | snd_urb_ctx_t syncurb[SYNC_URBS]; /* sync urb table */ |
180 | char syncbuf[SYNC_URBS * MAX_PACKS * 4]; /* sync buffer; it's so small - let's get static */ | 180 | char syncbuf[SYNC_URBS * 4]; /* sync buffer; it's so small - let's get static */ |
181 | char *tmpbuf; /* temporary buffer for playback */ | 181 | char *tmpbuf; /* temporary buffer for playback */ |
182 | 182 | ||
183 | u64 formats; /* format bitmasks (all or'ed) */ | 183 | u64 formats; /* format bitmasks (all or'ed) */ |
@@ -251,17 +251,13 @@ static int prepare_capture_sync_urb(snd_usb_substream_t *subs, | |||
251 | { | 251 | { |
252 | unsigned char *cp = urb->transfer_buffer; | 252 | unsigned char *cp = urb->transfer_buffer; |
253 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 253 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
254 | int i, offs; | ||
255 | 254 | ||
256 | urb->number_of_packets = ctx->packets; | ||
257 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 255 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
258 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { | 256 | urb->iso_frame_desc[0].length = 3; |
259 | urb->iso_frame_desc[i].length = 3; | 257 | urb->iso_frame_desc[0].offset = 0; |
260 | urb->iso_frame_desc[i].offset = offs; | 258 | cp[0] = subs->freqn >> 2; |
261 | cp[0] = subs->freqn >> 2; | 259 | cp[1] = subs->freqn >> 10; |
262 | cp[1] = subs->freqn >> 10; | 260 | cp[2] = subs->freqn >> 18; |
263 | cp[2] = subs->freqn >> 18; | ||
264 | } | ||
265 | return 0; | 261 | return 0; |
266 | } | 262 | } |
267 | 263 | ||
@@ -277,18 +273,14 @@ static int prepare_capture_sync_urb_hs(snd_usb_substream_t *subs, | |||
277 | { | 273 | { |
278 | unsigned char *cp = urb->transfer_buffer; | 274 | unsigned char *cp = urb->transfer_buffer; |
279 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 275 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
280 | int i, offs; | ||
281 | 276 | ||
282 | urb->number_of_packets = ctx->packets; | ||
283 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 277 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
284 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) { | 278 | urb->iso_frame_desc[0].length = 4; |
285 | urb->iso_frame_desc[i].length = 4; | 279 | urb->iso_frame_desc[0].offset = 0; |
286 | urb->iso_frame_desc[i].offset = offs; | 280 | cp[0] = subs->freqn; |
287 | cp[0] = subs->freqn; | 281 | cp[1] = subs->freqn >> 8; |
288 | cp[1] = subs->freqn >> 8; | 282 | cp[2] = subs->freqn >> 16; |
289 | cp[2] = subs->freqn >> 16; | 283 | cp[3] = subs->freqn >> 24; |
290 | cp[3] = subs->freqn >> 24; | ||
291 | } | ||
292 | return 0; | 284 | return 0; |
293 | } | 285 | } |
294 | 286 | ||
@@ -418,15 +410,11 @@ static int prepare_playback_sync_urb(snd_usb_substream_t *subs, | |||
418 | snd_pcm_runtime_t *runtime, | 410 | snd_pcm_runtime_t *runtime, |
419 | struct urb *urb) | 411 | struct urb *urb) |
420 | { | 412 | { |
421 | int i, offs; | ||
422 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 413 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
423 | 414 | ||
424 | urb->number_of_packets = ctx->packets; | ||
425 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 415 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
426 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { | 416 | urb->iso_frame_desc[0].length = 3; |
427 | urb->iso_frame_desc[i].length = 3; | 417 | urb->iso_frame_desc[0].offset = 0; |
428 | urb->iso_frame_desc[i].offset = offs; | ||
429 | } | ||
430 | return 0; | 418 | return 0; |
431 | } | 419 | } |
432 | 420 | ||
@@ -440,15 +428,11 @@ static int prepare_playback_sync_urb_hs(snd_usb_substream_t *subs, | |||
440 | snd_pcm_runtime_t *runtime, | 428 | snd_pcm_runtime_t *runtime, |
441 | struct urb *urb) | 429 | struct urb *urb) |
442 | { | 430 | { |
443 | int i, offs; | ||
444 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; | 431 | snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context; |
445 | 432 | ||
446 | urb->number_of_packets = ctx->packets; | ||
447 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | 433 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
448 | for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) { | 434 | urb->iso_frame_desc[0].length = 4; |
449 | urb->iso_frame_desc[i].length = 4; | 435 | urb->iso_frame_desc[0].offset = 0; |
450 | urb->iso_frame_desc[i].offset = offs; | ||
451 | } | ||
452 | return 0; | 436 | return 0; |
453 | } | 437 | } |
454 | 438 | ||
@@ -462,17 +446,12 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, | |||
462 | snd_pcm_runtime_t *runtime, | 446 | snd_pcm_runtime_t *runtime, |
463 | struct urb *urb) | 447 | struct urb *urb) |
464 | { | 448 | { |
465 | int i; | 449 | unsigned int f; |
466 | unsigned int f, found; | ||
467 | unsigned char *cp = urb->transfer_buffer; | ||
468 | unsigned long flags; | 450 | unsigned long flags; |
469 | 451 | ||
470 | found = 0; | 452 | if (urb->iso_frame_desc[0].status == 0 && |
471 | for (i = 0; i < urb->number_of_packets; i++, cp += 4) { | 453 | urb->iso_frame_desc[0].actual_length == 3) { |
472 | if (urb->iso_frame_desc[i].status || | 454 | f = combine_triple((u8*)urb->transfer_buffer) << 2; |
473 | urb->iso_frame_desc[i].actual_length < 3) | ||
474 | continue; | ||
475 | f = combine_triple(cp) << 2; | ||
476 | #if 0 | 455 | #if 0 |
477 | if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) { | 456 | if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) { |
478 | snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n", | 457 | snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n", |
@@ -481,11 +460,8 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs, | |||
481 | continue; | 460 | continue; |
482 | } | 461 | } |
483 | #endif | 462 | #endif |
484 | found = f; | ||
485 | } | ||
486 | if (found) { | ||
487 | spin_lock_irqsave(&subs->lock, flags); | 463 | spin_lock_irqsave(&subs->lock, flags); |
488 | subs->freqm = found; | 464 | subs->freqm = f; |
489 | spin_unlock_irqrestore(&subs->lock, flags); | 465 | spin_unlock_irqrestore(&subs->lock, flags); |
490 | } | 466 | } |
491 | 467 | ||
@@ -502,21 +478,14 @@ static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs, | |||
502 | snd_pcm_runtime_t *runtime, | 478 | snd_pcm_runtime_t *runtime, |
503 | struct urb *urb) | 479 | struct urb *urb) |
504 | { | 480 | { |
505 | int i; | 481 | unsigned int f; |
506 | unsigned int found; | ||
507 | unsigned char *cp = urb->transfer_buffer; | ||
508 | unsigned long flags; | 482 | unsigned long flags; |
509 | 483 | ||
510 | found = 0; | 484 | if (urb->iso_frame_desc[0].status == 0 && |
511 | for (i = 0; i < urb->number_of_packets; i++, cp += 4) { | 485 | urb->iso_frame_desc[0].actual_length == 4) { |
512 | if (urb->iso_frame_desc[i].status || | 486 | f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; |
513 | urb->iso_frame_desc[i].actual_length < 4) | ||
514 | continue; | ||
515 | found = combine_quad(cp) & 0x0fffffff; | ||
516 | } | ||
517 | if (found) { | ||
518 | spin_lock_irqsave(&subs->lock, flags); | 487 | spin_lock_irqsave(&subs->lock, flags); |
519 | subs->freqm = found; | 488 | subs->freqm = f; |
520 | spin_unlock_irqrestore(&subs->lock, flags); | 489 | spin_unlock_irqrestore(&subs->lock, flags); |
521 | } | 490 | } |
522 | 491 | ||
@@ -1039,18 +1008,18 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
1039 | snd_urb_ctx_t *u = &subs->syncurb[i]; | 1008 | snd_urb_ctx_t *u = &subs->syncurb[i]; |
1040 | u->index = i; | 1009 | u->index = i; |
1041 | u->subs = subs; | 1010 | u->subs = subs; |
1042 | u->packets = nrpacks; | 1011 | u->packets = 1; |
1043 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | 1012 | u->urb = usb_alloc_urb(1, GFP_KERNEL); |
1044 | if (! u->urb) { | 1013 | if (! u->urb) { |
1045 | release_substream_urbs(subs, 0); | 1014 | release_substream_urbs(subs, 0); |
1046 | return -ENOMEM; | 1015 | return -ENOMEM; |
1047 | } | 1016 | } |
1048 | u->urb->transfer_buffer = subs->syncbuf + i * nrpacks * 4; | 1017 | u->urb->transfer_buffer = subs->syncbuf + i * 4; |
1049 | u->urb->transfer_buffer_length = nrpacks * 4; | 1018 | u->urb->transfer_buffer_length = 4; |
1050 | u->urb->dev = subs->dev; | 1019 | u->urb->dev = subs->dev; |
1051 | u->urb->pipe = subs->syncpipe; | 1020 | u->urb->pipe = subs->syncpipe; |
1052 | u->urb->transfer_flags = URB_ISO_ASAP; | 1021 | u->urb->transfer_flags = URB_ISO_ASAP; |
1053 | u->urb->number_of_packets = u->packets; | 1022 | u->urb->number_of_packets = 1; |
1054 | u->urb->interval = 1 << subs->syncinterval; | 1023 | u->urb->interval = 1 << subs->syncinterval; |
1055 | u->urb->context = u; | 1024 | u->urb->context = u; |
1056 | u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); | 1025 | u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb); |