diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-11-16 06:23:46 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-11-24 04:19:59 -0500 |
commit | d82af9f9aab69e82b86450272588c861364f8879 (patch) | |
tree | 725374db87473b6ae0e2ac6f41ca44866affa37b /sound/usb/usbmidi.c | |
parent | 96f61d9ade82f3e9503df36809175325e8f5eaca (diff) |
sound: usb: make the USB MIDI module more independent
Remove the dependecy from the USB MIDI code on the snd_usb_audio
structure. This allows using the USB MIDI module from another driver
without having to pretend to be the generic USB audio driver.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r-- | sound/usb/usbmidi.c | 96 |
1 files changed, 51 insertions, 45 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 80b2845bc48..6e89b8368d9 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -102,7 +102,8 @@ struct usb_protocol_ops { | |||
102 | }; | 102 | }; |
103 | 103 | ||
104 | struct snd_usb_midi { | 104 | struct snd_usb_midi { |
105 | struct snd_usb_audio *chip; | 105 | struct usb_device *dev; |
106 | struct snd_card *card; | ||
106 | struct usb_interface *iface; | 107 | struct usb_interface *iface; |
107 | const struct snd_usb_audio_quirk *quirk; | 108 | const struct snd_usb_audio_quirk *quirk; |
108 | struct snd_rawmidi *rmidi; | 109 | struct snd_rawmidi *rmidi; |
@@ -111,6 +112,8 @@ struct snd_usb_midi { | |||
111 | struct timer_list error_timer; | 112 | struct timer_list error_timer; |
112 | spinlock_t disc_lock; | 113 | spinlock_t disc_lock; |
113 | struct mutex mutex; | 114 | struct mutex mutex; |
115 | u32 usb_id; | ||
116 | int next_midi_device; | ||
114 | 117 | ||
115 | struct snd_usb_midi_endpoint { | 118 | struct snd_usb_midi_endpoint { |
116 | struct snd_usb_midi_out_endpoint *out; | 119 | struct snd_usb_midi_out_endpoint *out; |
@@ -260,7 +263,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb) | |||
260 | } | 263 | } |
261 | } | 264 | } |
262 | 265 | ||
263 | urb->dev = ep->umidi->chip->dev; | 266 | urb->dev = ep->umidi->dev; |
264 | snd_usbmidi_submit_urb(urb, GFP_ATOMIC); | 267 | snd_usbmidi_submit_urb(urb, GFP_ATOMIC); |
265 | } | 268 | } |
266 | 269 | ||
@@ -301,7 +304,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) | |||
301 | unsigned long flags; | 304 | unsigned long flags; |
302 | 305 | ||
303 | spin_lock_irqsave(&ep->buffer_lock, flags); | 306 | spin_lock_irqsave(&ep->buffer_lock, flags); |
304 | if (ep->umidi->chip->shutdown) { | 307 | if (ep->umidi->disconnected) { |
305 | spin_unlock_irqrestore(&ep->buffer_lock, flags); | 308 | spin_unlock_irqrestore(&ep->buffer_lock, flags); |
306 | return; | 309 | return; |
307 | } | 310 | } |
@@ -317,7 +320,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) | |||
317 | 320 | ||
318 | dump_urb("sending", urb->transfer_buffer, | 321 | dump_urb("sending", urb->transfer_buffer, |
319 | urb->transfer_buffer_length); | 322 | urb->transfer_buffer_length); |
320 | urb->dev = ep->umidi->chip->dev; | 323 | urb->dev = ep->umidi->dev; |
321 | if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) | 324 | if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) |
322 | break; | 325 | break; |
323 | ep->active_urbs |= 1 << urb_index; | 326 | ep->active_urbs |= 1 << urb_index; |
@@ -354,7 +357,7 @@ static void snd_usbmidi_error_timer(unsigned long data) | |||
354 | if (in && in->error_resubmit) { | 357 | if (in && in->error_resubmit) { |
355 | in->error_resubmit = 0; | 358 | in->error_resubmit = 0; |
356 | for (j = 0; j < INPUT_URBS; ++j) { | 359 | for (j = 0; j < INPUT_URBS; ++j) { |
357 | in->urbs[j]->dev = umidi->chip->dev; | 360 | in->urbs[j]->dev = umidi->dev; |
358 | snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); | 361 | snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); |
359 | } | 362 | } |
360 | } | 363 | } |
@@ -374,7 +377,7 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep, | |||
374 | return -ENOMEM; | 377 | return -ENOMEM; |
375 | dump_urb("sending", buf, len); | 378 | dump_urb("sending", buf, len); |
376 | if (ep->urbs[0].urb) | 379 | if (ep->urbs[0].urb) |
377 | err = usb_bulk_msg(ep->umidi->chip->dev, ep->urbs[0].urb->pipe, | 380 | err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe, |
378 | buf, len, NULL, 250); | 381 | buf, len, NULL, 250); |
379 | kfree(buf); | 382 | kfree(buf); |
380 | return err; | 383 | return err; |
@@ -729,8 +732,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep, | |||
729 | 732 | ||
730 | if (!ep->ports[0].active) | 733 | if (!ep->ports[0].active) |
731 | return; | 734 | return; |
732 | count = snd_usb_get_speed(ep->umidi->chip->dev) == USB_SPEED_HIGH | 735 | count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2; |
733 | ? 1 : 2; | ||
734 | count = snd_rawmidi_transmit(ep->ports[0].substream, | 736 | count = snd_rawmidi_transmit(ep->ports[0].substream, |
735 | urb->transfer_buffer, | 737 | urb->transfer_buffer, |
736 | count); | 738 | count); |
@@ -898,7 +900,7 @@ static void update_roland_altsetting(struct snd_usb_midi* umidi) | |||
898 | hostif = &intf->altsetting[umidi->roland_load_ctl->private_value]; | 900 | hostif = &intf->altsetting[umidi->roland_load_ctl->private_value]; |
899 | intfd = get_iface_desc(hostif); | 901 | intfd = get_iface_desc(hostif); |
900 | snd_usbmidi_input_stop(&umidi->list); | 902 | snd_usbmidi_input_stop(&umidi->list); |
901 | usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, | 903 | usb_set_interface(umidi->dev, intfd->bInterfaceNumber, |
902 | intfd->bAlternateSetting); | 904 | intfd->bAlternateSetting); |
903 | snd_usbmidi_input_start(&umidi->list); | 905 | snd_usbmidi_input_start(&umidi->list); |
904 | } | 906 | } |
@@ -913,7 +915,7 @@ static void substream_open(struct snd_rawmidi_substream *substream, int open) | |||
913 | if (umidi->opened++ == 0 && umidi->roland_load_ctl) { | 915 | if (umidi->opened++ == 0 && umidi->roland_load_ctl) { |
914 | ctl = umidi->roland_load_ctl; | 916 | ctl = umidi->roland_load_ctl; |
915 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | 917 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
916 | snd_ctl_notify(umidi->chip->card, | 918 | snd_ctl_notify(umidi->card, |
917 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | 919 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); |
918 | update_roland_altsetting(umidi); | 920 | update_roland_altsetting(umidi); |
919 | } | 921 | } |
@@ -921,7 +923,7 @@ static void substream_open(struct snd_rawmidi_substream *substream, int open) | |||
921 | if (--umidi->opened == 0 && umidi->roland_load_ctl) { | 923 | if (--umidi->opened == 0 && umidi->roland_load_ctl) { |
922 | ctl = umidi->roland_load_ctl; | 924 | ctl = umidi->roland_load_ctl; |
923 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | 925 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
924 | snd_ctl_notify(umidi->chip->card, | 926 | snd_ctl_notify(umidi->card, |
925 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | 927 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); |
926 | } | 928 | } |
927 | } | 929 | } |
@@ -963,7 +965,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, | |||
963 | 965 | ||
964 | port->active = up; | 966 | port->active = up; |
965 | if (up) { | 967 | if (up) { |
966 | if (port->ep->umidi->chip->shutdown) { | 968 | if (port->ep->umidi->disconnected) { |
967 | /* gobble up remaining bytes to prevent wait in | 969 | /* gobble up remaining bytes to prevent wait in |
968 | * snd_rawmidi_drain_output */ | 970 | * snd_rawmidi_drain_output */ |
969 | while (!snd_rawmidi_transmit_empty(substream)) | 971 | while (!snd_rawmidi_transmit_empty(substream)) |
@@ -1041,7 +1043,7 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = { | |||
1041 | static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, | 1043 | static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, |
1042 | unsigned int buffer_length) | 1044 | unsigned int buffer_length) |
1043 | { | 1045 | { |
1044 | usb_buffer_free(umidi->chip->dev, buffer_length, | 1046 | usb_buffer_free(umidi->dev, buffer_length, |
1045 | urb->transfer_buffer, urb->transfer_dma); | 1047 | urb->transfer_buffer, urb->transfer_dma); |
1046 | usb_free_urb(urb); | 1048 | usb_free_urb(urb); |
1047 | } | 1049 | } |
@@ -1088,24 +1090,24 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1088 | } | 1090 | } |
1089 | } | 1091 | } |
1090 | if (ep_info->in_interval) | 1092 | if (ep_info->in_interval) |
1091 | pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); | 1093 | pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep); |
1092 | else | 1094 | else |
1093 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); | 1095 | pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep); |
1094 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); | 1096 | length = usb_maxpacket(umidi->dev, pipe, 0); |
1095 | for (i = 0; i < INPUT_URBS; ++i) { | 1097 | for (i = 0; i < INPUT_URBS; ++i) { |
1096 | buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, | 1098 | buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL, |
1097 | &ep->urbs[i]->transfer_dma); | 1099 | &ep->urbs[i]->transfer_dma); |
1098 | if (!buffer) { | 1100 | if (!buffer) { |
1099 | snd_usbmidi_in_endpoint_delete(ep); | 1101 | snd_usbmidi_in_endpoint_delete(ep); |
1100 | return -ENOMEM; | 1102 | return -ENOMEM; |
1101 | } | 1103 | } |
1102 | if (ep_info->in_interval) | 1104 | if (ep_info->in_interval) |
1103 | usb_fill_int_urb(ep->urbs[i], umidi->chip->dev, | 1105 | usb_fill_int_urb(ep->urbs[i], umidi->dev, |
1104 | pipe, buffer, length, | 1106 | pipe, buffer, length, |
1105 | snd_usbmidi_in_urb_complete, | 1107 | snd_usbmidi_in_urb_complete, |
1106 | ep, ep_info->in_interval); | 1108 | ep, ep_info->in_interval); |
1107 | else | 1109 | else |
1108 | usb_fill_bulk_urb(ep->urbs[i], umidi->chip->dev, | 1110 | usb_fill_bulk_urb(ep->urbs[i], umidi->dev, |
1109 | pipe, buffer, length, | 1111 | pipe, buffer, length, |
1110 | snd_usbmidi_in_urb_complete, ep); | 1112 | snd_usbmidi_in_urb_complete, ep); |
1111 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | 1113 | ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; |
@@ -1157,15 +1159,15 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
1157 | ep->urbs[i].ep = ep; | 1159 | ep->urbs[i].ep = ep; |
1158 | } | 1160 | } |
1159 | if (ep_info->out_interval) | 1161 | if (ep_info->out_interval) |
1160 | pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep); | 1162 | pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep); |
1161 | else | 1163 | else |
1162 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | 1164 | pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep); |
1163 | if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ | 1165 | if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ |
1164 | ep->max_transfer = 4; | 1166 | ep->max_transfer = 4; |
1165 | else | 1167 | else |
1166 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | 1168 | ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); |
1167 | for (i = 0; i < OUTPUT_URBS; ++i) { | 1169 | for (i = 0; i < OUTPUT_URBS; ++i) { |
1168 | buffer = usb_buffer_alloc(umidi->chip->dev, | 1170 | buffer = usb_buffer_alloc(umidi->dev, |
1169 | ep->max_transfer, GFP_KERNEL, | 1171 | ep->max_transfer, GFP_KERNEL, |
1170 | &ep->urbs[i].urb->transfer_dma); | 1172 | &ep->urbs[i].urb->transfer_dma); |
1171 | if (!buffer) { | 1173 | if (!buffer) { |
@@ -1173,12 +1175,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, | |||
1173 | return -ENOMEM; | 1175 | return -ENOMEM; |
1174 | } | 1176 | } |
1175 | if (ep_info->out_interval) | 1177 | if (ep_info->out_interval) |
1176 | usb_fill_int_urb(ep->urbs[i].urb, umidi->chip->dev, | 1178 | usb_fill_int_urb(ep->urbs[i].urb, umidi->dev, |
1177 | pipe, buffer, ep->max_transfer, | 1179 | pipe, buffer, ep->max_transfer, |
1178 | snd_usbmidi_out_urb_complete, | 1180 | snd_usbmidi_out_urb_complete, |
1179 | &ep->urbs[i], ep_info->out_interval); | 1181 | &ep->urbs[i], ep_info->out_interval); |
1180 | else | 1182 | else |
1181 | usb_fill_bulk_urb(ep->urbs[i].urb, umidi->chip->dev, | 1183 | usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev, |
1182 | pipe, buffer, ep->max_transfer, | 1184 | pipe, buffer, ep->max_transfer, |
1183 | snd_usbmidi_out_urb_complete, | 1185 | snd_usbmidi_out_urb_complete, |
1184 | &ep->urbs[i]); | 1186 | &ep->urbs[i]); |
@@ -1412,7 +1414,7 @@ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) | |||
1412 | int i; | 1414 | int i; |
1413 | 1415 | ||
1414 | for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { | 1416 | for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { |
1415 | if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id && | 1417 | if (snd_usbmidi_port_info[i].id == umidi->usb_id && |
1416 | snd_usbmidi_port_info[i].port == number) | 1418 | snd_usbmidi_port_info[i].port == number) |
1417 | return &snd_usbmidi_port_info[i]; | 1419 | return &snd_usbmidi_port_info[i]; |
1418 | } | 1420 | } |
@@ -1450,7 +1452,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi, | |||
1450 | port_info = find_port_info(umidi, number); | 1452 | port_info = find_port_info(umidi, number); |
1451 | name_format = port_info ? port_info->name : "%s MIDI %d"; | 1453 | name_format = port_info ? port_info->name : "%s MIDI %d"; |
1452 | snprintf(substream->name, sizeof(substream->name), | 1454 | snprintf(substream->name, sizeof(substream->name), |
1453 | name_format, umidi->chip->card->shortname, number + 1); | 1455 | name_format, umidi->card->shortname, number + 1); |
1454 | 1456 | ||
1455 | *rsubstream = substream; | 1457 | *rsubstream = substream; |
1456 | } | 1458 | } |
@@ -1548,7 +1550,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1548 | endpoints[epidx].out_ep = usb_endpoint_num(ep); | 1550 | endpoints[epidx].out_ep = usb_endpoint_num(ep); |
1549 | if (usb_endpoint_xfer_int(ep)) | 1551 | if (usb_endpoint_xfer_int(ep)) |
1550 | endpoints[epidx].out_interval = ep->bInterval; | 1552 | endpoints[epidx].out_interval = ep->bInterval; |
1551 | else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) | 1553 | else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW) |
1552 | /* | 1554 | /* |
1553 | * Low speed bulk transfers don't exist, so | 1555 | * Low speed bulk transfers don't exist, so |
1554 | * force interrupt transfers for devices like | 1556 | * force interrupt transfers for devices like |
@@ -1568,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, | |||
1568 | endpoints[epidx].in_ep = usb_endpoint_num(ep); | 1570 | endpoints[epidx].in_ep = usb_endpoint_num(ep); |
1569 | if (usb_endpoint_xfer_int(ep)) | 1571 | if (usb_endpoint_xfer_int(ep)) |
1570 | endpoints[epidx].in_interval = ep->bInterval; | 1572 | endpoints[epidx].in_interval = ep->bInterval; |
1571 | else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) | 1573 | else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW) |
1572 | endpoints[epidx].in_interval = 1; | 1574 | endpoints[epidx].in_interval = 1; |
1573 | endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; | 1575 | endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; |
1574 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", | 1576 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", |
@@ -1647,11 +1649,11 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi) | |||
1647 | 1649 | ||
1648 | snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", | 1650 | snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", |
1649 | intfd->bAlternateSetting); | 1651 | intfd->bAlternateSetting); |
1650 | usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, | 1652 | usb_set_interface(umidi->dev, intfd->bInterfaceNumber, |
1651 | intfd->bAlternateSetting); | 1653 | intfd->bAlternateSetting); |
1652 | 1654 | ||
1653 | umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi); | 1655 | umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi); |
1654 | if (snd_ctl_add(umidi->chip->card, umidi->roland_load_ctl) < 0) | 1656 | if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0) |
1655 | umidi->roland_load_ctl = NULL; | 1657 | umidi->roland_load_ctl = NULL; |
1656 | } | 1658 | } |
1657 | 1659 | ||
@@ -1668,7 +1670,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi, | |||
1668 | struct usb_endpoint_descriptor* epd; | 1670 | struct usb_endpoint_descriptor* epd; |
1669 | int i, out_eps = 0, in_eps = 0; | 1671 | int i, out_eps = 0, in_eps = 0; |
1670 | 1672 | ||
1671 | if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582) | 1673 | if (USB_ID_VENDOR(umidi->usb_id) == 0x0582) |
1672 | snd_usbmidi_switch_roland_altsetting(umidi); | 1674 | snd_usbmidi_switch_roland_altsetting(umidi); |
1673 | 1675 | ||
1674 | if (endpoint[0].out_ep || endpoint[0].in_ep) | 1676 | if (endpoint[0].out_ep || endpoint[0].in_ep) |
@@ -1855,12 +1857,12 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi, | |||
1855 | struct snd_rawmidi *rmidi; | 1857 | struct snd_rawmidi *rmidi; |
1856 | int err; | 1858 | int err; |
1857 | 1859 | ||
1858 | err = snd_rawmidi_new(umidi->chip->card, "USB MIDI", | 1860 | err = snd_rawmidi_new(umidi->card, "USB MIDI", |
1859 | umidi->chip->next_midi_device++, | 1861 | umidi->next_midi_device++, |
1860 | out_ports, in_ports, &rmidi); | 1862 | out_ports, in_ports, &rmidi); |
1861 | if (err < 0) | 1863 | if (err < 0) |
1862 | return err; | 1864 | return err; |
1863 | strcpy(rmidi->name, umidi->chip->card->shortname); | 1865 | strcpy(rmidi->name, umidi->card->shortname); |
1864 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | | 1866 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | |
1865 | SNDRV_RAWMIDI_INFO_INPUT | | 1867 | SNDRV_RAWMIDI_INFO_INPUT | |
1866 | SNDRV_RAWMIDI_INFO_DUPLEX; | 1868 | SNDRV_RAWMIDI_INFO_DUPLEX; |
@@ -1899,7 +1901,7 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) | |||
1899 | return; | 1901 | return; |
1900 | for (i = 0; i < INPUT_URBS; ++i) { | 1902 | for (i = 0; i < INPUT_URBS; ++i) { |
1901 | struct urb* urb = ep->urbs[i]; | 1903 | struct urb* urb = ep->urbs[i]; |
1902 | urb->dev = ep->umidi->chip->dev; | 1904 | urb->dev = ep->umidi->dev; |
1903 | snd_usbmidi_submit_urb(urb, GFP_KERNEL); | 1905 | snd_usbmidi_submit_urb(urb, GFP_KERNEL); |
1904 | } | 1906 | } |
1905 | } | 1907 | } |
@@ -1920,9 +1922,10 @@ void snd_usbmidi_input_start(struct list_head* p) | |||
1920 | /* | 1922 | /* |
1921 | * Creates and registers everything needed for a MIDI streaming interface. | 1923 | * Creates and registers everything needed for a MIDI streaming interface. |
1922 | */ | 1924 | */ |
1923 | int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | 1925 | int snd_usbmidi_create(struct snd_card *card, |
1924 | struct usb_interface* iface, | 1926 | struct usb_interface* iface, |
1925 | const struct snd_usb_audio_quirk* quirk) | 1927 | struct list_head *midi_list, |
1928 | const struct snd_usb_audio_quirk* quirk) | ||
1926 | { | 1929 | { |
1927 | struct snd_usb_midi* umidi; | 1930 | struct snd_usb_midi* umidi; |
1928 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; | 1931 | struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; |
@@ -1932,13 +1935,16 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1932 | umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); | 1935 | umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); |
1933 | if (!umidi) | 1936 | if (!umidi) |
1934 | return -ENOMEM; | 1937 | return -ENOMEM; |
1935 | umidi->chip = chip; | 1938 | umidi->dev = interface_to_usbdev(iface); |
1939 | umidi->card = card; | ||
1936 | umidi->iface = iface; | 1940 | umidi->iface = iface; |
1937 | umidi->quirk = quirk; | 1941 | umidi->quirk = quirk; |
1938 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | 1942 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; |
1939 | init_timer(&umidi->error_timer); | 1943 | init_timer(&umidi->error_timer); |
1940 | spin_lock_init(&umidi->disc_lock); | 1944 | spin_lock_init(&umidi->disc_lock); |
1941 | mutex_init(&umidi->mutex); | 1945 | mutex_init(&umidi->mutex); |
1946 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | ||
1947 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | ||
1942 | umidi->error_timer.function = snd_usbmidi_error_timer; | 1948 | umidi->error_timer.function = snd_usbmidi_error_timer; |
1943 | umidi->error_timer.data = (unsigned long)umidi; | 1949 | umidi->error_timer.data = (unsigned long)umidi; |
1944 | 1950 | ||
@@ -1947,7 +1953,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1947 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { | 1953 | switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { |
1948 | case QUIRK_MIDI_STANDARD_INTERFACE: | 1954 | case QUIRK_MIDI_STANDARD_INTERFACE: |
1949 | err = snd_usbmidi_get_ms_info(umidi, endpoints); | 1955 | err = snd_usbmidi_get_ms_info(umidi, endpoints); |
1950 | if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ | 1956 | if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ |
1951 | umidi->usb_protocol_ops = | 1957 | umidi->usb_protocol_ops = |
1952 | &snd_usbmidi_maudio_broken_running_status_ops; | 1958 | &snd_usbmidi_maudio_broken_running_status_ops; |
1953 | break; | 1959 | break; |
@@ -1983,7 +1989,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
1983 | * interface 0, so we have to make sure that the USB core looks | 1989 | * interface 0, so we have to make sure that the USB core looks |
1984 | * again at interface 0 by calling usb_set_interface() on it. | 1990 | * again at interface 0 by calling usb_set_interface() on it. |
1985 | */ | 1991 | */ |
1986 | usb_set_interface(umidi->chip->dev, 0, 0); | 1992 | usb_set_interface(umidi->dev, 0, 0); |
1987 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1993 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1988 | break; | 1994 | break; |
1989 | case QUIRK_MIDI_EMAGIC: | 1995 | case QUIRK_MIDI_EMAGIC: |
@@ -2029,14 +2035,14 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, | |||
2029 | return err; | 2035 | return err; |
2030 | } | 2036 | } |
2031 | 2037 | ||
2032 | list_add(&umidi->list, &umidi->chip->midi_list); | 2038 | list_add_tail(&umidi->list, midi_list); |
2033 | 2039 | ||
2034 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | 2040 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) |
2035 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | 2041 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); |
2036 | return 0; | 2042 | return 0; |
2037 | } | 2043 | } |
2038 | 2044 | ||
2039 | EXPORT_SYMBOL(snd_usb_create_midi_interface); | 2045 | EXPORT_SYMBOL(snd_usbmidi_create); |
2040 | EXPORT_SYMBOL(snd_usbmidi_input_stop); | 2046 | EXPORT_SYMBOL(snd_usbmidi_input_stop); |
2041 | EXPORT_SYMBOL(snd_usbmidi_input_start); | 2047 | EXPORT_SYMBOL(snd_usbmidi_input_start); |
2042 | EXPORT_SYMBOL(snd_usbmidi_disconnect); | 2048 | EXPORT_SYMBOL(snd_usbmidi_disconnect); |