aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-05-02 02:55:54 -0400
committerJaroslav Kysela <perex@suse.cz>2005-05-29 04:05:57 -0400
commitca81090a00e3e7152fe1f3d7398f11d57919428e (patch)
treeac134db42671da0ae343a72c1f48501aa7eb09bf
parent1149a64fe4916fe6fdc8938043a0dc9a6551ab63 (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>
-rw-r--r--sound/usb/usbaudio.c93
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);