--- zzzz-none-000/linux-3.10.107/sound/usb/midi.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/sound/usb/midi.c 2021-02-04 17:41:59.000000000 +0000 @@ -64,7 +64,7 @@ /* #define DUMP_PACKETS */ /* - * how long to wait after some USB errors, so that khubd can disconnect() us + * how long to wait after some USB errors, so that hub_wq can disconnect() us * without too many spurious errors */ #define ERROR_DELAY_JIFFIES (HZ / 10) @@ -102,8 +102,8 @@ void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int); void (*output)(struct snd_usb_midi_out_endpoint *ep, struct urb *urb); void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t); - void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*); - void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*); + void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint *); + void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint *); }; struct snd_usb_midi { @@ -112,7 +112,7 @@ struct usb_interface *iface; const struct snd_usb_audio_quirk *quirk; struct snd_rawmidi *rmidi; - struct usb_protocol_ops* usb_protocol_ops; + struct usb_protocol_ops *usb_protocol_ops; struct list_head list; struct timer_list error_timer; spinlock_t disc_lock; @@ -134,7 +134,7 @@ }; struct snd_usb_midi_out_endpoint { - struct snd_usb_midi* umidi; + struct snd_usb_midi *umidi; struct out_urb_context { struct urb *urb; struct snd_usb_midi_out_endpoint *ep; @@ -147,7 +147,7 @@ spinlock_t buffer_lock; struct usbmidi_out_port { - struct snd_usb_midi_out_endpoint* ep; + struct snd_usb_midi_out_endpoint *ep; struct snd_rawmidi_substream *substream; int active; uint8_t cable; /* cable number << 4 */ @@ -167,8 +167,8 @@ }; struct snd_usb_midi_in_endpoint { - struct snd_usb_midi* umidi; - struct urb* urbs[INPUT_URBS]; + struct snd_usb_midi *umidi; + struct urb *urbs[INPUT_URBS]; struct usbmidi_in_port { struct snd_rawmidi_substream *substream; u8 running_status_length; @@ -180,7 +180,7 @@ int current_port; }; -static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep); +static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep); static const uint8_t snd_usbmidi_cin_length[] = { 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 @@ -189,20 +189,20 @@ /* * Submits the URB, with error handling. */ -static int snd_usbmidi_submit_urb(struct urb* urb, gfp_t flags) +static int snd_usbmidi_submit_urb(struct urb *urb, gfp_t flags) { int err = usb_submit_urb(urb, flags); if (err < 0 && err != -ENODEV) - snd_printk(KERN_ERR "usb_submit_urb: %d\n", err); + dev_err(&urb->dev->dev, "usb_submit_urb: %d\n", err); return err; } /* * Error handling for URB completion functions. */ -static int snd_usbmidi_urb_error(int status) +static int snd_usbmidi_urb_error(const struct urb *urb) { - switch (status) { + switch (urb->status) { /* manually unlinked, or device gone */ case -ENOENT: case -ECONNRESET: @@ -215,7 +215,7 @@ case -EILSEQ: return -EIO; default: - snd_printk(KERN_ERR "urb status %d\n", status); + dev_err(&urb->dev->dev, "urb status %d\n", urb->status); return 0; /* continue */ } } @@ -223,13 +223,13 @@ /* * Receives a chunk of MIDI data. */ -static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint* ep, int portidx, - uint8_t* data, int length) +static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint *ep, + int portidx, uint8_t *data, int length) { - struct usbmidi_in_port* port = &ep->ports[portidx]; + struct usbmidi_in_port *port = &ep->ports[portidx]; if (!port->substream) { - snd_printd("unexpected port %d!\n", portidx); + dev_dbg(&ep->umidi->dev->dev, "unexpected port %d!\n", portidx); return; } if (!test_bit(port->substream->number, &ep->umidi->input_triggered)) @@ -252,16 +252,16 @@ /* * Processes the data read from the device. */ -static void snd_usbmidi_in_urb_complete(struct urb* urb) +static void snd_usbmidi_in_urb_complete(struct urb *urb) { - struct snd_usb_midi_in_endpoint* ep = urb->context; + struct snd_usb_midi_in_endpoint *ep = urb->context; if (urb->status == 0) { dump_urb("received", urb->transfer_buffer, urb->actual_length); ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer, urb->actual_length); } else { - int err = snd_usbmidi_urb_error(urb->status); + int err = snd_usbmidi_urb_error(urb); if (err < 0) { if (err != -ENODEV) { ep->error_resubmit = 1; @@ -276,10 +276,10 @@ snd_usbmidi_submit_urb(urb, GFP_ATOMIC); } -static void snd_usbmidi_out_urb_complete(struct urb* urb) +static void snd_usbmidi_out_urb_complete(struct urb *urb) { struct out_urb_context *context = urb->context; - struct snd_usb_midi_out_endpoint* ep = context->ep; + struct snd_usb_midi_out_endpoint *ep = context->ep; unsigned int urb_index; spin_lock(&ep->buffer_lock); @@ -291,7 +291,7 @@ } spin_unlock(&ep->buffer_lock); if (urb->status < 0) { - int err = snd_usbmidi_urb_error(urb->status); + int err = snd_usbmidi_urb_error(urb); if (err < 0) { if (err != -ENODEV) mod_timer(&ep->umidi->error_timer, @@ -306,10 +306,10 @@ * This is called when some data should be transferred to the device * (from one or more substreams). */ -static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep) +static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep) { unsigned int urb_index; - struct urb* urb; + struct urb *urb; unsigned long flags; spin_lock_irqsave(&ep->buffer_lock, flags); @@ -345,7 +345,8 @@ static void snd_usbmidi_out_tasklet(unsigned long data) { - struct snd_usb_midi_out_endpoint* ep = (struct snd_usb_midi_out_endpoint *) data; + struct snd_usb_midi_out_endpoint *ep = + (struct snd_usb_midi_out_endpoint *) data; snd_usbmidi_do_output(ep); } @@ -379,7 +380,7 @@ } /* helper function to send static data that may not DMA-able */ -static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep, +static int send_bulk_static_data(struct snd_usb_midi_out_endpoint *ep, const void *data, int len) { int err = 0; @@ -400,8 +401,8 @@ * fourth byte in each packet, and uses length instead of CIN. */ -static void snd_usbmidi_standard_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_standard_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { int i; @@ -409,12 +410,13 @@ if (buffer[i] != 0) { int cable = buffer[i] >> 4; int length = snd_usbmidi_cin_length[buffer[i] & 0x0f]; - snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); + snd_usbmidi_input_data(ep, cable, &buffer[i + 1], + length); } } -static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { int i; @@ -431,8 +433,8 @@ * the data bytes but not the status byte and that is marked with CIN 4. */ static void snd_usbmidi_maudio_broken_running_status_input( - struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) + struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { int i; @@ -462,7 +464,8 @@ * doesn't use this format.) */ port->running_status_length = 0; - snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); + snd_usbmidi_input_data(ep, cable, &buffer[i + 1], + length); } } @@ -516,11 +519,13 @@ /* * Adds one USB MIDI packet to the output buffer. */ -static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, - uint8_t p1, uint8_t p2, uint8_t p3) +static void snd_usbmidi_output_standard_packet(struct urb *urb, uint8_t p0, + uint8_t p1, uint8_t p2, + uint8_t p3) { - uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length; + uint8_t *buf = + (uint8_t *)urb->transfer_buffer + urb->transfer_buffer_length; buf[0] = p0; buf[1] = p1; buf[2] = p2; @@ -531,11 +536,13 @@ /* * Adds one Midiman packet to the output buffer. */ -static void snd_usbmidi_output_midiman_packet(struct urb* urb, uint8_t p0, - uint8_t p1, uint8_t p2, uint8_t p3) +static void snd_usbmidi_output_midiman_packet(struct urb *urb, uint8_t p0, + uint8_t p1, uint8_t p2, + uint8_t p3) { - uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length; + uint8_t *buf = + (uint8_t *)urb->transfer_buffer + urb->transfer_buffer_length; buf[0] = p1; buf[1] = p2; buf[2] = p3; @@ -546,8 +553,8 @@ /* * Converts MIDI commands to USB MIDI packets. */ -static void snd_usbmidi_transmit_byte(struct usbmidi_out_port* port, - uint8_t b, struct urb* urb) +static void snd_usbmidi_transmit_byte(struct usbmidi_out_port *port, + uint8_t b, struct urb *urb) { uint8_t p0 = port->cable; void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t) = @@ -584,10 +591,12 @@ output_packet(urb, p0 | 0x05, 0xf7, 0, 0); break; case STATE_SYSEX_1: - output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0); + output_packet(urb, p0 | 0x06, port->data[0], + 0xf7, 0); break; case STATE_SYSEX_2: - output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7); + output_packet(urb, p0 | 0x07, port->data[0], + port->data[1], 0xf7); break; } port->state = STATE_UNKNOWN; @@ -633,21 +642,22 @@ port->state = STATE_SYSEX_2; break; case STATE_SYSEX_2: - output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b); + output_packet(urb, p0 | 0x04, port->data[0], + port->data[1], b); port->state = STATE_SYSEX_0; break; } } } -static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep, +static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint *ep, struct urb *urb) { int p; /* FIXME: lower-numbered ports can starve higher-numbered ports */ for (p = 0; p < 0x10; ++p) { - struct usbmidi_out_port* port = &ep->ports[p]; + struct usbmidi_out_port *port = &ep->ports[p]; if (!port->active) continue; while (urb->transfer_buffer_length + 3 < ep->max_transfer) { @@ -796,18 +806,18 @@ * at the third byte. */ -static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1) return; snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1); } -static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep, +static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint *ep, struct urb *urb) { - uint8_t* transfer_buffer; + uint8_t *transfer_buffer; int count; if (!ep->ports[0].active) @@ -834,13 +844,13 @@ * "raw" protocol: just move raw MIDI bytes from/to the endpoint */ -static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { snd_usbmidi_input_data(ep, 0, buffer, buffer_length); } -static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep, +static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint *ep, struct urb *urb) { int count; @@ -866,8 +876,8 @@ * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes. */ -static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { if (buffer_length > 2) snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); @@ -926,7 +936,7 @@ * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching. */ -static void snd_usbmidi_emagic_init_out(struct snd_usb_midi_out_endpoint* ep) +static void snd_usbmidi_emagic_init_out(struct snd_usb_midi_out_endpoint *ep) { static const u8 init_data[] = { /* initialization magic: "get version" */ @@ -943,7 +953,7 @@ send_bulk_static_data(ep, init_data, sizeof(init_data)); } -static void snd_usbmidi_emagic_finish_out(struct snd_usb_midi_out_endpoint* ep) +static void snd_usbmidi_emagic_finish_out(struct snd_usb_midi_out_endpoint *ep) { static const u8 finish_data[] = { /* switch to patch mode with last preset */ @@ -959,8 +969,8 @@ send_bulk_static_data(ep, finish_data, sizeof(finish_data)); } -static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint* ep, - uint8_t* buffer, int buffer_length) +static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint *ep, + uint8_t *buffer, int buffer_length) { int i; @@ -1003,18 +1013,18 @@ } } -static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep, +static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint *ep, struct urb *urb) { int port0 = ep->current_port; - uint8_t* buf = urb->transfer_buffer; + uint8_t *buf = urb->transfer_buffer; int buf_free = ep->max_transfer; int length, i; for (i = 0; i < 0x10; ++i) { /* round-robin, starting at the last current port */ int portnum = (port0 + i) & 15; - struct usbmidi_out_port* port = &ep->ports[portnum]; + struct usbmidi_out_port *port = &ep->ports[portnum]; if (!port->active) continue; @@ -1058,7 +1068,7 @@ }; -static void update_roland_altsetting(struct snd_usb_midi* umidi) +static void update_roland_altsetting(struct snd_usb_midi *umidi) { struct usb_interface *intf; struct usb_host_interface *hostif; @@ -1080,7 +1090,7 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir, int open) { - struct snd_usb_midi* umidi = substream->rmidi->private_data; + struct snd_usb_midi *umidi = substream->rmidi->private_data; struct snd_kcontrol *ctl; down_read(&umidi->disc_rwsem); @@ -1094,7 +1104,8 @@ if (!umidi->opened[0] && !umidi->opened[1]) { if (umidi->roland_load_ctl) { ctl = umidi->roland_load_ctl; - ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + ctl->vd[0].access |= + SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(umidi->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); update_roland_altsetting(umidi); @@ -1110,7 +1121,8 @@ if (!umidi->opened[0] && !umidi->opened[1]) { if (umidi->roland_load_ctl) { ctl = umidi->roland_load_ctl; - ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + ctl->vd[0].access &= + ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(umidi->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); } @@ -1123,8 +1135,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) { - struct snd_usb_midi* umidi = substream->rmidi->private_data; - struct usbmidi_out_port* port = NULL; + struct snd_usb_midi *umidi = substream->rmidi->private_data; + struct usbmidi_out_port *port = NULL; int i, j; for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) @@ -1149,9 +1161,11 @@ return substream_open(substream, 0, 0); } -static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) +static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, + int up) { - struct usbmidi_out_port* port = (struct usbmidi_out_port*)substream->runtime->private_data; + struct usbmidi_out_port *port = + (struct usbmidi_out_port *)substream->runtime->private_data; port->active = up; if (up) { @@ -1168,7 +1182,7 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) { - struct usbmidi_out_port* port = substream->runtime->private_data; + struct usbmidi_out_port *port = substream->runtime->private_data; struct snd_usb_midi_out_endpoint *ep = port->ep; unsigned int drain_urbs; DEFINE_WAIT(wait); @@ -1207,9 +1221,10 @@ return substream_open(substream, 1, 0); } -static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) +static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, + int up) { - struct snd_usb_midi* umidi = substream->rmidi->private_data; + struct snd_usb_midi *umidi = substream->rmidi->private_data; if (up) set_bit(substream->number, &umidi->input_triggered); @@ -1242,7 +1257,7 @@ * Frees an input endpoint. * May be called when ep hasn't been initialized completely. */ -static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint* ep) +static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint *ep) { unsigned int i; @@ -1256,12 +1271,12 @@ /* * Creates an input endpoint. */ -static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* ep_info, - struct snd_usb_midi_endpoint* rep) +static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *ep_info, + struct snd_usb_midi_endpoint *rep) { - struct snd_usb_midi_in_endpoint* ep; - void* buffer; + struct snd_usb_midi_in_endpoint *ep; + void *buffer; unsigned int pipe; int length; unsigned int i; @@ -1332,14 +1347,14 @@ /* * Creates an output endpoint, and initializes output ports. */ -static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* ep_info, - struct snd_usb_midi_endpoint* rep) +static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *ep_info, + struct snd_usb_midi_endpoint *rep) { - struct snd_usb_midi_out_endpoint* ep; + struct snd_usb_midi_out_endpoint *ep; unsigned int i; unsigned int pipe; - void* buffer; + void *buffer; rep->out = NULL; ep = kzalloc(sizeof(*ep), GFP_KERNEL); @@ -1425,12 +1440,12 @@ /* * Frees everything. */ -static void snd_usbmidi_free(struct snd_usb_midi* umidi) +static void snd_usbmidi_free(struct snd_usb_midi *umidi) { int i; for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { - struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; + struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; if (ep->out) snd_usbmidi_out_endpoint_delete(ep->out); if (ep->in) @@ -1443,9 +1458,9 @@ /* * Unlinks all URBs (must be done before the usb_device is deleted). */ -void snd_usbmidi_disconnect(struct list_head* p) +void snd_usbmidi_disconnect(struct list_head *p) { - struct snd_usb_midi* umidi; + struct snd_usb_midi *umidi; unsigned int i, j; umidi = list_entry(p, struct snd_usb_midi, list); @@ -1461,7 +1476,7 @@ up_write(&umidi->disc_rwsem); for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { - struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; + struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; if (ep->out) tasklet_kill(&ep->out->tasklet); if (ep->out) { @@ -1492,16 +1507,18 @@ static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi) { - struct snd_usb_midi* umidi = rmidi->private_data; + struct snd_usb_midi *umidi = rmidi->private_data; snd_usbmidi_free(umidi); } -static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi, - int stream, int number) +static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi *umidi, + int stream, + int number) { struct snd_rawmidi_substream *substream; - list_for_each_entry(substream, &umidi->rmidi->streams[stream].substreams, list) { + list_for_each_entry(substream, &umidi->rmidi->streams[stream].substreams, + list) { if (substream->number == number) return substream; } @@ -1533,6 +1550,12 @@ PORT_INFO(vendor, product, num, name, 0, \ SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \ SNDRV_SEQ_PORT_TYPE_HARDWARE) +#define GM_SYNTH_PORT(vendor, product, num, name, voices) \ + PORT_INFO(vendor, product, num, name, voices, \ + SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \ + SNDRV_SEQ_PORT_TYPE_MIDI_GM | \ + SNDRV_SEQ_PORT_TYPE_HARDWARE | \ + SNDRV_SEQ_PORT_TYPE_SYNTHESIZER) #define ROLAND_SYNTH_PORT(vendor, product, num, name, voices) \ PORT_INFO(vendor, product, num, name, voices, \ SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC | \ @@ -1552,6 +1575,11 @@ SNDRV_SEQ_PORT_TYPE_MIDI_MT32 | \ SNDRV_SEQ_PORT_TYPE_HARDWARE | \ SNDRV_SEQ_PORT_TYPE_SYNTHESIZER) + /* Yamaha MOTIF XF */ + GM_SYNTH_PORT(0x0499, 0x105c, 0, "%s Tone Generator", 128), + CONTROL_PORT(0x0499, 0x105c, 1, "%s Remote Control"), + EXTERNAL_PORT(0x0499, 0x105c, 2, "%s Thru"), + CONTROL_PORT(0x0499, 0x105c, 3, "%s Editor"), /* Roland UA-100 */ CONTROL_PORT(0x0582, 0x0000, 2, "%s Control"), /* Roland SC-8850 */ @@ -1619,8 +1647,41 @@ EXTERNAL_PORT(0x0582, 0x004d, 0, "%s MIDI"), EXTERNAL_PORT(0x0582, 0x004d, 1, "%s 1"), EXTERNAL_PORT(0x0582, 0x004d, 2, "%s 2"), + /* BOSS GT-PRO */ + CONTROL_PORT(0x0582, 0x0089, 0, "%s Control"), /* Edirol UM-3EX */ CONTROL_PORT(0x0582, 0x009a, 3, "%s Control"), + /* Roland VG-99 */ + CONTROL_PORT(0x0582, 0x00b2, 0, "%s Control"), + EXTERNAL_PORT(0x0582, 0x00b2, 1, "%s MIDI"), + /* Cakewalk Sonar V-Studio 100 */ + EXTERNAL_PORT(0x0582, 0x00eb, 0, "%s MIDI"), + CONTROL_PORT(0x0582, 0x00eb, 1, "%s Control"), + /* Roland VB-99 */ + CONTROL_PORT(0x0582, 0x0102, 0, "%s Control"), + EXTERNAL_PORT(0x0582, 0x0102, 1, "%s MIDI"), + /* Roland A-PRO */ + EXTERNAL_PORT(0x0582, 0x010f, 0, "%s MIDI"), + CONTROL_PORT(0x0582, 0x010f, 1, "%s 1"), + CONTROL_PORT(0x0582, 0x010f, 2, "%s 2"), + /* Roland SD-50 */ + ROLAND_SYNTH_PORT(0x0582, 0x0114, 0, "%s Synth", 128), + EXTERNAL_PORT(0x0582, 0x0114, 1, "%s MIDI"), + CONTROL_PORT(0x0582, 0x0114, 2, "%s Control"), + /* Roland OCTA-CAPTURE */ + EXTERNAL_PORT(0x0582, 0x0120, 0, "%s MIDI"), + CONTROL_PORT(0x0582, 0x0120, 1, "%s Control"), + EXTERNAL_PORT(0x0582, 0x0121, 0, "%s MIDI"), + CONTROL_PORT(0x0582, 0x0121, 1, "%s Control"), + /* Roland SPD-SX */ + CONTROL_PORT(0x0582, 0x0145, 0, "%s Control"), + EXTERNAL_PORT(0x0582, 0x0145, 1, "%s MIDI"), + /* Roland A-Series */ + CONTROL_PORT(0x0582, 0x0156, 0, "%s Keyboard"), + EXTERNAL_PORT(0x0582, 0x0156, 1, "%s MIDI"), + /* Roland INTEGRA-7 */ + ROLAND_SYNTH_PORT(0x0582, 0x015b, 0, "%s Synth", 128), + CONTROL_PORT(0x0582, 0x015b, 1, "%s Control"), /* M-Audio MidiSport 8x8 */ CONTROL_PORT(0x0763, 0x1031, 8, "%s Control"), CONTROL_PORT(0x0763, 0x1033, 8, "%s Control"), @@ -1644,7 +1705,7 @@ SNDRV_SEQ_PORT_TYPE_SYNTHESIZER), }; -static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number) +static struct port_info *find_port_info(struct snd_usb_midi *umidi, int number) { int i; @@ -1670,16 +1731,18 @@ } } -static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi, +static void snd_usbmidi_init_substream(struct snd_usb_midi *umidi, int stream, int number, - struct snd_rawmidi_substream ** rsubstream) + struct snd_rawmidi_substream **rsubstream) { struct port_info *port_info; const char *name_format; - struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number); + struct snd_rawmidi_substream *substream = + snd_usbmidi_find_substream(umidi, stream, number); if (!substream) { - snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number); + dev_err(&umidi->dev->dev, "substream %d:%d not found\n", stream, + number); return; } @@ -1695,21 +1758,23 @@ /* * Creates the endpoints and their ports. */ -static int snd_usbmidi_create_endpoints(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoints) +static int snd_usbmidi_create_endpoints(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoints) { int i, j, err; int out_ports = 0, in_ports = 0; for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { if (endpoints[i].out_cables) { - err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i], + err = snd_usbmidi_out_endpoint_create(umidi, + &endpoints[i], &umidi->endpoints[i]); if (err < 0) return err; } if (endpoints[i].in_cables) { - err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i], + err = snd_usbmidi_in_endpoint_create(umidi, + &endpoints[i], &umidi->endpoints[i]); if (err < 0) return err; @@ -1717,18 +1782,22 @@ for (j = 0; j < 0x10; ++j) { if (endpoints[i].out_cables & (1 << j)) { - snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, out_ports, + snd_usbmidi_init_substream(umidi, + SNDRV_RAWMIDI_STREAM_OUTPUT, + out_ports, &umidi->endpoints[i].out->ports[j].substream); ++out_ports; } if (endpoints[i].in_cables & (1 << j)) { - snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, in_ports, + snd_usbmidi_init_substream(umidi, + SNDRV_RAWMIDI_STREAM_INPUT, + in_ports, &umidi->endpoints[i].in->ports[j].substream); ++in_ports; } } } - snd_printdd(KERN_INFO "created %d output and %d input ports\n", + dev_dbg(&umidi->dev->dev, "created %d output and %d input ports\n", out_ports, in_ports); return 0; } @@ -1736,16 +1805,16 @@ /* * Returns MIDIStreaming device capabilities. */ -static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoints) +static int snd_usbmidi_get_ms_info(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoints) { - struct usb_interface* intf; + struct usb_interface *intf; struct usb_host_interface *hostif; - struct usb_interface_descriptor* intfd; - struct usb_ms_header_descriptor* ms_header; + struct usb_interface_descriptor *intfd; + struct usb_ms_header_descriptor *ms_header; struct usb_host_endpoint *hostep; - struct usb_endpoint_descriptor* ep; - struct usb_ms_endpoint_descriptor* ms_ep; + struct usb_endpoint_descriptor *ep; + struct usb_ms_endpoint_descriptor *ms_ep; int i, epidx; intf = umidi->iface; @@ -1753,15 +1822,16 @@ return -ENXIO; hostif = &intf->altsetting[0]; intfd = get_iface_desc(hostif); - ms_header = (struct usb_ms_header_descriptor*)hostif->extra; + ms_header = (struct usb_ms_header_descriptor *)hostif->extra; if (hostif->extralen >= 7 && ms_header->bLength >= 7 && ms_header->bDescriptorType == USB_DT_CS_INTERFACE && ms_header->bDescriptorSubtype == UAC_HEADER) - snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", + dev_dbg(&umidi->dev->dev, "MIDIStreaming version %02x.%02x\n", ms_header->bcdMSC[1], ms_header->bcdMSC[0]); else - snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n"); + dev_warn(&umidi->dev->dev, + "MIDIStreaming interface descriptor not found\n"); epidx = 0; for (i = 0; i < intfd->bNumEndpoints; ++i) { @@ -1769,7 +1839,7 @@ ep = get_ep_desc(hostep); if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep)) continue; - ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra; + ms_ep = (struct usb_ms_endpoint_descriptor *)hostep->extra; if (hostep->extralen < 4 || ms_ep->bLength < 4 || ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || @@ -1778,7 +1848,8 @@ if (usb_endpoint_dir_out(ep)) { if (endpoints[epidx].out_ep) { if (++epidx >= MIDI_MAX_ENDPOINTS) { - snd_printk(KERN_WARNING "too many endpoints\n"); + dev_warn(&umidi->dev->dev, + "too many endpoints\n"); break; } } @@ -1792,13 +1863,15 @@ * ESI MIDI Mate that try to use them anyway. */ endpoints[epidx].out_interval = 1; - endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; - snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", - ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); + endpoints[epidx].out_cables = + (1 << ms_ep->bNumEmbMIDIJack) - 1; + dev_dbg(&umidi->dev->dev, "EP %02X: %d jack(s)\n", + ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); } else { if (endpoints[epidx].in_ep) { if (++epidx >= MIDI_MAX_ENDPOINTS) { - snd_printk(KERN_WARNING "too many endpoints\n"); + dev_warn(&umidi->dev->dev, + "too many endpoints\n"); break; } } @@ -1807,9 +1880,10 @@ endpoints[epidx].in_interval = ep->bInterval; else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW) endpoints[epidx].in_interval = 1; - endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; - snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", - ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); + endpoints[epidx].in_cables = + (1 << ms_ep->bNumEmbMIDIJack) - 1; + dev_dbg(&umidi->dev->dev, "EP %02X: %d jack(s)\n", + ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); } } return 0; @@ -1833,7 +1907,7 @@ static int roland_load_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) { - struct snd_usb_midi* umidi = kcontrol->private_data; + struct snd_usb_midi *umidi = kcontrol->private_data; int changed; if (value->value.enumerated.item[0] > 1) @@ -1859,11 +1933,11 @@ * On Roland devices, use the second alternate setting to be able to use * the interrupt input endpoint. */ -static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi) +static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi *umidi) { - struct usb_interface* intf; + struct usb_interface *intf; struct usb_host_interface *hostif; - struct usb_interface_descriptor* intfd; + struct usb_interface_descriptor *intfd; intf = umidi->iface; if (!intf || intf->num_altsetting != 2) @@ -1871,12 +1945,17 @@ hostif = &intf->altsetting[1]; intfd = get_iface_desc(hostif); + /* If either or both of the endpoints support interrupt transfer, + * then use the alternate setting + */ if (intfd->bNumEndpoints != 2 || - (get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || - (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) + !((get_endpoint(hostif, 0)->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT || + (get_endpoint(hostif, 1)->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) return; - snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", + dev_dbg(&umidi->dev->dev, "switching to altsetting %d with int ep\n", intfd->bAlternateSetting); usb_set_interface(umidi->dev, intfd->bInterfaceNumber, intfd->bAlternateSetting); @@ -1889,14 +1968,14 @@ /* * Try to find any usable endpoints in the interface. */ -static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoint, +static int snd_usbmidi_detect_endpoints(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoint, int max_endpoints) { - struct usb_interface* intf; + struct usb_interface *intf; struct usb_host_interface *hostif; - struct usb_interface_descriptor* intfd; - struct usb_endpoint_descriptor* epd; + struct usb_interface_descriptor *intfd; + struct usb_endpoint_descriptor *epd; int i, out_eps = 0, in_eps = 0; if (USB_ID_VENDOR(umidi->usb_id) == 0x0582) @@ -1937,8 +2016,8 @@ /* * Detects the endpoints for one-port-per-endpoint protocols. */ -static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoints) +static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoints) { int err, i; @@ -1955,13 +2034,13 @@ /* * Detects the endpoints and ports of Yamaha devices. */ -static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoint) +static int snd_usbmidi_detect_yamaha(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoint) { - struct usb_interface* intf; + struct usb_interface *intf; struct usb_host_interface *hostif; - struct usb_interface_descriptor* intfd; - uint8_t* cs_desc; + struct usb_interface_descriptor *intfd; + uint8_t *cs_desc; intf = umidi->iface; if (!intf) @@ -1980,9 +2059,11 @@ cs_desc += cs_desc[0]) { if (cs_desc[1] == USB_DT_CS_INTERFACE) { if (cs_desc[2] == UAC_MIDI_IN_JACK) - endpoint->in_cables = (endpoint->in_cables << 1) | 1; + endpoint->in_cables = + (endpoint->in_cables << 1) | 1; else if (cs_desc[2] == UAC_MIDI_OUT_JACK) - endpoint->out_cables = (endpoint->out_cables << 1) | 1; + endpoint->out_cables = + (endpoint->out_cables << 1) | 1; } } if (!endpoint->in_cables && !endpoint->out_cables) @@ -1992,16 +2073,54 @@ } /* + * Detects the endpoints and ports of Roland devices. + */ +static int snd_usbmidi_detect_roland(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoint) +{ + struct usb_interface *intf; + struct usb_host_interface *hostif; + u8 *cs_desc; + + intf = umidi->iface; + if (!intf) + return -ENOENT; + hostif = intf->altsetting; + /* + * Some devices have a descriptor <06 24 F1 02 >, + * some have standard class descriptors, or both kinds, or neither. + */ + for (cs_desc = hostif->extra; + cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; + cs_desc += cs_desc[0]) { + if (cs_desc[0] >= 6 && + cs_desc[1] == USB_DT_CS_INTERFACE && + cs_desc[2] == 0xf1 && + cs_desc[3] == 0x02) { + endpoint->in_cables = (1 << cs_desc[4]) - 1; + endpoint->out_cables = (1 << cs_desc[5]) - 1; + return snd_usbmidi_detect_endpoints(umidi, endpoint, 1); + } else if (cs_desc[0] >= 7 && + cs_desc[1] == USB_DT_CS_INTERFACE && + cs_desc[2] == UAC_HEADER) { + return snd_usbmidi_get_ms_info(umidi, endpoint); + } + } + + return -ENODEV; +} + +/* * Creates the endpoints and their ports for Midiman devices. */ -static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi, - struct snd_usb_midi_endpoint_info* endpoint) +static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi *umidi, + struct snd_usb_midi_endpoint_info *endpoint) { struct snd_usb_midi_endpoint_info ep_info; - struct usb_interface* intf; + struct usb_interface *intf; struct usb_host_interface *hostif; - struct usb_interface_descriptor* intfd; - struct usb_endpoint_descriptor* epd; + struct usb_interface_descriptor *intfd; + struct usb_endpoint_descriptor *epd; int cable, err; intf = umidi->iface; @@ -2020,57 +2139,68 @@ * input bulk endpoints (at indices 1 and 3) which aren't used. */ if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) { - snd_printdd(KERN_ERR "not enough endpoints\n"); + dev_dbg(&umidi->dev->dev, "not enough endpoints\n"); return -ENOENT; } epd = get_endpoint(hostif, 0); if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) { - snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n"); + dev_dbg(&umidi->dev->dev, "endpoint[0] isn't interrupt\n"); return -ENXIO; } epd = get_endpoint(hostif, 2); if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) { - snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n"); + dev_dbg(&umidi->dev->dev, "endpoint[2] isn't bulk output\n"); return -ENXIO; } if (endpoint->out_cables > 0x0001) { epd = get_endpoint(hostif, 4); if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) { - snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n"); + dev_dbg(&umidi->dev->dev, + "endpoint[4] isn't bulk output\n"); return -ENXIO; } } - ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; ep_info.out_interval = 0; ep_info.out_cables = endpoint->out_cables & 0x5555; - err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); + err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, + &umidi->endpoints[0]); if (err < 0) return err; - ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; ep_info.in_interval = get_endpoint(hostif, 0)->bInterval; ep_info.in_cables = endpoint->in_cables; - err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); + err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, + &umidi->endpoints[0]); if (err < 0) return err; if (endpoint->out_cables > 0x0001) { - ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; ep_info.out_cables = endpoint->out_cables & 0xaaaa; - err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]); + err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, + &umidi->endpoints[1]); if (err < 0) return err; } for (cable = 0; cable < 0x10; ++cable) { if (endpoint->out_cables & (1 << cable)) - snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, cable, + snd_usbmidi_init_substream(umidi, + SNDRV_RAWMIDI_STREAM_OUTPUT, + cable, &umidi->endpoints[cable & 1].out->ports[cable].substream); if (endpoint->in_cables & (1 << cable)) - snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, cable, + snd_usbmidi_init_substream(umidi, + SNDRV_RAWMIDI_STREAM_INPUT, + cable, &umidi->endpoints[0].in->ports[cable].substream); } return 0; @@ -2080,7 +2210,7 @@ .get_port_info = snd_usbmidi_get_port_info, }; -static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi, +static int snd_usbmidi_create_rawmidi(struct snd_usb_midi *umidi, int out_ports, int in_ports) { struct snd_rawmidi *rmidi; @@ -2098,8 +2228,10 @@ rmidi->ops = &snd_usbmidi_ops; rmidi->private_data = umidi; rmidi->private_free = snd_usbmidi_rawmidi_free; - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops); - snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input_ops); + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_usbmidi_output_ops); + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_usbmidi_input_ops); umidi->rmidi = rmidi; return 0; @@ -2108,16 +2240,16 @@ /* * Temporarily stop input. */ -void snd_usbmidi_input_stop(struct list_head* p) +void snd_usbmidi_input_stop(struct list_head *p) { - struct snd_usb_midi* umidi; + struct snd_usb_midi *umidi; unsigned int i, j; umidi = list_entry(p, struct snd_usb_midi, list); if (!umidi->input_running) return; for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { - struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; + struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i]; if (ep->in) for (j = 0; j < INPUT_URBS; ++j) usb_kill_urb(ep->in->urbs[j]); @@ -2126,14 +2258,14 @@ } EXPORT_SYMBOL(snd_usbmidi_input_stop); -static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) +static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint *ep) { unsigned int i; if (!ep) return; for (i = 0; i < INPUT_URBS; ++i) { - struct urb* urb = ep->urbs[i]; + struct urb *urb = ep->urbs[i]; urb->dev = ep->umidi->dev; snd_usbmidi_submit_urb(urb, GFP_KERNEL); } @@ -2142,9 +2274,9 @@ /* * Resume input after a call to snd_usbmidi_input_stop(). */ -void snd_usbmidi_input_start(struct list_head* p) +void snd_usbmidi_input_start(struct list_head *p) { - struct snd_usb_midi* umidi; + struct snd_usb_midi *umidi; int i; umidi = list_entry(p, struct snd_usb_midi, list); @@ -2157,14 +2289,42 @@ EXPORT_SYMBOL(snd_usbmidi_input_start); /* + * Prepare for suspend. Typically called from the USB suspend callback. + */ +void snd_usbmidi_suspend(struct list_head *p) +{ + struct snd_usb_midi *umidi; + + umidi = list_entry(p, struct snd_usb_midi, list); + mutex_lock(&umidi->mutex); + snd_usbmidi_input_stop(p); + mutex_unlock(&umidi->mutex); +} +EXPORT_SYMBOL(snd_usbmidi_suspend); + +/* + * Resume. Typically called from the USB resume callback. + */ +void snd_usbmidi_resume(struct list_head *p) +{ + struct snd_usb_midi *umidi; + + umidi = list_entry(p, struct snd_usb_midi, list); + mutex_lock(&umidi->mutex); + snd_usbmidi_input_start(p); + mutex_unlock(&umidi->mutex); +} +EXPORT_SYMBOL(snd_usbmidi_resume); + +/* * Creates and registers everything needed for a MIDI streaming interface. */ int snd_usbmidi_create(struct snd_card *card, - struct usb_interface* iface, + struct usb_interface *iface, struct list_head *midi_list, - const struct snd_usb_audio_quirk* quirk) + const struct snd_usb_audio_quirk *quirk) { - struct snd_usb_midi* umidi; + struct snd_usb_midi *umidi; struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; int out_ports, in_ports; int i, err; @@ -2177,14 +2337,13 @@ umidi->iface = iface; umidi->quirk = quirk; umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; - init_timer(&umidi->error_timer); spin_lock_init(&umidi->disc_lock); init_rwsem(&umidi->disc_rwsem); mutex_init(&umidi->mutex); umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), le16_to_cpu(umidi->dev->descriptor.idProduct)); - umidi->error_timer.function = snd_usbmidi_error_timer; - umidi->error_timer.data = (unsigned long)umidi; + setup_timer(&umidi->error_timer, snd_usbmidi_error_timer, + (unsigned long)umidi); /* detect the endpoint(s) to use */ memset(endpoints, 0, sizeof(endpoints)); @@ -2206,6 +2365,9 @@ case QUIRK_MIDI_YAMAHA: err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]); break; + case QUIRK_MIDI_ROLAND: + err = snd_usbmidi_detect_roland(umidi, &endpoints[0]); + break; case QUIRK_MIDI_MIDIMAN: umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops; memcpy(&endpoints[0], quirk->data, @@ -2263,7 +2425,8 @@ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; default: - snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); + dev_err(&umidi->dev->dev, "invalid quirk type %d\n", + quirk->type); err = -ENXIO; break; }