aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-07-13 07:43:59 -0400
committerTakashi Iwai <tiwai@suse.de>2009-07-15 05:56:30 -0400
commited4affa53229701be7be4f7f84ba84164135d7e8 (patch)
treefdb069a760d512320c38621850a50e176368815b
parent4773d1fb8f37612336d2c929058bf96d3a1624b1 (diff)
sound: usb-audio: use multiple output URBs
Some newer USB MIDI interfaces use rather small packet sizes, so to get enough bandwidth, we have to be able to send multiple packets in one USB frame, so we have to use multiple URBs. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/usbmidi.c170
1 files changed, 103 insertions, 67 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index cc17401de95e..32d70cc046e7 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -62,6 +62,7 @@
62 */ 62 */
63#define ERROR_DELAY_JIFFIES (HZ / 10) 63#define ERROR_DELAY_JIFFIES (HZ / 10)
64 64
65#define OUTPUT_URBS 7
65#define INPUT_URBS 7 66#define INPUT_URBS 7
66 67
67 68
@@ -92,7 +93,7 @@ struct snd_usb_midi_endpoint;
92 93
93struct usb_protocol_ops { 94struct usb_protocol_ops {
94 void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int); 95 void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int);
95 void (*output)(struct snd_usb_midi_out_endpoint*); 96 void (*output)(struct snd_usb_midi_out_endpoint *ep, struct urb *urb);
96 void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t); 97 void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
97 void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*); 98 void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*);
98 void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*); 99 void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*);
@@ -118,8 +119,11 @@ struct snd_usb_midi {
118 119
119struct snd_usb_midi_out_endpoint { 120struct snd_usb_midi_out_endpoint {
120 struct snd_usb_midi* umidi; 121 struct snd_usb_midi* umidi;
121 struct urb* urb; 122 struct out_urb_context {
122 int urb_active; 123 struct urb *urb;
124 struct snd_usb_midi_out_endpoint *ep;
125 } urbs[OUTPUT_URBS];
126 unsigned int active_urbs;
123 int max_transfer; /* size of urb buffer */ 127 int max_transfer; /* size of urb buffer */
124 struct tasklet_struct tasklet; 128 struct tasklet_struct tasklet;
125 129
@@ -253,10 +257,11 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
253 257
254static void snd_usbmidi_out_urb_complete(struct urb* urb) 258static void snd_usbmidi_out_urb_complete(struct urb* urb)
255{ 259{
256 struct snd_usb_midi_out_endpoint* ep = urb->context; 260 struct out_urb_context *context = urb->context;
261 struct snd_usb_midi_out_endpoint* ep = context->ep;
257 262
258 spin_lock(&ep->buffer_lock); 263 spin_lock(&ep->buffer_lock);
259 ep->urb_active = 0; 264 ep->active_urbs &= ~(1 << (context - ep->urbs));
260 spin_unlock(&ep->buffer_lock); 265 spin_unlock(&ep->buffer_lock);
261 if (urb->status < 0) { 266 if (urb->status < 0) {
262 int err = snd_usbmidi_urb_error(urb->status); 267 int err = snd_usbmidi_urb_error(urb->status);
@@ -276,23 +281,37 @@ static void snd_usbmidi_out_urb_complete(struct urb* urb)
276 */ 281 */
277static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) 282static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
278{ 283{
279 struct urb* urb = ep->urb; 284 unsigned int urb_index;
285 struct urb* urb;
280 unsigned long flags; 286 unsigned long flags;
281 287
282 spin_lock_irqsave(&ep->buffer_lock, flags); 288 spin_lock_irqsave(&ep->buffer_lock, flags);
283 if (ep->urb_active || ep->umidi->chip->shutdown) { 289 if (ep->umidi->chip->shutdown) {
284 spin_unlock_irqrestore(&ep->buffer_lock, flags); 290 spin_unlock_irqrestore(&ep->buffer_lock, flags);
285 return; 291 return;
286 } 292 }
287 293
288 urb->transfer_buffer_length = 0; 294 for (;;) {
289 ep->umidi->usb_protocol_ops->output(ep); 295 urb = NULL;
296 for (urb_index = 0; urb_index < OUTPUT_URBS; ++urb_index)
297 if (!(ep->active_urbs & (1 << urb_index))) {
298 urb = ep->urbs[urb_index].urb;
299 break;
300 }
301 if (!urb)
302 break;
303
304 urb->transfer_buffer_length = 0;
305 ep->umidi->usb_protocol_ops->output(ep, urb);
306 if (urb->transfer_buffer_length == 0)
307 break;
290 308
291 if (urb->transfer_buffer_length > 0) {
292 dump_urb("sending", urb->transfer_buffer, 309 dump_urb("sending", urb->transfer_buffer,
293 urb->transfer_buffer_length); 310 urb->transfer_buffer_length);
294 urb->dev = ep->umidi->chip->dev; 311 urb->dev = ep->umidi->chip->dev;
295 ep->urb_active = snd_usbmidi_submit_urb(urb, GFP_ATOMIC) >= 0; 312 if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0)
313 break;
314 ep->active_urbs |= 1 << urb_index;
296 } 315 }
297 spin_unlock_irqrestore(&ep->buffer_lock, flags); 316 spin_unlock_irqrestore(&ep->buffer_lock, flags);
298} 317}
@@ -334,13 +353,14 @@ static void snd_usbmidi_error_timer(unsigned long data)
334static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep, 353static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
335 const void *data, int len) 354 const void *data, int len)
336{ 355{
337 int err; 356 int err = 0;
338 void *buf = kmemdup(data, len, GFP_KERNEL); 357 void *buf = kmemdup(data, len, GFP_KERNEL);
339 if (!buf) 358 if (!buf)
340 return -ENOMEM; 359 return -ENOMEM;
341 dump_urb("sending", buf, len); 360 dump_urb("sending", buf, len);
342 err = usb_bulk_msg(ep->umidi->chip->dev, ep->urb->pipe, buf, len, 361 if (ep->urbs[0].urb)
343 NULL, 250); 362 err = usb_bulk_msg(ep->umidi->chip->dev, ep->urbs[0].urb->pipe,
363 buf, len, NULL, 250);
344 kfree(buf); 364 kfree(buf);
345 return err; 365 return err;
346} 366}
@@ -558,9 +578,9 @@ static void snd_usbmidi_transmit_byte(struct usbmidi_out_port* port,
558 } 578 }
559} 579}
560 580
561static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep) 581static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep,
582 struct urb *urb)
562{ 583{
563 struct urb* urb = ep->urb;
564 int p; 584 int p;
565 585
566 /* FIXME: lower-numbered ports can starve higher-numbered ports */ 586 /* FIXME: lower-numbered ports can starve higher-numbered ports */
@@ -617,14 +637,15 @@ static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint* ep,
617 snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1); 637 snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1);
618} 638}
619 639
620static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep) 640static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep,
641 struct urb *urb)
621{ 642{
622 uint8_t* transfer_buffer; 643 uint8_t* transfer_buffer;
623 int count; 644 int count;
624 645
625 if (!ep->ports[0].active) 646 if (!ep->ports[0].active)
626 return; 647 return;
627 transfer_buffer = ep->urb->transfer_buffer; 648 transfer_buffer = urb->transfer_buffer;
628 count = snd_rawmidi_transmit(ep->ports[0].substream, 649 count = snd_rawmidi_transmit(ep->ports[0].substream,
629 &transfer_buffer[2], 650 &transfer_buffer[2],
630 ep->max_transfer - 2); 651 ep->max_transfer - 2);
@@ -634,7 +655,7 @@ static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep)
634 } 655 }
635 transfer_buffer[0] = 0; 656 transfer_buffer[0] = 0;
636 transfer_buffer[1] = count; 657 transfer_buffer[1] = count;
637 ep->urb->transfer_buffer_length = 2 + count; 658 urb->transfer_buffer_length = 2 + count;
638} 659}
639 660
640static struct usb_protocol_ops snd_usbmidi_novation_ops = { 661static struct usb_protocol_ops snd_usbmidi_novation_ops = {
@@ -652,20 +673,21 @@ static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep,
652 snd_usbmidi_input_data(ep, 0, buffer, buffer_length); 673 snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
653} 674}
654 675
655static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep) 676static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep,
677 struct urb *urb)
656{ 678{
657 int count; 679 int count;
658 680
659 if (!ep->ports[0].active) 681 if (!ep->ports[0].active)
660 return; 682 return;
661 count = snd_rawmidi_transmit(ep->ports[0].substream, 683 count = snd_rawmidi_transmit(ep->ports[0].substream,
662 ep->urb->transfer_buffer, 684 urb->transfer_buffer,
663 ep->max_transfer); 685 ep->max_transfer);
664 if (count < 1) { 686 if (count < 1) {
665 ep->ports[0].active = 0; 687 ep->ports[0].active = 0;
666 return; 688 return;
667 } 689 }
668 ep->urb->transfer_buffer_length = count; 690 urb->transfer_buffer_length = count;
669} 691}
670 692
671static struct usb_protocol_ops snd_usbmidi_raw_ops = { 693static struct usb_protocol_ops snd_usbmidi_raw_ops = {
@@ -685,23 +707,25 @@ static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep,
685 snd_usbmidi_input_data(ep, 0, buffer, buffer_length); 707 snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
686} 708}
687 709
688static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep) 710static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
711 struct urb *urb)
689{ 712{
690 int count; 713 int count;
691 714
692 if (!ep->ports[0].active) 715 if (!ep->ports[0].active)
693 return; 716 return;
694 count = ep->urb->dev->speed == USB_SPEED_HIGH ? 1 : 2; 717 count = snd_usb_get_speed(ep->umidi->chip->dev) == USB_SPEED_HIGH
718 ? 1 : 2;
695 count = snd_rawmidi_transmit(ep->ports[0].substream, 719 count = snd_rawmidi_transmit(ep->ports[0].substream,
696 ep->urb->transfer_buffer, 720 urb->transfer_buffer,
697 count); 721 count);
698 if (count < 1) { 722 if (count < 1) {
699 ep->ports[0].active = 0; 723 ep->ports[0].active = 0;
700 return; 724 return;
701 } 725 }
702 726
703 memset(ep->urb->transfer_buffer + count, 0xFD, 9 - count); 727 memset(urb->transfer_buffer + count, 0xFD, 9 - count);
704 ep->urb->transfer_buffer_length = count; 728 urb->transfer_buffer_length = count;
705} 729}
706 730
707static struct usb_protocol_ops snd_usbmidi_122l_ops = { 731static struct usb_protocol_ops snd_usbmidi_122l_ops = {
@@ -790,10 +814,11 @@ static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint* ep,
790 } 814 }
791} 815}
792 816
793static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep) 817static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep,
818 struct urb *urb)
794{ 819{
795 int port0 = ep->current_port; 820 int port0 = ep->current_port;
796 uint8_t* buf = ep->urb->transfer_buffer; 821 uint8_t* buf = urb->transfer_buffer;
797 int buf_free = ep->max_transfer; 822 int buf_free = ep->max_transfer;
798 int length, i; 823 int length, i;
799 824
@@ -833,7 +858,7 @@ static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep)
833 *buf = 0xff; 858 *buf = 0xff;
834 --buf_free; 859 --buf_free;
835 } 860 }
836 ep->urb->transfer_buffer_length = ep->max_transfer - buf_free; 861 urb->transfer_buffer_length = ep->max_transfer - buf_free;
837} 862}
838 863
839static struct usb_protocol_ops snd_usbmidi_emagic_ops = { 864static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
@@ -920,6 +945,14 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
920 .trigger = snd_usbmidi_input_trigger 945 .trigger = snd_usbmidi_input_trigger
921}; 946};
922 947
948static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
949 unsigned int buffer_length)
950{
951 usb_buffer_free(umidi->chip->dev, buffer_length,
952 urb->transfer_buffer, urb->transfer_dma);
953 usb_free_urb(urb);
954}
955
923/* 956/*
924 * Frees an input endpoint. 957 * Frees an input endpoint.
925 * May be called when ep hasn't been initialized completely. 958 * May be called when ep hasn't been initialized completely.
@@ -928,15 +961,10 @@ static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint* ep)
928{ 961{
929 unsigned int i; 962 unsigned int i;
930 963
931 for (i = 0; i < INPUT_URBS; ++i) { 964 for (i = 0; i < INPUT_URBS; ++i)
932 if (ep->urbs[i]) { 965 if (ep->urbs[i])
933 usb_buffer_free(ep->umidi->chip->dev, 966 free_urb_and_buffer(ep->umidi, ep->urbs[i],
934 ep->urbs[i]->transfer_buffer_length, 967 ep->urbs[i]->transfer_buffer_length);
935 ep->urbs[i]->transfer_buffer,
936 ep->urbs[i]->transfer_dma);
937 usb_free_urb(ep->urbs[i]);
938 }
939 }
940 kfree(ep); 968 kfree(ep);
941} 969}
942 970
@@ -1009,12 +1037,12 @@ static unsigned int snd_usbmidi_count_bits(unsigned int x)
1009 */ 1037 */
1010static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) 1038static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
1011{ 1039{
1012 if (ep->urb) { 1040 unsigned int i;
1013 usb_buffer_free(ep->umidi->chip->dev, ep->max_transfer, 1041
1014 ep->urb->transfer_buffer, 1042 for (i = 0; i < OUTPUT_URBS; ++i)
1015 ep->urb->transfer_dma); 1043 if (ep->urbs[i].urb)
1016 usb_free_urb(ep->urb); 1044 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
1017 } 1045 ep->max_transfer);
1018 kfree(ep); 1046 kfree(ep);
1019} 1047}
1020 1048
@@ -1026,7 +1054,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1026 struct snd_usb_midi_endpoint* rep) 1054 struct snd_usb_midi_endpoint* rep)
1027{ 1055{
1028 struct snd_usb_midi_out_endpoint* ep; 1056 struct snd_usb_midi_out_endpoint* ep;
1029 int i; 1057 unsigned int i;
1030 unsigned int pipe; 1058 unsigned int pipe;
1031 void* buffer; 1059 void* buffer;
1032 1060
@@ -1036,35 +1064,42 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1036 return -ENOMEM; 1064 return -ENOMEM;
1037 ep->umidi = umidi; 1065 ep->umidi = umidi;
1038 1066
1039 ep->urb = usb_alloc_urb(0, GFP_KERNEL); 1067 for (i = 0; i < OUTPUT_URBS; ++i) {
1040 if (!ep->urb) { 1068 ep->urbs[i].urb = usb_alloc_urb(0, GFP_KERNEL);
1041 snd_usbmidi_out_endpoint_delete(ep); 1069 if (!ep->urbs[i].urb) {
1042 return -ENOMEM; 1070 snd_usbmidi_out_endpoint_delete(ep);
1071 return -ENOMEM;
1072 }
1073 ep->urbs[i].ep = ep;
1043 } 1074 }
1044 if (ep_info->out_interval) 1075 if (ep_info->out_interval)
1045 pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep); 1076 pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep);
1046 else 1077 else
1047 pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); 1078 pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep);
1048 if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ 1079 if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
1049 /* FIXME: we need more URBs to get reasonable bandwidth here: */
1050 ep->max_transfer = 4; 1080 ep->max_transfer = 4;
1051 else 1081 else
1052 ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); 1082 ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1);
1053 buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, 1083 for (i = 0; i < OUTPUT_URBS; ++i) {
1054 GFP_KERNEL, &ep->urb->transfer_dma); 1084 buffer = usb_buffer_alloc(umidi->chip->dev,
1055 if (!buffer) { 1085 ep->max_transfer, GFP_KERNEL,
1056 snd_usbmidi_out_endpoint_delete(ep); 1086 &ep->urbs[i].urb->transfer_dma);
1057 return -ENOMEM; 1087 if (!buffer) {
1088 snd_usbmidi_out_endpoint_delete(ep);
1089 return -ENOMEM;
1090 }
1091 if (ep_info->out_interval)
1092 usb_fill_int_urb(ep->urbs[i].urb, umidi->chip->dev,
1093 pipe, buffer, ep->max_transfer,
1094 snd_usbmidi_out_urb_complete,
1095 &ep->urbs[i], ep_info->out_interval);
1096 else
1097 usb_fill_bulk_urb(ep->urbs[i].urb, umidi->chip->dev,
1098 pipe, buffer, ep->max_transfer,
1099 snd_usbmidi_out_urb_complete,
1100 &ep->urbs[i]);
1101 ep->urbs[i].urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
1058 } 1102 }
1059 if (ep_info->out_interval)
1060 usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer,
1061 ep->max_transfer, snd_usbmidi_out_urb_complete,
1062 ep, ep_info->out_interval);
1063 else
1064 usb_fill_bulk_urb(ep->urb, umidi->chip->dev,
1065 pipe, buffer, ep->max_transfer,
1066 snd_usbmidi_out_urb_complete, ep);
1067 ep->urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
1068 1103
1069 spin_lock_init(&ep->buffer_lock); 1104 spin_lock_init(&ep->buffer_lock);
1070 tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); 1105 tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep);
@@ -1120,8 +1155,9 @@ void snd_usbmidi_disconnect(struct list_head* p)
1120 struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; 1155 struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
1121 if (ep->out) 1156 if (ep->out)
1122 tasklet_kill(&ep->out->tasklet); 1157 tasklet_kill(&ep->out->tasklet);
1123 if (ep->out && ep->out->urb) { 1158 if (ep->out) {
1124 usb_kill_urb(ep->out->urb); 1159 for (j = 0; j < OUTPUT_URBS; ++j)
1160 usb_kill_urb(ep->out->urbs[j].urb);
1125 if (umidi->usb_protocol_ops->finish_out_endpoint) 1161 if (umidi->usb_protocol_ops->finish_out_endpoint)
1126 umidi->usb_protocol_ops->finish_out_endpoint(ep->out); 1162 umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
1127 } 1163 }