X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fusb%2Fusbmidi.c;h=496e520c5bdee3de24ed0ca24d1acf5af33b084f;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=a2f1b5621475ee32511ea13eb02a3975d4420a3d;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index a2f1b5621..496e520c5 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -49,12 +49,17 @@ #include #include "usbaudio.h" +MODULE_AUTHOR("Clemens Ladisch "); +MODULE_DESCRIPTION("USB Audio/MIDI helper module"); +MODULE_LICENSE("Dual BSD/GPL"); + + struct usb_ms_header_descriptor { __u8 bLength; __u8 bDescriptorType; __u8 bDescriptorSubtype; __u8 bcdMSC[2]; - __u16 wTotalLength; + __le16 wTotalLength; } __attribute__ ((packed)); struct usb_ms_endpoint_descriptor { @@ -175,7 +180,7 @@ static void snd_usbmidi_input_packet(snd_usb_midi_in_endpoint_t* ep, */ static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) { - snd_usb_midi_in_endpoint_t* ep = snd_magic_cast(snd_usb_midi_in_endpoint_t, urb->context, return); + snd_usb_midi_in_endpoint_t* ep = urb->context; if (urb->status == 0) { uint8_t* buffer = (uint8_t*)ep->urb->transfer_buffer; @@ -229,7 +234,7 @@ static void snd_usbmidi_in_midiman_complete(struct urb* urb, struct pt_regs *reg static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) { - snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, urb->context, return); + snd_usb_midi_out_endpoint_t* ep = urb->context; if (urb->status < 0) { if (snd_usbmidi_urb_error(urb->status) < 0) @@ -393,7 +398,7 @@ static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep) int p; struct urb* urb = ep->urb; unsigned long flags; - + spin_lock_irqsave(&ep->buffer_lock, flags); if (urb->status == -EINPROGRESS || ep->umidi->chip->shutdown) { spin_unlock_irqrestore(&ep->buffer_lock, flags); @@ -417,14 +422,14 @@ static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep) static void snd_usbmidi_out_tasklet(unsigned long data) { - snd_usb_midi_out_endpoint_t* ep = snd_magic_cast(snd_usb_midi_out_endpoint_t, (void*)data, return); - + snd_usb_midi_out_endpoint_t* ep = (snd_usb_midi_out_endpoint_t *) data; + snd_usbmidi_do_output(ep); } static int snd_usbmidi_output_open(snd_rawmidi_substream_t* substream) { - snd_usb_midi_t* umidi = snd_magic_cast(snd_usb_midi_t, substream->rmidi->private_data, return -ENXIO); + snd_usb_midi_t* umidi = substream->rmidi->private_data; usbmidi_out_port_t* port = NULL; int i, j; @@ -499,11 +504,10 @@ static snd_rawmidi_ops_t snd_usbmidi_input_ops = { static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) { if (ep->urb) { - if (ep->urb->transfer_buffer) - kfree(ep->urb->transfer_buffer); + kfree(ep->urb->transfer_buffer); usb_free_urb(ep->urb); } - snd_magic_kfree(ep); + kfree(ep); } /* @@ -516,7 +520,7 @@ static struct usb_endpoint_descriptor* snd_usbmidi_get_int_epd(snd_usb_midi_t* u struct usb_host_interface *hostif; struct usb_interface_descriptor* intfd; - if (umidi->chip->dev->descriptor.idVendor != 0x0582) + if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) != 0x0582) return NULL; intf = umidi->iface; if (!intf || intf->num_altsetting != 2) @@ -571,7 +575,7 @@ static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, int length; rep->in = NULL; - ep = snd_magic_kcalloc(snd_usb_midi_in_endpoint_t, 0, GFP_KERNEL); + ep = kcalloc(1, sizeof(*ep), GFP_KERNEL); if (!ep) return -ENOMEM; ep->umidi = umidi; @@ -627,11 +631,10 @@ static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) if (ep->tasklet.func) tasklet_kill(&ep->tasklet); if (ep->urb) { - if (ep->urb->transfer_buffer) - kfree(ep->urb->transfer_buffer); + kfree(ep->urb->transfer_buffer); usb_free_urb(ep->urb); } - snd_magic_kfree(ep); + kfree(ep); } /* @@ -647,7 +650,7 @@ static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, void* buffer; rep->out = NULL; - ep = snd_magic_kcalloc(snd_usb_midi_out_endpoint_t, 0, GFP_KERNEL); + ep = kcalloc(1, sizeof(*ep), GFP_KERNEL); if (!ep) return -ENOMEM; ep->umidi = umidi; @@ -695,7 +698,7 @@ static void snd_usbmidi_free(snd_usb_midi_t* umidi) if (ep->in) snd_usbmidi_in_endpoint_delete(ep->in); } - snd_magic_kfree(umidi); + kfree(umidi); } /* @@ -710,15 +713,15 @@ void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver) for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; if (ep->out && ep->out->urb) - usb_unlink_urb(ep->out->urb); + usb_kill_urb(ep->out->urb); if (ep->in && ep->in->urb) - usb_unlink_urb(ep->in->urb); + usb_kill_urb(ep->in->urb); } } static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi) { - snd_usb_midi_t* umidi = snd_magic_cast(snd_usb_midi_t, rmidi->private_data, return); + snd_usb_midi_t* umidi = rmidi->private_data; snd_usbmidi_free(umidi); } @@ -834,8 +837,8 @@ static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi, /* TODO: read port name from jack descriptor */ name_format = "%s MIDI %d"; - vendor = umidi->chip->dev->descriptor.idVendor; - product = umidi->chip->dev->descriptor.idProduct; + vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor); + product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct); for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) { if (snd_usbmidi_port_names[i].vendor == vendor && snd_usbmidi_port_names[i].product == product && @@ -964,7 +967,7 @@ static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi, * If the endpoints aren't specified, use the first bulk endpoints in the * first alternate setting of the interface. */ -static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, +static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, snd_usb_midi_endpoint_info_t* endpoint) { struct usb_interface* intf; @@ -998,7 +1001,7 @@ static int snd_usbmidi_detect_endpoint(snd_usb_midi_t* umidi, /* * Detects the endpoints and ports of Yamaha devices. */ -static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi, +static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi, snd_usb_midi_endpoint_info_t* endpoint) { struct usb_interface* intf; @@ -1144,6 +1147,44 @@ static int snd_usbmidi_create_rawmidi(snd_usb_midi_t* umidi, return 0; } +/* + * Temporarily stop input. + */ +void snd_usbmidi_input_stop(struct list_head* p) +{ + snd_usb_midi_t* umidi; + int i; + + umidi = list_entry(p, snd_usb_midi_t, list); + for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { + snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; + if (ep->in) + usb_kill_urb(ep->in->urb); + } +} + +static void snd_usbmidi_input_start_ep(snd_usb_midi_in_endpoint_t* ep) +{ + if (ep) { + struct urb* urb = ep->urb; + urb->dev = ep->umidi->chip->dev; + snd_usbmidi_submit_urb(urb, GFP_KERNEL); + } +} + +/* + * Resume input after a call to snd_usbmidi_input_stop(). + */ +void snd_usbmidi_input_start(struct list_head* p) +{ + snd_usb_midi_t* umidi; + int i; + + umidi = list_entry(p, snd_usb_midi_t, list); + for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) + snd_usbmidi_input_start_ep(umidi->endpoints[i].in); +} + /* * Creates and registers everything needed for a MIDI streaming interface. */ @@ -1156,7 +1197,7 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, int out_ports, in_ports; int i, err; - umidi = snd_magic_kcalloc(snd_usb_midi_t, 0, GFP_KERNEL); + umidi = kcalloc(1, sizeof(*umidi), GFP_KERNEL); if (!umidi) return -ENOMEM; umidi->chip = chip; @@ -1189,7 +1230,7 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, } } if (err < 0) { - snd_magic_kfree(umidi); + kfree(umidi); return err; } @@ -1202,7 +1243,7 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, } err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); if (err < 0) { - snd_magic_kfree(umidi); + kfree(umidi); return err; } @@ -1219,8 +1260,11 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, list_add(&umidi->list, &umidi->chip->midi_list); for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) - if (umidi->endpoints[i].in) - snd_usbmidi_submit_urb(umidi->endpoints[i].in->urb, - GFP_KERNEL); + snd_usbmidi_input_start_ep(umidi->endpoints[i].in); return 0; } + +EXPORT_SYMBOL(snd_usb_create_midi_interface); +EXPORT_SYMBOL(snd_usbmidi_input_stop); +EXPORT_SYMBOL(snd_usbmidi_input_start); +EXPORT_SYMBOL(snd_usbmidi_disconnect);