diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /sound/usb/usbmidi.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r-- | sound/usb/usbmidi.c | 262 |
1 files changed, 198 insertions, 64 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 0eff19ceb7e1..9e28b20cb2ce 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * usbmidi.c - ALSA USB MIDI driver | 2 | * usbmidi.c - ALSA USB MIDI driver |
3 | * | 3 | * |
4 | * Copyright (c) 2002-2007 Clemens Ladisch | 4 | * Copyright (c) 2002-2009 Clemens Ladisch |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Based on the OSS usb-midi driver by NAGANO Daisuke, | 7 | * Based on the OSS usb-midi driver by NAGANO Daisuke, |
@@ -46,7 +46,10 @@ | |||
46 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/wait.h> | 48 | #include <linux/wait.h> |
49 | #include <linux/usb/audio.h> | ||
50 | |||
49 | #include <sound/core.h> | 51 | #include <sound/core.h> |
52 | #include <sound/control.h> | ||
50 | #include <sound/rawmidi.h> | 53 | #include <sound/rawmidi.h> |
51 | #include <sound/asequencer.h> | 54 | #include <sound/asequencer.h> |
52 | #include "usbaudio.h" | 55 | #include "usbaudio.h" |
@@ -101,7 +104,8 @@ struct usb_protocol_ops { | |||
101 | }; | 104 | }; |
102 | 105 | ||
103 | struct snd_usb_midi { | 106 | struct snd_usb_midi { |
104 | struct snd_usb_audio *chip; | 107 | struct usb_device *dev; |
108 | struct snd_card *card; | ||
105 | struct usb_interface *iface; | 109 | struct usb_interface *iface; |
106 | const struct snd_usb_audio_quirk *quirk; | 110 | const struct snd_usb_audio_quirk *quirk; |
107 | struct snd_rawmidi *rmidi; | 111 | struct snd_rawmidi *rmidi; |
@@ -109,13 +113,19 @@ struct snd_usb_midi { | |||
109 | struct list_head list; | 113 | struct list_head list; |
110 | struct timer_list error_timer; | 114 | struct timer_list error_timer; |
111 | spinlock_t disc_lock; | 115 | spinlock_t disc_lock; |
116 | struct mutex mutex; | ||
117 | u32 usb_id; | ||
118 | int next_midi_device; | ||
112 | 119 | ||
113 | struct snd_usb_midi_endpoint { | 120 | struct snd_usb_midi_endpoint { |
114 | struct snd_usb_midi_out_endpoint *out; | 121 | struct snd_usb_midi_out_endpoint *out; |
115 | struct snd_usb_midi_in_endpoint *in; | 122 | struct snd_usb_midi_in_endpoint *in; |
116 | } endpoints[MIDI_MAX_ENDPOINTS]; | 123 | } endpoints[MIDI_MAX_ENDPOINTS]; |
117 | unsigned long input_triggered; | 124 | unsigned long input_triggered; |
125 | unsigned int opened; | ||
118 | unsigned char disconnected; | 126 | unsigned char disconnected; |
127 | |||
128 | struct snd_kcontrol *roland_load_ctl; | ||
119 | }; | 129 | }; |
120 | 130 | ||
121 | struct snd_usb_midi_out_endpoint { | 131 | struct snd_usb_midi_out_endpoint { |
@@ -255,7 +265,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb) | |||
255 | } | 265 | } |
256 | } | 266 | } |
257 | 267 | ||
258 | urb->dev = ep->umidi->chip->dev; | 268 | urb->dev = ep->umidi->dev; |
259 | snd_usbmidi_submit_urb(urb, GFP_ATOMIC); | 269 | snd_usbmidi_submit_urb(urb, GFP_ATOMIC); |
260 | } | 270 | } |
261 | 271 | ||
@@ -296,7 +306,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) | |||
296 | unsigned long flags; | 306 | unsigned long flags; |
297 | 307 | ||
298 | spin_lock_irqsave(&ep->buffer_lock, flags); | 308 | spin_lock_irqsave(&ep->buffer_lock, flags); |
299 | if (ep->umidi->chip->shutdown) { | 309 | if (ep->umidi->disconnected) { |
300 | spin_unlock_irqrestore(&ep->buffer_lock, flags); | 310 | spin_unlock_irqrestore(&ep->buffer_lock, flags); |
301 | return; | 311 | return; |
302 | } | 312 | } |
@@ -312,7 +322,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) | |||
312 | 322 | ||
313 | dump_urb("sending", urb->transfer_buffer, | 323 | dump_urb("sending", urb->transfer_buffer, |
314 | urb->transfer_buffer_length); | 324 | urb->transfer_buffer_length); |
315 | urb->dev = ep->umidi->chip->dev; | 325 | urb->dev = ep->umidi->dev; |
316 | if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) | 326 | if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) |
317 | break; | 327 | break; |
318 | ep->active_urbs |= 1 << urb_index; | 328 | ep->active_urbs |= 1 << urb_index; |
@@ -349,7 +359,7 @@ static void snd_usbmidi_error_timer(unsigned long data) | |||
349 | if (in && in->error_resubmit) { | 359 | if (in && in->error_resubmit) { |
350 | in->error_resubmit = 0; | 360 | in->error_resubmit = 0; |
351 | for (j = 0; j < INPUT_URBS; ++j) { | 361 | for (j = 0; j < INPUT_URBS; ++j) { |
352 | in->urbs[j]->dev = umidi->chip->dev; | 362 | in->urbs[j]->dev = umidi->dev; |
353 | snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); | 363 | snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); |
354 | } | 364 | } |
355 | } | 365 | } |
@@ -369,7 +379,7 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep, | |||
369 | return -ENOMEM; | 379 | return -ENOMEM; |
370 | dump_urb("sending", buf, len); | 380 | dump_urb("sending", buf, len); |
371 | if (ep->urbs[0].urb) | 381 | if (ep->urbs[0].urb) |
372 | err = usb_bulk_msg(ep->umidi->chip->dev, ep->urbs[0].urb->pipe, | 382 | err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe, |
373 | buf, len, NULL, 250); | 383 | buf, len, NULL, 250); |
374 | kfree(buf); | 384 | kfree(buf); |
375 | return err; | 385 | return err; |
@@ -724,8 +734,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep, | |||
724 | 734 | ||
725 | if (!ep->ports[0].active) | 735 | if (!ep->ports[0].active) |
726 | return; | 736 | return; |
727 | count = snd_usb_get_speed(ep->umidi->chip->dev) == USB_SPEED_HIGH | 737 | count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; |
728 | ? 1 : 2; | ||
729 | count = snd_rawmidi_transmit(ep->ports[0].substream, | 738 | count = snd_rawmidi_transmit(ep->ports[0].substream, |
730 | urb->transfer_buffer, | 739 | urb->transfer_buffer, |
731 | count); | 740 | count); |
@@ -879,6 +888,50 @@ static struct usb_protocol_ops snd_usbmidi_emagic_ops = { | |||
879 | }; | 888 | }; |
880 | 889 | ||
881 | 890 | ||
891 | static void update_roland_altsetting(struct snd_usb_midi* umidi) | ||
892 | { | ||
893 | struct usb_interface *intf; | ||
894 | struct usb_host_interface *hostif; | ||
895 | struct usb_interface_descriptor *intfd; | ||
896 | int is_light_load; | ||
897 | |||
898 | intf = umidi->iface; | ||
899 | is_light_load = intf->cur_altsetting != intf->altsetting; | ||
900 | if (umidi->roland_load_ctl->private_value == is_light_load) | ||
901 | return; | ||
902 | hostif = &intf->altsetting[umidi->roland_load_ctl->private_value]; | ||
903 | intfd = get_iface_desc(hostif); | ||
904 | snd_usbmidi_input_stop(&umidi->list); | ||
905 | usb_set_interface(umidi->dev, intfd->bInterfaceNumber, | ||
906 | intfd->bAlternateSetting); | ||
907 | snd_usbmidi_input_start(&umidi->list); | ||
908 | } | ||
909 | |||
910 | static void substream_open(struct snd_rawmidi_substream *substream, int open) | ||
911 | { | ||
912 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | ||
913 | struct snd_kcontrol *ctl; | ||
914 | |||
915 | mutex_lock(&umidi->mutex); | ||
916 | if (open) { | ||
917 | if (umidi->opened++ == 0 && umidi->roland_load_ctl) { | ||
918 | ctl = umidi->roland_load_ctl; | ||
919 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
920 | snd_ctl_notify(umidi->card, | ||
921 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
922 | update_roland_altsetting(umidi); | ||
923 | } | ||
924 | } else { | ||
925 | if (--umidi->opened == 0 && umidi->roland_load_ctl) { | ||
926 | ctl = umidi->roland_load_ctl; | ||
927 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
928 | snd_ctl_notify(umidi->card, | ||
929 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
930 | } | ||
931 | } | ||
932 | mutex_unlock(&umidi->mutex); | ||
933 | } | ||
934 | |||
882 | static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | 935 | static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) |
883 | { | 936 | { |
884 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 937 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
@@ -898,11 +951,13 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
898 | } | 951 | } |
899 | substream->runtime->private_data = port; | 952 | substream->runtime->private_data = port; |
900 | port->state = STATE_UNKNOWN; | 953 | port->state = STATE_UNKNOWN; |
954 | substream_open(substream, 1); | ||
901 | return 0; | 955 | return 0; |
902 | } | 956 | } |
903 | 957 | ||
904 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) | 958 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) |
905 | { | 959 | { |
960 | substream_open(substream, 0); | ||
906 | return 0; | 961 | return 0; |
907 | } | 962 | } |
908 | 963 | ||
@@ -912,7 +967,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, | |||
912 | 967 | ||
913 | port->active = up; | 968 | port->active = up; |
914 | if (up) { | 969 | if (up) { |
915 | if (port->ep->umidi->chip->shutdown) { | 970 | if (port->ep->umidi->disconnected) { |
916 | /* gobble up remaining bytes to prevent wait in | 971 | /* gobble up remaining bytes to prevent wait in |
917 | * snd_rawmidi_drain_output */ | 972 | * snd_rawmidi_drain_output */ |
918 | while (!snd_rawmidi_transmit_empty(substream)) | 973 | while (!snd_rawmidi_transmit_empty(substream)) |
@@ -931,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
931 | DEFINE_WAIT(wait); | 986 | DEFINE_WAIT(wait); |
932 | long timeout = msecs_to_jiffies(50); | 987 | long timeout = msecs_to_jiffies(50); |
933 | 988 | ||
989 | if (ep->umidi->disconnected) | ||
990 | return; | ||
934 | /* | 991 | /* |
935 | * The substream buffer is empty, but some data might still be in the | 992 | * The substream buffer is empty, but some data might still be in the |
936 | * currently active URBs, so we have to wait for those to complete. | 993 | * currently active URBs, so we have to wait for those to complete. |
@@ -954,11 +1011,13 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
954 | 1011 | ||
955 | static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) | 1012 | static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) |
956 | { | 1013 | { |
1014 | substream_open(substream, 1); | ||
957 | return 0; | 1015 | return 0; |
958 | } | 1016 | } |
959 | 1017 | ||
960 | static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) | 1018 | static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) |
961 | { | 1019 | { |
1020 | substream_open(substream, 0); | ||
962 | return 0; | 1021 | return 0; |
963 | } | 1022 | } |
964 | 1023 | ||
@@ -988,7 +1047,7 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = { | |||
988 | static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, | 1047 | static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, |
989 | unsigned int buffer_length) | 1048 | unsigned int buffer_length) |
990 | { | 1049 | { |
991 | usb_buffer_free(umidi->chip->dev, buffer_length, | 1050 | usb_buffer_free(umidi->dev, buffer_length, |
992 | urb->transfer_buffer, urb->transfer_dma); | 1051 | urb->transfer_buffer, urb->transfer_dma); |
993 | usb_free_urb(urb); | 1052 | usb_free_urb(urb); |
994 | } | 1053 | } |
@@ -1035,24 +1094,24 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1035 | } | 1094 | } |
1036 | } | 1095 | } |
1037 | if (ep_info->in_interval) | 1096 | if (ep_info->in_interval) |
1038 | pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); | 1097 | pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep); |
1039 | else | 1098 | else |
1040 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); | 1099 | pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep); |
1041 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); | 1100 | length = usb_maxpacket(umidi->dev, pipe, 0); |
1042 | for (i = 0; i < INPUT_URBS; ++i) { | 1101 | for (i = 0; i < INPUT_URBS; ++i) { |
1043 | buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, | 1102 | buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL, |
1044 | &ep->urbs[i]->transfer_dma); | 1103 | &ep->urbs[i]->transfer_dma); |
1045 | if (!buffer) { | 1104 | if (!buffer) { |
1046 | snd_usbmidi_in_endpoint_delete(ep); | 1105 | snd_usbmidi_in_endpoint_delete(ep); |
1047 | return -ENOMEM; | 1106 | return -ENOMEM; |
1048 | } | 1107 | } |
1049 | if (ep_info->in_interval) | 1108 | if (ep_info->in_interval) |
1050 | usb_fill_int_urb(ep->urbs[i], umidi->chip->dev, | 1109 | usb_fill_int_urb(ep->urbs[i], umidi->dev, |
1051 | pipe, buffer, length, | 1110 | pipe, buffer, length, |
1052 | snd_usbmidi_in_urb_complete, | 1111 | snd_usbmidi_in_urb_complete, |
1053 | ep, ep_info->in_interval); | 1112 | ep, ep_info->in_interval); |
1054 | else | 1113 | else |
1055 | usb_fill_bulk_urb(ep->urbs[i], umidi->chip->dev, | 1114 | usb_fill_bulk_urb(ep->urbs[i], umidi->dev, |
1056 | pipe, buffer, length, | 1115 | pipe, buffer, length, |
1057 | snd_usbmidi_in_urb_complete, ep); | 1116 | snd_usbmidi_in_urb_complete, ep); |
1058 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 1117 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
@@ -1062,27 +1121,25 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1062 | return 0; | 1121 | return 0; |
1063 | } | 1122 | } |
1064 | 1123 | ||
1065 | static unsigned int snd_usbmidi_count_bits(unsigned int x) | ||
1066 | { | ||
1067 | unsigned int bits; | ||
1068 | |||
1069 | for (bits = 0; x; ++bits) | ||
1070 | x &= x - 1; | ||
1071 | return bits; | ||
1072 | } | ||
1073 | |||
1074 | /* | 1124 | /* |
1075 | * Frees an output endpoint. | 1125 | * Frees an output endpoint. |
1076 | * May be called when ep hasn't been initialized completely. | 1126 | * May be called when ep hasn't been initialized completely. |
1077 | */ | 1127 | */ |
1078 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) | 1128 | static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) |
1079 | { | 1129 | { |
1080 | unsigned int i; | 1130 | unsigned int i; |
1081 | 1131 | ||
1082 | for (i = 0; i < OUTPUT_URBS; ++i) | 1132 | for (i = 0; i < OUTPUT_URBS; ++i) |
1083 | if (ep->urbs[i].urb) | 1133 | if (ep->urbs[i].urb) { |
1084 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, | 1134 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, |
1085 | ep->max_transfer); | 1135 | ep->max_transfer); |
1136 | ep->urbs[i].urb = NULL; | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) | ||
1141 | { | ||
1142 | snd_usbmidi_out_endpoint_clear(ep); | ||
1086 | kfree(ep); | 1143 | kfree(ep); |
1087 | } | 1144 | } |
1088 | 1145 | ||
@@ -1113,15 +1170,27 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
1113 | ep->urbs[i].ep = ep; | 1170 | ep->urbs[i].ep = ep; |
1114 | } | 1171 | } |
1115 | if (ep_info->out_interval) | 1172 | if (ep_info->out_interval) |
1116 | pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep); | 1173 | pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep); |
1117 | else | 1174 | else |
1118 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | 1175 | pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep); |
1119 | if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ | 1176 | switch (umidi->usb_id) { |
1177 | default: | ||
1178 | ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); | ||
1179 | break; | ||
1180 | /* | ||
1181 | * Various chips declare a packet size larger than 4 bytes, but | ||
1182 | * do not actually work with larger packets: | ||
1183 | */ | ||
1184 | case USB_ID(0x0a92, 0x1020): /* ESI M4U */ | ||
1185 | case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ | ||
1186 | case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ | ||
1187 | case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */ | ||
1188 | case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ | ||
1120 | ep->max_transfer = 4; | 1189 | ep->max_transfer = 4; |
1121 | else | 1190 | break; |
1122 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | 1191 | } |
1123 | for (i = 0; i < OUTPUT_URBS; ++i) { | 1192 | for (i = 0; i < OUTPUT_URBS; ++i) { |
1124 | buffer = usb_buffer_alloc(umidi->chip->dev, | 1193 | buffer = usb_buffer_alloc(umidi->dev, |
1125 | ep->max_transfer, GFP_KERNEL, | 1194 | ep->max_transfer, GFP_KERNEL, |
1126 | &ep->urbs[i].urb->transfer_dma); | 1195 | &ep->urbs[i].urb->transfer_dma); |
1127 | if (!buffer) { | 1196 | if (!buffer) { |
@@ -1129,12 +1198,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
1129 | return -ENOMEM; | 1198 | return -ENOMEM; |
1130 | } | 1199 | } |
1131 | if (ep_info->out_interval) | 1200 | if (ep_info->out_interval) |
1132 | usb_fill_int_urb(ep->urbs[i].urb, umidi->chip->dev, | 1201 | usb_fill_int_urb(ep->urbs[i].urb, umidi->dev, |
1133 | pipe, buffer, ep->max_transfer, | 1202 | pipe, buffer, ep->max_transfer, |
1134 | snd_usbmidi_out_urb_complete, | 1203 | snd_usbmidi_out_urb_complete, |
1135 | &ep->urbs[i], ep_info->out_interval); | 1204 | &ep->urbs[i], ep_info->out_interval); |
1136 | else | 1205 | else |
1137 | usb_fill_bulk_urb(ep->urbs[i].urb, umidi->chip->dev, | 1206 | usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev, |
1138 | pipe, buffer, ep->max_transfer, | 1207 | pipe, buffer, ep->max_transfer, |
1139 | snd_usbmidi_out_urb_complete, | 1208 | snd_usbmidi_out_urb_complete, |
1140 | &ep->urbs[i]); | 1209 | &ep->urbs[i]); |
@@ -1172,6 +1241,7 @@ static void snd_usbmidi_free(struct snd_usb_midi* umidi) | |||
1172 | if (ep->in) | 1241 | if (ep->in) |
1173 | snd_usbmidi_in_endpoint_delete(ep->in); | 1242 | snd_usbmidi_in_endpoint_delete(ep->in); |
1174 | } | 1243 | } |
1244 | mutex_destroy(&umidi->mutex); | ||
1175 | kfree(umidi); | 1245 | kfree(umidi); |
1176 | } | 1246 | } |
1177 | 1247 | ||
@@ -1201,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1201 | usb_kill_urb(ep->out->urbs[j].urb); | 1271 | usb_kill_urb(ep->out->urbs[j].urb); |
1202 | if (umidi->usb_protocol_ops->finish_out_endpoint) | 1272 | if (umidi->usb_protocol_ops->finish_out_endpoint) |
1203 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); | 1273 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); |
1274 | ep->out->active_urbs = 0; | ||
1275 | if (ep->out->drain_urbs) { | ||
1276 | ep->out->drain_urbs = 0; | ||
1277 | wake_up(&ep->out->drain_wait); | ||
1278 | } | ||
1204 | } | 1279 | } |
1205 | if (ep->in) | 1280 | if (ep->in) |
1206 | for (j = 0; j < INPUT_URBS; ++j) | 1281 | for (j = 0; j < INPUT_URBS; ++j) |
1207 | usb_kill_urb(ep->in->urbs[j]); | 1282 | usb_kill_urb(ep->in->urbs[j]); |
1208 | /* free endpoints here; later call can result in Oops */ | 1283 | /* free endpoints here; later call can result in Oops */ |
1209 | if (ep->out) { | 1284 | if (ep->out) |
1210 | snd_usbmidi_out_endpoint_delete(ep->out); | 1285 | snd_usbmidi_out_endpoint_clear(ep->out); |
1211 | ep->out = NULL; | ||
1212 | } | ||
1213 | if (ep->in) { | 1286 | if (ep->in) { |
1214 | snd_usbmidi_in_endpoint_delete(ep->in); | 1287 | snd_usbmidi_in_endpoint_delete(ep->in); |
1215 | ep->in = NULL; | 1288 | ep->in = NULL; |
@@ -1360,6 +1433,12 @@ static struct port_info { | |||
1360 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), | 1433 | EXTERNAL_PORT(0x086a, 0x0001, 8, "%s Broadcast"), |
1361 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), | 1434 | EXTERNAL_PORT(0x086a, 0x0002, 8, "%s Broadcast"), |
1362 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), | 1435 | EXTERNAL_PORT(0x086a, 0x0003, 4, "%s Broadcast"), |
1436 | /* Access Music Virus TI */ | ||
1437 | EXTERNAL_PORT(0x133e, 0x0815, 0, "%s MIDI"), | ||
1438 | PORT_INFO(0x133e, 0x0815, 1, "%s Synth", 0, | ||
1439 | SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | | ||
1440 | SNDRV_SEQ_PORT_TYPE_HARDWARE | | ||
1441 | SNDRV_SEQ_PORT_TYPE_SYNTHESIZER), | ||
1363 | }; | 1442 | }; |
1364 | 1443 | ||
1365 | static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) | 1444 | static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) |
@@ -1367,7 +1446,7 @@ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) | |||
1367 | int i; | 1446 | int i; |
1368 | 1447 | ||
1369 | for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { | 1448 | for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { |
1370 | if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id && | 1449 | if (snd_usbmidi_port_info[i].id == umidi->usb_id && |
1371 | snd_usbmidi_port_info[i].port == number) | 1450 | snd_usbmidi_port_info[i].port == number) |
1372 | return &snd_usbmidi_port_info[i]; | 1451 | return &snd_usbmidi_port_info[i]; |
1373 | } | 1452 | } |
@@ -1405,7 +1484,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi, | |||
1405 | port_info = find_port_info(umidi, number); | 1484 | port_info = find_port_info(umidi, number); |
1406 | name_format = port_info ? port_info->name : "%s MIDI %d"; | 1485 | name_format = port_info ? port_info->name : "%s MIDI %d"; |
1407 | snprintf(substream->name, sizeof(substream->name), | 1486 | snprintf(substream->name, sizeof(substream->name), |
1408 | name_format, umidi->chip->card->shortname, number + 1); | 1487 | name_format, umidi->card->shortname, number + 1); |
1409 | 1488 | ||
1410 | *rsubstream = substream; | 1489 | *rsubstream = substream; |
1411 | } | 1490 | } |
@@ -1475,7 +1554,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1475 | if (hostif->extralen >= 7 && | 1554 | if (hostif->extralen >= 7 && |
1476 | ms_header->bLength >= 7 && | 1555 | ms_header->bLength >= 7 && |
1477 | ms_header->bDescriptorType == USB_DT_CS_INTERFACE && | 1556 | ms_header->bDescriptorType == USB_DT_CS_INTERFACE && |
1478 | ms_header->bDescriptorSubtype == HEADER) | 1557 | ms_header->bDescriptorSubtype == UAC_HEADER) |
1479 | snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", | 1558 | snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", |
1480 | ms_header->bcdMSC[1], ms_header->bcdMSC[0]); | 1559 | ms_header->bcdMSC[1], ms_header->bcdMSC[0]); |
1481 | else | 1560 | else |
@@ -1491,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1491 | if (hostep->extralen < 4 || | 1570 | if (hostep->extralen < 4 || |
1492 | ms_ep->bLength < 4 || | 1571 | ms_ep->bLength < 4 || |
1493 | ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || | 1572 | ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || |
1494 | ms_ep->bDescriptorSubtype != MS_GENERAL) | 1573 | ms_ep->bDescriptorSubtype != UAC_MS_GENERAL) |
1495 | continue; | 1574 | continue; |
1496 | if (usb_endpoint_dir_out(ep)) { | 1575 | if (usb_endpoint_dir_out(ep)) { |
1497 | if (endpoints[epidx].out_ep) { | 1576 | if (endpoints[epidx].out_ep) { |
@@ -1503,7 +1582,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1503 | endpoints[epidx].out_ep = usb_endpoint_num(ep); | 1582 | endpoints[epidx].out_ep = usb_endpoint_num(ep); |
1504 | if (usb_endpoint_xfer_int(ep)) | 1583 | if (usb_endpoint_xfer_int(ep)) |
1505 | endpoints[epidx].out_interval = ep->bInterval; | 1584 | endpoints[epidx].out_interval = ep->bInterval; |
1506 | else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) | 1585 | else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW) |
1507 | /* | 1586 | /* |
1508 | * Low speed bulk transfers don't exist, so | 1587 | * Low speed bulk transfers don't exist, so |
1509 | * force interrupt transfers for devices like | 1588 | * force interrupt transfers for devices like |
@@ -1523,7 +1602,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1523 | endpoints[epidx].in_ep = usb_endpoint_num(ep); | 1602 | endpoints[epidx].in_ep = usb_endpoint_num(ep); |
1524 | if (usb_endpoint_xfer_int(ep)) | 1603 | if (usb_endpoint_xfer_int(ep)) |
1525 | endpoints[epidx].in_interval = ep->bInterval; | 1604 | endpoints[epidx].in_interval = ep->bInterval; |
1526 | else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) | 1605 | else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW) |
1527 | endpoints[epidx].in_interval = 1; | 1606 | endpoints[epidx].in_interval = 1; |
1528 | endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; | 1607 | endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; |
1529 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", | 1608 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", |
@@ -1533,6 +1612,52 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1533 | return 0; | 1612 | return 0; |
1534 | } | 1613 | } |
1535 | 1614 | ||
1615 | static int roland_load_info(struct snd_kcontrol *kcontrol, | ||
1616 | struct snd_ctl_elem_info *info) | ||
1617 | { | ||
1618 | static const char *const names[] = { "High Load", "Light Load" }; | ||
1619 | |||
1620 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1621 | info->count = 1; | ||
1622 | info->value.enumerated.items = 2; | ||
1623 | if (info->value.enumerated.item > 1) | ||
1624 | info->value.enumerated.item = 1; | ||
1625 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
1626 | return 0; | ||
1627 | } | ||
1628 | |||
1629 | static int roland_load_get(struct snd_kcontrol *kcontrol, | ||
1630 | struct snd_ctl_elem_value *value) | ||
1631 | { | ||
1632 | value->value.enumerated.item[0] = kcontrol->private_value; | ||
1633 | return 0; | ||
1634 | } | ||
1635 | |||
1636 | static int roland_load_put(struct snd_kcontrol *kcontrol, | ||
1637 | struct snd_ctl_elem_value *value) | ||
1638 | { | ||
1639 | struct snd_usb_midi* umidi = kcontrol->private_data; | ||
1640 | int changed; | ||
1641 | |||
1642 | if (value->value.enumerated.item[0] > 1) | ||
1643 | return -EINVAL; | ||
1644 | mutex_lock(&umidi->mutex); | ||
1645 | changed = value->value.enumerated.item[0] != kcontrol->private_value; | ||
1646 | if (changed) | ||
1647 | kcontrol->private_value = value->value.enumerated.item[0]; | ||
1648 | mutex_unlock(&umidi->mutex); | ||
1649 | return changed; | ||
1650 | } | ||
1651 | |||
1652 | static struct snd_kcontrol_new roland_load_ctl = { | ||
1653 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1654 | .name = "MIDI Input Mode", | ||
1655 | .info = roland_load_info, | ||
1656 | .get = roland_load_get, | ||
1657 | .put = roland_load_put, | ||
1658 | .private_value = 1, | ||
1659 | }; | ||
1660 | |||
1536 | /* | 1661 | /* |
1537 | * On Roland devices, use the second alternate setting to be able to use | 1662 | * On Roland devices, use the second alternate setting to be able to use |
1538 | * the interrupt input endpoint. | 1663 | * the interrupt input endpoint. |
@@ -1556,8 +1681,12 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi) | |||
1556 | 1681 | ||
1557 | snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", | 1682 | snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", |
1558 | intfd->bAlternateSetting); | 1683 | intfd->bAlternateSetting); |
1559 | usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, | 1684 | usb_set_interface(umidi->dev, intfd->bInterfaceNumber, |
1560 | intfd->bAlternateSetting); | 1685 | intfd->bAlternateSetting); |
1686 | |||
1687 | umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi); | ||
1688 | if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0) | ||
1689 | umidi->roland_load_ctl = NULL; | ||
1561 | } | 1690 | } |
1562 | 1691 | ||
1563 | /* | 1692 | /* |
@@ -1573,7 +1702,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi, | |||
1573 | struct usb_endpoint_descriptor* epd; | 1702 | struct usb_endpoint_descriptor* epd; |
1574 | int i, out_eps = 0, in_eps = 0; | 1703 | int i, out_eps = 0, in_eps = 0; |
1575 | 1704 | ||
1576 | if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582) | 1705 | if (USB_ID_VENDOR(umidi->usb_id) == 0x0582) |
1577 | snd_usbmidi_switch_roland_altsetting(umidi); | 1706 | snd_usbmidi_switch_roland_altsetting(umidi); |
1578 | 1707 | ||
1579 | if (endpoint[0].out_ep || endpoint[0].in_ep) | 1708 | if (endpoint[0].out_ep || endpoint[0].in_ep) |
@@ -1653,9 +1782,9 @@ static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi, | |||
1653 | cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; | 1782 | cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; |
1654 | cs_desc += cs_desc[0]) { | 1783 | cs_desc += cs_desc[0]) { |
1655 | if (cs_desc[1] == USB_DT_CS_INTERFACE) { | 1784 | if (cs_desc[1] == USB_DT_CS_INTERFACE) { |
1656 | if (cs_desc[2] == MIDI_IN_JACK) | 1785 | if (cs_desc[2] == UAC_MIDI_IN_JACK) |
1657 | endpoint->in_cables = (endpoint->in_cables << 1) | 1; | 1786 | endpoint->in_cables = (endpoint->in_cables << 1) | 1; |
1658 | else if (cs_desc[2] == MIDI_OUT_JACK) | 1787 | else if (cs_desc[2] == UAC_MIDI_OUT_JACK) |
1659 | endpoint->out_cables = (endpoint->out_cables << 1) | 1; | 1788 | endpoint->out_cables = (endpoint->out_cables << 1) | 1; |
1660 | } | 1789 | } |
1661 | } | 1790 | } |
@@ -1760,12 +1889,12 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi, | |||
1760 | struct snd_rawmidi *rmidi; | 1889 | struct snd_rawmidi *rmidi; |
1761 | int err; | 1890 | int err; |
1762 | 1891 | ||
1763 | err = snd_rawmidi_new(umidi->chip->card, "USB MIDI", | 1892 | err = snd_rawmidi_new(umidi->card, "USB MIDI", |
1764 | umidi->chip->next_midi_device++, | 1893 | umidi->next_midi_device++, |
1765 | out_ports, in_ports, &rmidi); | 1894 | out_ports, in_ports, &rmidi); |
1766 | if (err < 0) | 1895 | if (err < 0) |
1767 | return err; | 1896 | return err; |
1768 | strcpy(rmidi->name, umidi->chip->card->shortname); | 1897 | strcpy(rmidi->name, umidi->card->shortname); |
1769 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | | 1898 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | |
1770 | SNDRV_RAWMIDI_INFO_INPUT | | 1899 | SNDRV_RAWMIDI_INFO_INPUT | |
1771 | SNDRV_RAWMIDI_INFO_DUPLEX; | 1900 | SNDRV_RAWMIDI_INFO_DUPLEX; |
@@ -1804,7 +1933,7 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) | |||
1804 | return; | 1933 | return; |
1805 | for (i = 0; i < INPUT_URBS; ++i) { | 1934 | for (i = 0; i < INPUT_URBS; ++i) { |
1806 | struct urb* urb = ep->urbs[i]; | 1935 | struct urb* urb = ep->urbs[i]; |
1807 | urb->dev = ep->umidi->chip->dev; | 1936 | urb->dev = ep->umidi->dev; |
1808 | snd_usbmidi_submit_urb(urb, GFP_KERNEL); | 1937 | snd_usbmidi_submit_urb(urb, GFP_KERNEL); |
1809 | } | 1938 | } |
1810 | } | 1939 | } |
@@ -1825,9 +1954,10 @@ void snd_usbmidi_input_start(struct list_head* p) | |||
1825 | /* | 1954 | /* |
1826 | * Creates and registers everything needed for a MIDI streaming interface. | 1955 | * Creates and registers everything needed for a MIDI streaming interface. |
1827 | */ | 1956 | */ |
1828 | int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | 1957 | int snd_usbmidi_create(struct snd_card *card, |
1829 | struct usb_interface* iface, | 1958 | struct usb_interface* iface, |
1830 | const struct snd_usb_audio_quirk* quirk) | 1959 | struct list_head *midi_list, |
1960 | const struct snd_usb_audio_quirk* quirk) | ||
1831 | { | 1961 | { |
1832 | struct snd_usb_midi* umidi; | 1962 | struct snd_usb_midi* umidi; |
1833 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; | 1963 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; |
@@ -1837,12 +1967,16 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1837 | umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); | 1967 | umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); |
1838 | if (!umidi) | 1968 | if (!umidi) |
1839 | return -ENOMEM; | 1969 | return -ENOMEM; |
1840 | umidi->chip = chip; | 1970 | umidi->dev = interface_to_usbdev(iface); |
1971 | umidi->card = card; | ||
1841 | umidi->iface = iface; | 1972 | umidi->iface = iface; |
1842 | umidi->quirk = quirk; | 1973 | umidi->quirk = quirk; |
1843 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | 1974 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; |
1844 | init_timer(&umidi->error_timer); | 1975 | init_timer(&umidi->error_timer); |
1845 | spin_lock_init(&umidi->disc_lock); | 1976 | spin_lock_init(&umidi->disc_lock); |
1977 | mutex_init(&umidi->mutex); | ||
1978 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | ||
1979 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | ||
1846 | umidi->error_timer.function = snd_usbmidi_error_timer; | 1980 | umidi->error_timer.function = snd_usbmidi_error_timer; |
1847 | umidi->error_timer.data = (unsigned long)umidi; | 1981 | umidi->error_timer.data = (unsigned long)umidi; |
1848 | 1982 | ||
@@ -1851,7 +1985,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1851 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { | 1985 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { |
1852 | case QUIRK_MIDI_STANDARD_INTERFACE: | 1986 | case QUIRK_MIDI_STANDARD_INTERFACE: |
1853 | err = snd_usbmidi_get_ms_info(umidi, endpoints); | 1987 | err = snd_usbmidi_get_ms_info(umidi, endpoints); |
1854 | if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ | 1988 | if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ |
1855 | umidi->usb_protocol_ops = | 1989 | umidi->usb_protocol_ops = |
1856 | &snd_usbmidi_maudio_broken_running_status_ops; | 1990 | &snd_usbmidi_maudio_broken_running_status_ops; |
1857 | break; | 1991 | break; |
@@ -1887,7 +2021,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1887 | * interface 0, so we have to make sure that the USB core looks | 2021 | * interface 0, so we have to make sure that the USB core looks |
1888 | * again at interface 0 by calling usb_set_interface() on it. | 2022 | * again at interface 0 by calling usb_set_interface() on it. |
1889 | */ | 2023 | */ |
1890 | usb_set_interface(umidi->chip->dev, 0, 0); | 2024 | usb_set_interface(umidi->dev, 0, 0); |
1891 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 2025 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1892 | break; | 2026 | break; |
1893 | case QUIRK_MIDI_EMAGIC: | 2027 | case QUIRK_MIDI_EMAGIC: |
@@ -1914,8 +2048,8 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1914 | out_ports = 0; | 2048 | out_ports = 0; |
1915 | in_ports = 0; | 2049 | in_ports = 0; |
1916 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | 2050 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { |
1917 | out_ports += snd_usbmidi_count_bits(endpoints[i].out_cables); | 2051 | out_ports += hweight16(endpoints[i].out_cables); |
1918 | in_ports += snd_usbmidi_count_bits(endpoints[i].in_cables); | 2052 | in_ports += hweight16(endpoints[i].in_cables); |
1919 | } | 2053 | } |
1920 | err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); | 2054 | err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); |
1921 | if (err < 0) { | 2055 | if (err < 0) { |
@@ -1933,14 +2067,14 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1933 | return err; | 2067 | return err; |
1934 | } | 2068 | } |
1935 | 2069 | ||
1936 | list_add(&umidi->list, &umidi->chip->midi_list); | 2070 | list_add_tail(&umidi->list, midi_list); |
1937 | 2071 | ||
1938 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | 2072 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) |
1939 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | 2073 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); |
1940 | return 0; | 2074 | return 0; |
1941 | } | 2075 | } |
1942 | 2076 | ||
1943 | EXPORT_SYMBOL(snd_usb_create_midi_interface); | 2077 | EXPORT_SYMBOL(snd_usbmidi_create); |
1944 | EXPORT_SYMBOL(snd_usbmidi_input_stop); | 2078 | EXPORT_SYMBOL(snd_usbmidi_input_stop); |
1945 | EXPORT_SYMBOL(snd_usbmidi_input_start); | 2079 | EXPORT_SYMBOL(snd_usbmidi_input_start); |
1946 | EXPORT_SYMBOL(snd_usbmidi_disconnect); | 2080 | EXPORT_SYMBOL(snd_usbmidi_disconnect); |