diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/usb/usbmidi.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'sound/usb/usbmidi.c')
-rw-r--r-- | sound/usb/usbmidi.c | 1564 |
1 files changed, 1564 insertions, 0 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c new file mode 100644 index 000000000000..5d32857ff955 --- /dev/null +++ b/sound/usb/usbmidi.c | |||
@@ -0,0 +1,1564 @@ | |||
1 | /* | ||
2 | * usbmidi.c - ALSA USB MIDI driver | ||
3 | * | ||
4 | * Copyright (c) 2002-2005 Clemens Ladisch | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Based on the OSS usb-midi driver by NAGANO Daisuke, | ||
8 | * NetBSD's umidi driver by Takuya SHIOZAKI, | ||
9 | * the "USB Device Class Definition for MIDI Devices" by Roland | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. The name of the author may not be used to endorse or promote products | ||
18 | * derived from this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed and/or modified under the | ||
21 | * terms of the GNU General Public License as published by the Free Software | ||
22 | * Foundation; either version 2 of the License, or (at your option) any later | ||
23 | * version. | ||
24 | * | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | ||
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR | ||
29 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
35 | * SUCH DAMAGE. | ||
36 | */ | ||
37 | |||
38 | #include <sound/driver.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/types.h> | ||
41 | #include <linux/bitops.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/string.h> | ||
45 | #include <linux/init.h> | ||
46 | #include <linux/slab.h> | ||
47 | #include <linux/usb.h> | ||
48 | #include <sound/core.h> | ||
49 | #include <sound/minors.h> | ||
50 | #include <sound/rawmidi.h> | ||
51 | #include "usbaudio.h" | ||
52 | |||
53 | |||
54 | /* | ||
55 | * define this to log all USB packets | ||
56 | */ | ||
57 | /* #define DUMP_PACKETS */ | ||
58 | |||
59 | |||
60 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
61 | MODULE_DESCRIPTION("USB Audio/MIDI helper module"); | ||
62 | MODULE_LICENSE("Dual BSD/GPL"); | ||
63 | |||
64 | |||
65 | struct usb_ms_header_descriptor { | ||
66 | __u8 bLength; | ||
67 | __u8 bDescriptorType; | ||
68 | __u8 bDescriptorSubtype; | ||
69 | __u8 bcdMSC[2]; | ||
70 | __le16 wTotalLength; | ||
71 | } __attribute__ ((packed)); | ||
72 | |||
73 | struct usb_ms_endpoint_descriptor { | ||
74 | __u8 bLength; | ||
75 | __u8 bDescriptorType; | ||
76 | __u8 bDescriptorSubtype; | ||
77 | __u8 bNumEmbMIDIJack; | ||
78 | __u8 baAssocJackID[0]; | ||
79 | } __attribute__ ((packed)); | ||
80 | |||
81 | typedef struct snd_usb_midi snd_usb_midi_t; | ||
82 | typedef struct snd_usb_midi_endpoint snd_usb_midi_endpoint_t; | ||
83 | typedef struct snd_usb_midi_out_endpoint snd_usb_midi_out_endpoint_t; | ||
84 | typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t; | ||
85 | typedef struct usbmidi_out_port usbmidi_out_port_t; | ||
86 | typedef struct usbmidi_in_port usbmidi_in_port_t; | ||
87 | |||
88 | struct usb_protocol_ops { | ||
89 | void (*input)(snd_usb_midi_in_endpoint_t*, uint8_t*, int); | ||
90 | void (*output)(snd_usb_midi_out_endpoint_t*); | ||
91 | void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t); | ||
92 | void (*init_out_endpoint)(snd_usb_midi_out_endpoint_t*); | ||
93 | void (*finish_out_endpoint)(snd_usb_midi_out_endpoint_t*); | ||
94 | }; | ||
95 | |||
96 | struct snd_usb_midi { | ||
97 | snd_usb_audio_t *chip; | ||
98 | struct usb_interface *iface; | ||
99 | const snd_usb_audio_quirk_t *quirk; | ||
100 | snd_rawmidi_t* rmidi; | ||
101 | struct usb_protocol_ops* usb_protocol_ops; | ||
102 | struct list_head list; | ||
103 | |||
104 | struct snd_usb_midi_endpoint { | ||
105 | snd_usb_midi_out_endpoint_t *out; | ||
106 | snd_usb_midi_in_endpoint_t *in; | ||
107 | } endpoints[MIDI_MAX_ENDPOINTS]; | ||
108 | unsigned long input_triggered; | ||
109 | }; | ||
110 | |||
111 | struct snd_usb_midi_out_endpoint { | ||
112 | snd_usb_midi_t* umidi; | ||
113 | struct urb* urb; | ||
114 | int urb_active; | ||
115 | int max_transfer; /* size of urb buffer */ | ||
116 | struct tasklet_struct tasklet; | ||
117 | |||
118 | spinlock_t buffer_lock; | ||
119 | |||
120 | struct usbmidi_out_port { | ||
121 | snd_usb_midi_out_endpoint_t* ep; | ||
122 | snd_rawmidi_substream_t* substream; | ||
123 | int active; | ||
124 | uint8_t cable; /* cable number << 4 */ | ||
125 | uint8_t state; | ||
126 | #define STATE_UNKNOWN 0 | ||
127 | #define STATE_1PARAM 1 | ||
128 | #define STATE_2PARAM_1 2 | ||
129 | #define STATE_2PARAM_2 3 | ||
130 | #define STATE_SYSEX_0 4 | ||
131 | #define STATE_SYSEX_1 5 | ||
132 | #define STATE_SYSEX_2 6 | ||
133 | uint8_t data[2]; | ||
134 | } ports[0x10]; | ||
135 | int current_port; | ||
136 | }; | ||
137 | |||
138 | struct snd_usb_midi_in_endpoint { | ||
139 | snd_usb_midi_t* umidi; | ||
140 | struct urb* urb; | ||
141 | struct usbmidi_in_port { | ||
142 | snd_rawmidi_substream_t* substream; | ||
143 | } ports[0x10]; | ||
144 | int seen_f5; | ||
145 | int current_port; | ||
146 | }; | ||
147 | |||
148 | static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep); | ||
149 | |||
150 | static const uint8_t snd_usbmidi_cin_length[] = { | ||
151 | 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1 | ||
152 | }; | ||
153 | |||
154 | /* | ||
155 | * Submits the URB, with error handling. | ||
156 | */ | ||
157 | static int snd_usbmidi_submit_urb(struct urb* urb, int flags) | ||
158 | { | ||
159 | int err = usb_submit_urb(urb, flags); | ||
160 | if (err < 0 && err != -ENODEV) | ||
161 | snd_printk(KERN_ERR "usb_submit_urb: %d\n", err); | ||
162 | return err; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Error handling for URB completion functions. | ||
167 | */ | ||
168 | static int snd_usbmidi_urb_error(int status) | ||
169 | { | ||
170 | if (status == -ENOENT) | ||
171 | return status; /* killed */ | ||
172 | if (status == -EILSEQ || | ||
173 | status == -ECONNRESET || | ||
174 | status == -ETIMEDOUT) | ||
175 | return -ENODEV; /* device removed/shutdown */ | ||
176 | snd_printk(KERN_ERR "urb status %d\n", status); | ||
177 | return 0; /* continue */ | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Receives a chunk of MIDI data. | ||
182 | */ | ||
183 | static void snd_usbmidi_input_data(snd_usb_midi_in_endpoint_t* ep, int portidx, | ||
184 | uint8_t* data, int length) | ||
185 | { | ||
186 | usbmidi_in_port_t* port = &ep->ports[portidx]; | ||
187 | |||
188 | if (!port->substream) { | ||
189 | snd_printd("unexpected port %d!\n", portidx); | ||
190 | return; | ||
191 | } | ||
192 | if (!test_bit(port->substream->number, &ep->umidi->input_triggered)) | ||
193 | return; | ||
194 | snd_rawmidi_receive(port->substream, data, length); | ||
195 | } | ||
196 | |||
197 | #ifdef DUMP_PACKETS | ||
198 | static void dump_urb(const char *type, const u8 *data, int length) | ||
199 | { | ||
200 | snd_printk(KERN_DEBUG "%s packet: [", type); | ||
201 | for (; length > 0; ++data, --length) | ||
202 | printk(" %02x", *data); | ||
203 | printk(" ]\n"); | ||
204 | } | ||
205 | #else | ||
206 | #define dump_urb(type, data, length) /* nothing */ | ||
207 | #endif | ||
208 | |||
209 | /* | ||
210 | * Processes the data read from the device. | ||
211 | */ | ||
212 | static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs) | ||
213 | { | ||
214 | snd_usb_midi_in_endpoint_t* ep = urb->context; | ||
215 | |||
216 | if (urb->status == 0) { | ||
217 | dump_urb("received", urb->transfer_buffer, urb->actual_length); | ||
218 | ep->umidi->usb_protocol_ops->input(ep, urb->transfer_buffer, | ||
219 | urb->actual_length); | ||
220 | } else { | ||
221 | if (snd_usbmidi_urb_error(urb->status) < 0) | ||
222 | return; | ||
223 | } | ||
224 | |||
225 | if (usb_pipe_needs_resubmit(urb->pipe)) { | ||
226 | urb->dev = ep->umidi->chip->dev; | ||
227 | snd_usbmidi_submit_urb(urb, GFP_ATOMIC); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs) | ||
232 | { | ||
233 | snd_usb_midi_out_endpoint_t* ep = urb->context; | ||
234 | |||
235 | spin_lock(&ep->buffer_lock); | ||
236 | ep->urb_active = 0; | ||
237 | spin_unlock(&ep->buffer_lock); | ||
238 | if (urb->status < 0) { | ||
239 | if (snd_usbmidi_urb_error(urb->status) < 0) | ||
240 | return; | ||
241 | } | ||
242 | snd_usbmidi_do_output(ep); | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * This is called when some data should be transferred to the device | ||
247 | * (from one or more substreams). | ||
248 | */ | ||
249 | static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep) | ||
250 | { | ||
251 | struct urb* urb = ep->urb; | ||
252 | unsigned long flags; | ||
253 | |||
254 | spin_lock_irqsave(&ep->buffer_lock, flags); | ||
255 | if (ep->urb_active || ep->umidi->chip->shutdown) { | ||
256 | spin_unlock_irqrestore(&ep->buffer_lock, flags); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | urb->transfer_buffer_length = 0; | ||
261 | ep->umidi->usb_protocol_ops->output(ep); | ||
262 | |||
263 | if (urb->transfer_buffer_length > 0) { | ||
264 | dump_urb("sending", urb->transfer_buffer, | ||
265 | urb->transfer_buffer_length); | ||
266 | urb->dev = ep->umidi->chip->dev; | ||
267 | ep->urb_active = snd_usbmidi_submit_urb(urb, GFP_ATOMIC) >= 0; | ||
268 | } | ||
269 | spin_unlock_irqrestore(&ep->buffer_lock, flags); | ||
270 | } | ||
271 | |||
272 | static void snd_usbmidi_out_tasklet(unsigned long data) | ||
273 | { | ||
274 | snd_usb_midi_out_endpoint_t* ep = (snd_usb_midi_out_endpoint_t *) data; | ||
275 | |||
276 | snd_usbmidi_do_output(ep); | ||
277 | } | ||
278 | |||
279 | /* helper function to send static data that may not DMA-able */ | ||
280 | static int send_bulk_static_data(snd_usb_midi_out_endpoint_t* ep, | ||
281 | const void *data, int len) | ||
282 | { | ||
283 | int err; | ||
284 | void *buf = kmalloc(len, GFP_KERNEL); | ||
285 | if (!buf) | ||
286 | return -ENOMEM; | ||
287 | memcpy(buf, data, len); | ||
288 | dump_urb("sending", buf, len); | ||
289 | err = usb_bulk_msg(ep->umidi->chip->dev, ep->urb->pipe, buf, len, | ||
290 | NULL, 250); | ||
291 | kfree(buf); | ||
292 | return err; | ||
293 | } | ||
294 | |||
295 | /* | ||
296 | * Standard USB MIDI protocol: see the spec. | ||
297 | * Midiman protocol: like the standard protocol, but the control byte is the | ||
298 | * fourth byte in each packet, and uses length instead of CIN. | ||
299 | */ | ||
300 | |||
301 | static void snd_usbmidi_standard_input(snd_usb_midi_in_endpoint_t* ep, | ||
302 | uint8_t* buffer, int buffer_length) | ||
303 | { | ||
304 | int i; | ||
305 | |||
306 | for (i = 0; i + 3 < buffer_length; i += 4) | ||
307 | if (buffer[i] != 0) { | ||
308 | int cable = buffer[i] >> 4; | ||
309 | int length = snd_usbmidi_cin_length[buffer[i] & 0x0f]; | ||
310 | snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | static void snd_usbmidi_midiman_input(snd_usb_midi_in_endpoint_t* ep, | ||
315 | uint8_t* buffer, int buffer_length) | ||
316 | { | ||
317 | int i; | ||
318 | |||
319 | for (i = 0; i + 3 < buffer_length; i += 4) | ||
320 | if (buffer[i + 3] != 0) { | ||
321 | int port = buffer[i + 3] >> 4; | ||
322 | int length = buffer[i + 3] & 3; | ||
323 | snd_usbmidi_input_data(ep, port, &buffer[i], length); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * Adds one USB MIDI packet to the output buffer. | ||
329 | */ | ||
330 | static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, | ||
331 | uint8_t p1, uint8_t p2, uint8_t p3) | ||
332 | { | ||
333 | |||
334 | uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length; | ||
335 | buf[0] = p0; | ||
336 | buf[1] = p1; | ||
337 | buf[2] = p2; | ||
338 | buf[3] = p3; | ||
339 | urb->transfer_buffer_length += 4; | ||
340 | } | ||
341 | |||
342 | /* | ||
343 | * Adds one Midiman packet to the output buffer. | ||
344 | */ | ||
345 | static void snd_usbmidi_output_midiman_packet(struct urb* urb, uint8_t p0, | ||
346 | uint8_t p1, uint8_t p2, uint8_t p3) | ||
347 | { | ||
348 | |||
349 | uint8_t* buf = (uint8_t*)urb->transfer_buffer + urb->transfer_buffer_length; | ||
350 | buf[0] = p1; | ||
351 | buf[1] = p2; | ||
352 | buf[2] = p3; | ||
353 | buf[3] = (p0 & 0xf0) | snd_usbmidi_cin_length[p0 & 0x0f]; | ||
354 | urb->transfer_buffer_length += 4; | ||
355 | } | ||
356 | |||
357 | /* | ||
358 | * Converts MIDI commands to USB MIDI packets. | ||
359 | */ | ||
360 | static void snd_usbmidi_transmit_byte(usbmidi_out_port_t* port, | ||
361 | uint8_t b, struct urb* urb) | ||
362 | { | ||
363 | uint8_t p0 = port->cable; | ||
364 | void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t) = | ||
365 | port->ep->umidi->usb_protocol_ops->output_packet; | ||
366 | |||
367 | if (b >= 0xf8) { | ||
368 | output_packet(urb, p0 | 0x0f, b, 0, 0); | ||
369 | } else if (b >= 0xf0) { | ||
370 | switch (b) { | ||
371 | case 0xf0: | ||
372 | port->data[0] = b; | ||
373 | port->state = STATE_SYSEX_1; | ||
374 | break; | ||
375 | case 0xf1: | ||
376 | case 0xf3: | ||
377 | port->data[0] = b; | ||
378 | port->state = STATE_1PARAM; | ||
379 | break; | ||
380 | case 0xf2: | ||
381 | port->data[0] = b; | ||
382 | port->state = STATE_2PARAM_1; | ||
383 | break; | ||
384 | case 0xf4: | ||
385 | case 0xf5: | ||
386 | port->state = STATE_UNKNOWN; | ||
387 | break; | ||
388 | case 0xf6: | ||
389 | output_packet(urb, p0 | 0x05, 0xf6, 0, 0); | ||
390 | port->state = STATE_UNKNOWN; | ||
391 | break; | ||
392 | case 0xf7: | ||
393 | switch (port->state) { | ||
394 | case STATE_SYSEX_0: | ||
395 | output_packet(urb, p0 | 0x05, 0xf7, 0, 0); | ||
396 | break; | ||
397 | case STATE_SYSEX_1: | ||
398 | output_packet(urb, p0 | 0x06, port->data[0], 0xf7, 0); | ||
399 | break; | ||
400 | case STATE_SYSEX_2: | ||
401 | output_packet(urb, p0 | 0x07, port->data[0], port->data[1], 0xf7); | ||
402 | break; | ||
403 | } | ||
404 | port->state = STATE_UNKNOWN; | ||
405 | break; | ||
406 | } | ||
407 | } else if (b >= 0x80) { | ||
408 | port->data[0] = b; | ||
409 | if (b >= 0xc0 && b <= 0xdf) | ||
410 | port->state = STATE_1PARAM; | ||
411 | else | ||
412 | port->state = STATE_2PARAM_1; | ||
413 | } else { /* b < 0x80 */ | ||
414 | switch (port->state) { | ||
415 | case STATE_1PARAM: | ||
416 | if (port->data[0] < 0xf0) { | ||
417 | p0 |= port->data[0] >> 4; | ||
418 | } else { | ||
419 | p0 |= 0x02; | ||
420 | port->state = STATE_UNKNOWN; | ||
421 | } | ||
422 | output_packet(urb, p0, port->data[0], b, 0); | ||
423 | break; | ||
424 | case STATE_2PARAM_1: | ||
425 | port->data[1] = b; | ||
426 | port->state = STATE_2PARAM_2; | ||
427 | break; | ||
428 | case STATE_2PARAM_2: | ||
429 | if (port->data[0] < 0xf0) { | ||
430 | p0 |= port->data[0] >> 4; | ||
431 | port->state = STATE_2PARAM_1; | ||
432 | } else { | ||
433 | p0 |= 0x03; | ||
434 | port->state = STATE_UNKNOWN; | ||
435 | } | ||
436 | output_packet(urb, p0, port->data[0], port->data[1], b); | ||
437 | break; | ||
438 | case STATE_SYSEX_0: | ||
439 | port->data[0] = b; | ||
440 | port->state = STATE_SYSEX_1; | ||
441 | break; | ||
442 | case STATE_SYSEX_1: | ||
443 | port->data[1] = b; | ||
444 | port->state = STATE_SYSEX_2; | ||
445 | break; | ||
446 | case STATE_SYSEX_2: | ||
447 | output_packet(urb, p0 | 0x04, port->data[0], port->data[1], b); | ||
448 | port->state = STATE_SYSEX_0; | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | static void snd_usbmidi_standard_output(snd_usb_midi_out_endpoint_t* ep) | ||
455 | { | ||
456 | struct urb* urb = ep->urb; | ||
457 | int p; | ||
458 | |||
459 | /* FIXME: lower-numbered ports can starve higher-numbered ports */ | ||
460 | for (p = 0; p < 0x10; ++p) { | ||
461 | usbmidi_out_port_t* port = &ep->ports[p]; | ||
462 | if (!port->active) | ||
463 | continue; | ||
464 | while (urb->transfer_buffer_length + 3 < ep->max_transfer) { | ||
465 | uint8_t b; | ||
466 | if (snd_rawmidi_transmit(port->substream, &b, 1) != 1) { | ||
467 | port->active = 0; | ||
468 | break; | ||
469 | } | ||
470 | snd_usbmidi_transmit_byte(port, b, urb); | ||
471 | } | ||
472 | } | ||
473 | } | ||
474 | |||
475 | static struct usb_protocol_ops snd_usbmidi_standard_ops = { | ||
476 | .input = snd_usbmidi_standard_input, | ||
477 | .output = snd_usbmidi_standard_output, | ||
478 | .output_packet = snd_usbmidi_output_standard_packet, | ||
479 | }; | ||
480 | |||
481 | static struct usb_protocol_ops snd_usbmidi_midiman_ops = { | ||
482 | .input = snd_usbmidi_midiman_input, | ||
483 | .output = snd_usbmidi_standard_output, | ||
484 | .output_packet = snd_usbmidi_output_midiman_packet, | ||
485 | }; | ||
486 | |||
487 | /* | ||
488 | * Novation USB MIDI protocol: number of data bytes is in the first byte | ||
489 | * (when receiving) (+1!) or in the second byte (when sending); data begins | ||
490 | * at the third byte. | ||
491 | */ | ||
492 | |||
493 | static void snd_usbmidi_novation_input(snd_usb_midi_in_endpoint_t* ep, | ||
494 | uint8_t* buffer, int buffer_length) | ||
495 | { | ||
496 | if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1) | ||
497 | return; | ||
498 | snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1); | ||
499 | } | ||
500 | |||
501 | static void snd_usbmidi_novation_output(snd_usb_midi_out_endpoint_t* ep) | ||
502 | { | ||
503 | uint8_t* transfer_buffer; | ||
504 | int count; | ||
505 | |||
506 | if (!ep->ports[0].active) | ||
507 | return; | ||
508 | transfer_buffer = ep->urb->transfer_buffer; | ||
509 | count = snd_rawmidi_transmit(ep->ports[0].substream, | ||
510 | &transfer_buffer[2], | ||
511 | ep->max_transfer - 2); | ||
512 | if (count < 1) { | ||
513 | ep->ports[0].active = 0; | ||
514 | return; | ||
515 | } | ||
516 | transfer_buffer[0] = 0; | ||
517 | transfer_buffer[1] = count; | ||
518 | ep->urb->transfer_buffer_length = 2 + count; | ||
519 | } | ||
520 | |||
521 | static struct usb_protocol_ops snd_usbmidi_novation_ops = { | ||
522 | .input = snd_usbmidi_novation_input, | ||
523 | .output = snd_usbmidi_novation_output, | ||
524 | }; | ||
525 | |||
526 | /* | ||
527 | * Mark of the Unicorn USB MIDI protocol: raw MIDI. | ||
528 | */ | ||
529 | |||
530 | static void snd_usbmidi_motu_input(snd_usb_midi_in_endpoint_t* ep, | ||
531 | uint8_t* buffer, int buffer_length) | ||
532 | { | ||
533 | snd_usbmidi_input_data(ep, 0, buffer, buffer_length); | ||
534 | } | ||
535 | |||
536 | static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep) | ||
537 | { | ||
538 | int count; | ||
539 | |||
540 | if (!ep->ports[0].active) | ||
541 | return; | ||
542 | count = snd_rawmidi_transmit(ep->ports[0].substream, | ||
543 | ep->urb->transfer_buffer, | ||
544 | ep->max_transfer); | ||
545 | if (count < 1) { | ||
546 | ep->ports[0].active = 0; | ||
547 | return; | ||
548 | } | ||
549 | ep->urb->transfer_buffer_length = count; | ||
550 | } | ||
551 | |||
552 | static struct usb_protocol_ops snd_usbmidi_motu_ops = { | ||
553 | .input = snd_usbmidi_motu_input, | ||
554 | .output = snd_usbmidi_motu_output, | ||
555 | }; | ||
556 | |||
557 | /* | ||
558 | * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching. | ||
559 | */ | ||
560 | |||
561 | static void snd_usbmidi_emagic_init_out(snd_usb_midi_out_endpoint_t* ep) | ||
562 | { | ||
563 | static const u8 init_data[] = { | ||
564 | /* initialization magic: "get version" */ | ||
565 | 0xf0, | ||
566 | 0x00, 0x20, 0x31, /* Emagic */ | ||
567 | 0x64, /* Unitor8 */ | ||
568 | 0x0b, /* version number request */ | ||
569 | 0x00, /* command version */ | ||
570 | 0x00, /* EEPROM, box 0 */ | ||
571 | 0xf7 | ||
572 | }; | ||
573 | send_bulk_static_data(ep, init_data, sizeof(init_data)); | ||
574 | /* while we're at it, pour on more magic */ | ||
575 | send_bulk_static_data(ep, init_data, sizeof(init_data)); | ||
576 | } | ||
577 | |||
578 | static void snd_usbmidi_emagic_finish_out(snd_usb_midi_out_endpoint_t* ep) | ||
579 | { | ||
580 | static const u8 finish_data[] = { | ||
581 | /* switch to patch mode with last preset */ | ||
582 | 0xf0, | ||
583 | 0x00, 0x20, 0x31, /* Emagic */ | ||
584 | 0x64, /* Unitor8 */ | ||
585 | 0x10, /* patch switch command */ | ||
586 | 0x00, /* command version */ | ||
587 | 0x7f, /* to all boxes */ | ||
588 | 0x40, /* last preset in EEPROM */ | ||
589 | 0xf7 | ||
590 | }; | ||
591 | send_bulk_static_data(ep, finish_data, sizeof(finish_data)); | ||
592 | } | ||
593 | |||
594 | static void snd_usbmidi_emagic_input(snd_usb_midi_in_endpoint_t* ep, | ||
595 | uint8_t* buffer, int buffer_length) | ||
596 | { | ||
597 | /* ignore padding bytes at end of buffer */ | ||
598 | while (buffer_length > 0 && buffer[buffer_length - 1] == 0xff) | ||
599 | --buffer_length; | ||
600 | |||
601 | /* handle F5 at end of last buffer */ | ||
602 | if (ep->seen_f5) | ||
603 | goto switch_port; | ||
604 | |||
605 | while (buffer_length > 0) { | ||
606 | int i; | ||
607 | |||
608 | /* determine size of data until next F5 */ | ||
609 | for (i = 0; i < buffer_length; ++i) | ||
610 | if (buffer[i] == 0xf5) | ||
611 | break; | ||
612 | snd_usbmidi_input_data(ep, ep->current_port, buffer, i); | ||
613 | buffer += i; | ||
614 | buffer_length -= i; | ||
615 | |||
616 | if (buffer_length <= 0) | ||
617 | break; | ||
618 | /* assert(buffer[0] == 0xf5); */ | ||
619 | ep->seen_f5 = 1; | ||
620 | ++buffer; | ||
621 | --buffer_length; | ||
622 | |||
623 | switch_port: | ||
624 | if (buffer_length <= 0) | ||
625 | break; | ||
626 | if (buffer[0] < 0x80) { | ||
627 | ep->current_port = (buffer[0] - 1) & 15; | ||
628 | ++buffer; | ||
629 | --buffer_length; | ||
630 | } | ||
631 | ep->seen_f5 = 0; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | static void snd_usbmidi_emagic_output(snd_usb_midi_out_endpoint_t* ep) | ||
636 | { | ||
637 | int port0 = ep->current_port; | ||
638 | uint8_t* buf = ep->urb->transfer_buffer; | ||
639 | int buf_free = ep->max_transfer; | ||
640 | int length, i; | ||
641 | |||
642 | for (i = 0; i < 0x10; ++i) { | ||
643 | /* round-robin, starting at the last current port */ | ||
644 | int portnum = (port0 + i) & 15; | ||
645 | usbmidi_out_port_t* port = &ep->ports[portnum]; | ||
646 | |||
647 | if (!port->active) | ||
648 | continue; | ||
649 | if (snd_rawmidi_transmit_peek(port->substream, buf, 1) != 1) { | ||
650 | port->active = 0; | ||
651 | continue; | ||
652 | } | ||
653 | |||
654 | if (portnum != ep->current_port) { | ||
655 | if (buf_free < 2) | ||
656 | break; | ||
657 | ep->current_port = portnum; | ||
658 | buf[0] = 0xf5; | ||
659 | buf[1] = (portnum + 1) & 15; | ||
660 | buf += 2; | ||
661 | buf_free -= 2; | ||
662 | } | ||
663 | |||
664 | if (buf_free < 1) | ||
665 | break; | ||
666 | length = snd_rawmidi_transmit(port->substream, buf, buf_free); | ||
667 | if (length > 0) { | ||
668 | buf += length; | ||
669 | buf_free -= length; | ||
670 | if (buf_free < 1) | ||
671 | break; | ||
672 | } | ||
673 | } | ||
674 | ep->urb->transfer_buffer_length = ep->max_transfer - buf_free; | ||
675 | } | ||
676 | |||
677 | static struct usb_protocol_ops snd_usbmidi_emagic_ops = { | ||
678 | .input = snd_usbmidi_emagic_input, | ||
679 | .output = snd_usbmidi_emagic_output, | ||
680 | .init_out_endpoint = snd_usbmidi_emagic_init_out, | ||
681 | .finish_out_endpoint = snd_usbmidi_emagic_finish_out, | ||
682 | }; | ||
683 | |||
684 | |||
685 | static int snd_usbmidi_output_open(snd_rawmidi_substream_t* substream) | ||
686 | { | ||
687 | snd_usb_midi_t* umidi = substream->rmidi->private_data; | ||
688 | usbmidi_out_port_t* port = NULL; | ||
689 | int i, j; | ||
690 | |||
691 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
692 | if (umidi->endpoints[i].out) | ||
693 | for (j = 0; j < 0x10; ++j) | ||
694 | if (umidi->endpoints[i].out->ports[j].substream == substream) { | ||
695 | port = &umidi->endpoints[i].out->ports[j]; | ||
696 | break; | ||
697 | } | ||
698 | if (!port) { | ||
699 | snd_BUG(); | ||
700 | return -ENXIO; | ||
701 | } | ||
702 | substream->runtime->private_data = port; | ||
703 | port->state = STATE_UNKNOWN; | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | static int snd_usbmidi_output_close(snd_rawmidi_substream_t* substream) | ||
708 | { | ||
709 | return 0; | ||
710 | } | ||
711 | |||
712 | static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int up) | ||
713 | { | ||
714 | usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data; | ||
715 | |||
716 | port->active = up; | ||
717 | if (up) { | ||
718 | if (port->ep->umidi->chip->shutdown) { | ||
719 | /* gobble up remaining bytes to prevent wait in | ||
720 | * snd_rawmidi_drain_output */ | ||
721 | while (!snd_rawmidi_transmit_empty(substream)) | ||
722 | snd_rawmidi_transmit_ack(substream, 1); | ||
723 | return; | ||
724 | } | ||
725 | tasklet_hi_schedule(&port->ep->tasklet); | ||
726 | } | ||
727 | } | ||
728 | |||
729 | static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream) | ||
730 | { | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream) | ||
735 | { | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t* substream, int up) | ||
740 | { | ||
741 | snd_usb_midi_t* umidi = substream->rmidi->private_data; | ||
742 | |||
743 | if (up) | ||
744 | set_bit(substream->number, &umidi->input_triggered); | ||
745 | else | ||
746 | clear_bit(substream->number, &umidi->input_triggered); | ||
747 | } | ||
748 | |||
749 | static snd_rawmidi_ops_t snd_usbmidi_output_ops = { | ||
750 | .open = snd_usbmidi_output_open, | ||
751 | .close = snd_usbmidi_output_close, | ||
752 | .trigger = snd_usbmidi_output_trigger, | ||
753 | }; | ||
754 | |||
755 | static snd_rawmidi_ops_t snd_usbmidi_input_ops = { | ||
756 | .open = snd_usbmidi_input_open, | ||
757 | .close = snd_usbmidi_input_close, | ||
758 | .trigger = snd_usbmidi_input_trigger | ||
759 | }; | ||
760 | |||
761 | /* | ||
762 | * Frees an input endpoint. | ||
763 | * May be called when ep hasn't been initialized completely. | ||
764 | */ | ||
765 | static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep) | ||
766 | { | ||
767 | if (ep->urb) { | ||
768 | kfree(ep->urb->transfer_buffer); | ||
769 | usb_free_urb(ep->urb); | ||
770 | } | ||
771 | kfree(ep); | ||
772 | } | ||
773 | |||
774 | /* | ||
775 | * Creates an input endpoint. | ||
776 | */ | ||
777 | static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi, | ||
778 | snd_usb_midi_endpoint_info_t* ep_info, | ||
779 | snd_usb_midi_endpoint_t* rep) | ||
780 | { | ||
781 | snd_usb_midi_in_endpoint_t* ep; | ||
782 | void* buffer; | ||
783 | unsigned int pipe; | ||
784 | int length; | ||
785 | |||
786 | rep->in = NULL; | ||
787 | ep = kcalloc(1, sizeof(*ep), GFP_KERNEL); | ||
788 | if (!ep) | ||
789 | return -ENOMEM; | ||
790 | ep->umidi = umidi; | ||
791 | |||
792 | ep->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
793 | if (!ep->urb) { | ||
794 | snd_usbmidi_in_endpoint_delete(ep); | ||
795 | return -ENOMEM; | ||
796 | } | ||
797 | if (ep_info->in_interval) | ||
798 | pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); | ||
799 | else | ||
800 | pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); | ||
801 | length = usb_maxpacket(umidi->chip->dev, pipe, 0); | ||
802 | buffer = kmalloc(length, GFP_KERNEL); | ||
803 | if (!buffer) { | ||
804 | snd_usbmidi_in_endpoint_delete(ep); | ||
805 | return -ENOMEM; | ||
806 | } | ||
807 | if (ep_info->in_interval) | ||
808 | usb_fill_int_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, | ||
809 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), | ||
810 | ep, ep_info->in_interval); | ||
811 | else | ||
812 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, length, | ||
813 | snd_usb_complete_callback(snd_usbmidi_in_urb_complete), | ||
814 | ep); | ||
815 | |||
816 | rep->in = ep; | ||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | static unsigned int snd_usbmidi_count_bits(unsigned int x) | ||
821 | { | ||
822 | unsigned int bits = 0; | ||
823 | |||
824 | for (; x; x >>= 1) | ||
825 | bits += x & 1; | ||
826 | return bits; | ||
827 | } | ||
828 | |||
829 | /* | ||
830 | * Frees an output endpoint. | ||
831 | * May be called when ep hasn't been initialized completely. | ||
832 | */ | ||
833 | static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep) | ||
834 | { | ||
835 | if (ep->tasklet.func) | ||
836 | tasklet_kill(&ep->tasklet); | ||
837 | if (ep->urb) { | ||
838 | kfree(ep->urb->transfer_buffer); | ||
839 | usb_free_urb(ep->urb); | ||
840 | } | ||
841 | kfree(ep); | ||
842 | } | ||
843 | |||
844 | /* | ||
845 | * Creates an output endpoint, and initializes output ports. | ||
846 | */ | ||
847 | static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi, | ||
848 | snd_usb_midi_endpoint_info_t* ep_info, | ||
849 | snd_usb_midi_endpoint_t* rep) | ||
850 | { | ||
851 | snd_usb_midi_out_endpoint_t* ep; | ||
852 | int i; | ||
853 | unsigned int pipe; | ||
854 | void* buffer; | ||
855 | |||
856 | rep->out = NULL; | ||
857 | ep = kcalloc(1, sizeof(*ep), GFP_KERNEL); | ||
858 | if (!ep) | ||
859 | return -ENOMEM; | ||
860 | ep->umidi = umidi; | ||
861 | |||
862 | ep->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
863 | if (!ep->urb) { | ||
864 | snd_usbmidi_out_endpoint_delete(ep); | ||
865 | return -ENOMEM; | ||
866 | } | ||
867 | /* we never use interrupt output pipes */ | ||
868 | pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); | ||
869 | ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); | ||
870 | buffer = kmalloc(ep->max_transfer, GFP_KERNEL); | ||
871 | if (!buffer) { | ||
872 | snd_usbmidi_out_endpoint_delete(ep); | ||
873 | return -ENOMEM; | ||
874 | } | ||
875 | usb_fill_bulk_urb(ep->urb, umidi->chip->dev, pipe, buffer, | ||
876 | ep->max_transfer, | ||
877 | snd_usb_complete_callback(snd_usbmidi_out_urb_complete), ep); | ||
878 | |||
879 | spin_lock_init(&ep->buffer_lock); | ||
880 | tasklet_init(&ep->tasklet, snd_usbmidi_out_tasklet, (unsigned long)ep); | ||
881 | |||
882 | for (i = 0; i < 0x10; ++i) | ||
883 | if (ep_info->out_cables & (1 << i)) { | ||
884 | ep->ports[i].ep = ep; | ||
885 | ep->ports[i].cable = i << 4; | ||
886 | } | ||
887 | |||
888 | if (umidi->usb_protocol_ops->init_out_endpoint) | ||
889 | umidi->usb_protocol_ops->init_out_endpoint(ep); | ||
890 | |||
891 | rep->out = ep; | ||
892 | return 0; | ||
893 | } | ||
894 | |||
895 | /* | ||
896 | * Frees everything. | ||
897 | */ | ||
898 | static void snd_usbmidi_free(snd_usb_midi_t* umidi) | ||
899 | { | ||
900 | int i; | ||
901 | |||
902 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
903 | snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; | ||
904 | if (ep->out) | ||
905 | snd_usbmidi_out_endpoint_delete(ep->out); | ||
906 | if (ep->in) | ||
907 | snd_usbmidi_in_endpoint_delete(ep->in); | ||
908 | } | ||
909 | kfree(umidi); | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * Unlinks all URBs (must be done before the usb_device is deleted). | ||
914 | */ | ||
915 | void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver) | ||
916 | { | ||
917 | snd_usb_midi_t* umidi; | ||
918 | int i; | ||
919 | |||
920 | umidi = list_entry(p, snd_usb_midi_t, list); | ||
921 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
922 | snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; | ||
923 | if (ep->out && ep->out->urb) { | ||
924 | usb_kill_urb(ep->out->urb); | ||
925 | if (umidi->usb_protocol_ops->finish_out_endpoint) | ||
926 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); | ||
927 | } | ||
928 | if (ep->in && ep->in->urb) | ||
929 | usb_kill_urb(ep->in->urb); | ||
930 | } | ||
931 | } | ||
932 | |||
933 | static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi) | ||
934 | { | ||
935 | snd_usb_midi_t* umidi = rmidi->private_data; | ||
936 | snd_usbmidi_free(umidi); | ||
937 | } | ||
938 | |||
939 | static snd_rawmidi_substream_t* snd_usbmidi_find_substream(snd_usb_midi_t* umidi, | ||
940 | int stream, int number) | ||
941 | { | ||
942 | struct list_head* list; | ||
943 | |||
944 | list_for_each(list, &umidi->rmidi->streams[stream].substreams) { | ||
945 | snd_rawmidi_substream_t* substream = list_entry(list, snd_rawmidi_substream_t, list); | ||
946 | if (substream->number == number) | ||
947 | return substream; | ||
948 | } | ||
949 | return NULL; | ||
950 | } | ||
951 | |||
952 | /* | ||
953 | * This list specifies names for ports that do not fit into the standard | ||
954 | * "(product) MIDI (n)" schema because they aren't external MIDI ports, | ||
955 | * such as internal control or synthesizer ports. | ||
956 | */ | ||
957 | static struct { | ||
958 | __u16 vendor; | ||
959 | __u16 product; | ||
960 | int port; | ||
961 | const char *name_format; | ||
962 | } snd_usbmidi_port_names[] = { | ||
963 | /* Roland UA-100 */ | ||
964 | {0x0582, 0x0000, 2, "%s Control"}, | ||
965 | /* Roland SC-8850 */ | ||
966 | {0x0582, 0x0003, 0, "%s Part A"}, | ||
967 | {0x0582, 0x0003, 1, "%s Part B"}, | ||
968 | {0x0582, 0x0003, 2, "%s Part C"}, | ||
969 | {0x0582, 0x0003, 3, "%s Part D"}, | ||
970 | {0x0582, 0x0003, 4, "%s MIDI 1"}, | ||
971 | {0x0582, 0x0003, 5, "%s MIDI 2"}, | ||
972 | /* Roland U-8 */ | ||
973 | {0x0582, 0x0004, 0, "%s MIDI"}, | ||
974 | {0x0582, 0x0004, 1, "%s Control"}, | ||
975 | /* Roland SC-8820 */ | ||
976 | {0x0582, 0x0007, 0, "%s Part A"}, | ||
977 | {0x0582, 0x0007, 1, "%s Part B"}, | ||
978 | {0x0582, 0x0007, 2, "%s MIDI"}, | ||
979 | /* Roland SK-500 */ | ||
980 | {0x0582, 0x000b, 0, "%s Part A"}, | ||
981 | {0x0582, 0x000b, 1, "%s Part B"}, | ||
982 | {0x0582, 0x000b, 2, "%s MIDI"}, | ||
983 | /* Roland SC-D70 */ | ||
984 | {0x0582, 0x000c, 0, "%s Part A"}, | ||
985 | {0x0582, 0x000c, 1, "%s Part B"}, | ||
986 | {0x0582, 0x000c, 2, "%s MIDI"}, | ||
987 | /* Edirol UM-880 */ | ||
988 | {0x0582, 0x0014, 8, "%s Control"}, | ||
989 | /* Edirol SD-90 */ | ||
990 | {0x0582, 0x0016, 0, "%s Part A"}, | ||
991 | {0x0582, 0x0016, 1, "%s Part B"}, | ||
992 | {0x0582, 0x0016, 2, "%s MIDI 1"}, | ||
993 | {0x0582, 0x0016, 3, "%s MIDI 2"}, | ||
994 | /* Edirol UM-550 */ | ||
995 | {0x0582, 0x0023, 5, "%s Control"}, | ||
996 | /* Edirol SD-20 */ | ||
997 | {0x0582, 0x0027, 0, "%s Part A"}, | ||
998 | {0x0582, 0x0027, 1, "%s Part B"}, | ||
999 | {0x0582, 0x0027, 2, "%s MIDI"}, | ||
1000 | /* Edirol SD-80 */ | ||
1001 | {0x0582, 0x0029, 0, "%s Part A"}, | ||
1002 | {0x0582, 0x0029, 1, "%s Part B"}, | ||
1003 | {0x0582, 0x0029, 2, "%s MIDI 1"}, | ||
1004 | {0x0582, 0x0029, 3, "%s MIDI 2"}, | ||
1005 | /* Edirol UA-700 */ | ||
1006 | {0x0582, 0x002b, 0, "%s MIDI"}, | ||
1007 | {0x0582, 0x002b, 1, "%s Control"}, | ||
1008 | /* Roland VariOS */ | ||
1009 | {0x0582, 0x002f, 0, "%s MIDI"}, | ||
1010 | {0x0582, 0x002f, 1, "%s External MIDI"}, | ||
1011 | {0x0582, 0x002f, 2, "%s Sync"}, | ||
1012 | /* Edirol PCR */ | ||
1013 | {0x0582, 0x0033, 0, "%s MIDI"}, | ||
1014 | {0x0582, 0x0033, 1, "%s 1"}, | ||
1015 | {0x0582, 0x0033, 2, "%s 2"}, | ||
1016 | /* BOSS GS-10 */ | ||
1017 | {0x0582, 0x003b, 0, "%s MIDI"}, | ||
1018 | {0x0582, 0x003b, 1, "%s Control"}, | ||
1019 | /* Edirol UA-1000 */ | ||
1020 | {0x0582, 0x0044, 0, "%s MIDI"}, | ||
1021 | {0x0582, 0x0044, 1, "%s Control"}, | ||
1022 | /* Edirol UR-80 */ | ||
1023 | {0x0582, 0x0048, 0, "%s MIDI"}, | ||
1024 | {0x0582, 0x0048, 1, "%s 1"}, | ||
1025 | {0x0582, 0x0048, 2, "%s 2"}, | ||
1026 | /* Edirol PCR-A */ | ||
1027 | {0x0582, 0x004d, 0, "%s MIDI"}, | ||
1028 | {0x0582, 0x004d, 1, "%s 1"}, | ||
1029 | {0x0582, 0x004d, 2, "%s 2"}, | ||
1030 | /* M-Audio MidiSport 8x8 */ | ||
1031 | {0x0763, 0x1031, 8, "%s Control"}, | ||
1032 | {0x0763, 0x1033, 8, "%s Control"}, | ||
1033 | /* MOTU Fastlane */ | ||
1034 | {0x07fd, 0x0001, 0, "%s MIDI A"}, | ||
1035 | {0x07fd, 0x0001, 1, "%s MIDI B"}, | ||
1036 | /* Emagic Unitor8/AMT8/MT4 */ | ||
1037 | {0x086a, 0x0001, 8, "%s Broadcast"}, | ||
1038 | {0x086a, 0x0002, 8, "%s Broadcast"}, | ||
1039 | {0x086a, 0x0003, 4, "%s Broadcast"}, | ||
1040 | }; | ||
1041 | |||
1042 | static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi, | ||
1043 | int stream, int number, | ||
1044 | snd_rawmidi_substream_t** rsubstream) | ||
1045 | { | ||
1046 | int i; | ||
1047 | __u16 vendor, product; | ||
1048 | const char *name_format; | ||
1049 | |||
1050 | snd_rawmidi_substream_t* substream = snd_usbmidi_find_substream(umidi, stream, number); | ||
1051 | if (!substream) { | ||
1052 | snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number); | ||
1053 | return; | ||
1054 | } | ||
1055 | |||
1056 | /* TODO: read port name from jack descriptor */ | ||
1057 | name_format = "%s MIDI %d"; | ||
1058 | vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor); | ||
1059 | product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct); | ||
1060 | for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) { | ||
1061 | if (snd_usbmidi_port_names[i].vendor == vendor && | ||
1062 | snd_usbmidi_port_names[i].product == product && | ||
1063 | snd_usbmidi_port_names[i].port == number) { | ||
1064 | name_format = snd_usbmidi_port_names[i].name_format; | ||
1065 | break; | ||
1066 | } | ||
1067 | } | ||
1068 | snprintf(substream->name, sizeof(substream->name), | ||
1069 | name_format, umidi->chip->card->shortname, number + 1); | ||
1070 | |||
1071 | *rsubstream = substream; | ||
1072 | } | ||
1073 | |||
1074 | /* | ||
1075 | * Creates the endpoints and their ports. | ||
1076 | */ | ||
1077 | static int snd_usbmidi_create_endpoints(snd_usb_midi_t* umidi, | ||
1078 | snd_usb_midi_endpoint_info_t* endpoints) | ||
1079 | { | ||
1080 | int i, j, err; | ||
1081 | int out_ports = 0, in_ports = 0; | ||
1082 | |||
1083 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
1084 | if (endpoints[i].out_cables) { | ||
1085 | err = snd_usbmidi_out_endpoint_create(umidi, &endpoints[i], | ||
1086 | &umidi->endpoints[i]); | ||
1087 | if (err < 0) | ||
1088 | return err; | ||
1089 | } | ||
1090 | if (endpoints[i].in_cables) { | ||
1091 | err = snd_usbmidi_in_endpoint_create(umidi, &endpoints[i], | ||
1092 | &umidi->endpoints[i]); | ||
1093 | if (err < 0) | ||
1094 | return err; | ||
1095 | } | ||
1096 | |||
1097 | for (j = 0; j < 0x10; ++j) { | ||
1098 | if (endpoints[i].out_cables & (1 << j)) { | ||
1099 | snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, out_ports, | ||
1100 | &umidi->endpoints[i].out->ports[j].substream); | ||
1101 | ++out_ports; | ||
1102 | } | ||
1103 | if (endpoints[i].in_cables & (1 << j)) { | ||
1104 | snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, in_ports, | ||
1105 | &umidi->endpoints[i].in->ports[j].substream); | ||
1106 | ++in_ports; | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | snd_printdd(KERN_INFO "created %d output and %d input ports\n", | ||
1111 | out_ports, in_ports); | ||
1112 | return 0; | ||
1113 | } | ||
1114 | |||
1115 | /* | ||
1116 | * Returns MIDIStreaming device capabilities. | ||
1117 | */ | ||
1118 | static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi, | ||
1119 | snd_usb_midi_endpoint_info_t* endpoints) | ||
1120 | { | ||
1121 | struct usb_interface* intf; | ||
1122 | struct usb_host_interface *hostif; | ||
1123 | struct usb_interface_descriptor* intfd; | ||
1124 | struct usb_ms_header_descriptor* ms_header; | ||
1125 | struct usb_host_endpoint *hostep; | ||
1126 | struct usb_endpoint_descriptor* ep; | ||
1127 | struct usb_ms_endpoint_descriptor* ms_ep; | ||
1128 | int i, epidx; | ||
1129 | |||
1130 | intf = umidi->iface; | ||
1131 | if (!intf) | ||
1132 | return -ENXIO; | ||
1133 | hostif = &intf->altsetting[0]; | ||
1134 | intfd = get_iface_desc(hostif); | ||
1135 | ms_header = (struct usb_ms_header_descriptor*)hostif->extra; | ||
1136 | if (hostif->extralen >= 7 && | ||
1137 | ms_header->bLength >= 7 && | ||
1138 | ms_header->bDescriptorType == USB_DT_CS_INTERFACE && | ||
1139 | ms_header->bDescriptorSubtype == HEADER) | ||
1140 | snd_printdd(KERN_INFO "MIDIStreaming version %02x.%02x\n", | ||
1141 | ms_header->bcdMSC[1], ms_header->bcdMSC[0]); | ||
1142 | else | ||
1143 | snd_printk(KERN_WARNING "MIDIStreaming interface descriptor not found\n"); | ||
1144 | |||
1145 | epidx = 0; | ||
1146 | for (i = 0; i < intfd->bNumEndpoints; ++i) { | ||
1147 | hostep = &hostif->endpoint[i]; | ||
1148 | ep = get_ep_desc(hostep); | ||
1149 | if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK && | ||
1150 | (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) | ||
1151 | continue; | ||
1152 | ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra; | ||
1153 | if (hostep->extralen < 4 || | ||
1154 | ms_ep->bLength < 4 || | ||
1155 | ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || | ||
1156 | ms_ep->bDescriptorSubtype != MS_GENERAL) | ||
1157 | continue; | ||
1158 | if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | ||
1159 | if (endpoints[epidx].out_ep) { | ||
1160 | if (++epidx >= MIDI_MAX_ENDPOINTS) { | ||
1161 | snd_printk(KERN_WARNING "too many endpoints\n"); | ||
1162 | break; | ||
1163 | } | ||
1164 | } | ||
1165 | endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1166 | if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
1167 | endpoints[epidx].out_interval = ep->bInterval; | ||
1168 | endpoints[epidx].out_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; | ||
1169 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", | ||
1170 | ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); | ||
1171 | } else { | ||
1172 | if (endpoints[epidx].in_ep) { | ||
1173 | if (++epidx >= MIDI_MAX_ENDPOINTS) { | ||
1174 | snd_printk(KERN_WARNING "too many endpoints\n"); | ||
1175 | break; | ||
1176 | } | ||
1177 | } | ||
1178 | endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1179 | if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
1180 | endpoints[epidx].in_interval = ep->bInterval; | ||
1181 | endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; | ||
1182 | snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", | ||
1183 | ep->bEndpointAddress, ms_ep->bNumEmbMIDIJack); | ||
1184 | } | ||
1185 | } | ||
1186 | return 0; | ||
1187 | } | ||
1188 | |||
1189 | /* | ||
1190 | * On Roland devices, use the second alternate setting to be able to use | ||
1191 | * the interrupt input endpoint. | ||
1192 | */ | ||
1193 | static void snd_usbmidi_switch_roland_altsetting(snd_usb_midi_t* umidi) | ||
1194 | { | ||
1195 | struct usb_interface* intf; | ||
1196 | struct usb_host_interface *hostif; | ||
1197 | struct usb_interface_descriptor* intfd; | ||
1198 | |||
1199 | intf = umidi->iface; | ||
1200 | if (!intf || intf->num_altsetting != 2) | ||
1201 | return; | ||
1202 | |||
1203 | hostif = &intf->altsetting[1]; | ||
1204 | intfd = get_iface_desc(hostif); | ||
1205 | if (intfd->bNumEndpoints != 2 || | ||
1206 | (get_endpoint(hostif, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK || | ||
1207 | (get_endpoint(hostif, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) | ||
1208 | return; | ||
1209 | |||
1210 | snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", | ||
1211 | intfd->bAlternateSetting); | ||
1212 | usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, | ||
1213 | intfd->bAlternateSetting); | ||
1214 | } | ||
1215 | |||
1216 | /* | ||
1217 | * Try to find any usable endpoints in the interface. | ||
1218 | */ | ||
1219 | static int snd_usbmidi_detect_endpoints(snd_usb_midi_t* umidi, | ||
1220 | snd_usb_midi_endpoint_info_t* endpoint, | ||
1221 | int max_endpoints) | ||
1222 | { | ||
1223 | struct usb_interface* intf; | ||
1224 | struct usb_host_interface *hostif; | ||
1225 | struct usb_interface_descriptor* intfd; | ||
1226 | struct usb_endpoint_descriptor* epd; | ||
1227 | int i, out_eps = 0, in_eps = 0; | ||
1228 | |||
1229 | if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) == 0x0582) | ||
1230 | snd_usbmidi_switch_roland_altsetting(umidi); | ||
1231 | |||
1232 | intf = umidi->iface; | ||
1233 | if (!intf || intf->num_altsetting < 1) | ||
1234 | return -ENOENT; | ||
1235 | hostif = intf->cur_altsetting; | ||
1236 | intfd = get_iface_desc(hostif); | ||
1237 | |||
1238 | for (i = 0; i < intfd->bNumEndpoints; ++i) { | ||
1239 | epd = get_endpoint(hostif, i); | ||
1240 | if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK && | ||
1241 | (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) | ||
1242 | continue; | ||
1243 | if (out_eps < max_endpoints && | ||
1244 | (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | ||
1245 | endpoint[out_eps].out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1246 | if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
1247 | endpoint[out_eps].out_interval = epd->bInterval; | ||
1248 | ++out_eps; | ||
1249 | } | ||
1250 | if (in_eps < max_endpoints && | ||
1251 | (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { | ||
1252 | endpoint[in_eps].in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1253 | if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
1254 | endpoint[in_eps].in_interval = epd->bInterval; | ||
1255 | ++in_eps; | ||
1256 | } | ||
1257 | } | ||
1258 | return (out_eps || in_eps) ? 0 : -ENOENT; | ||
1259 | } | ||
1260 | |||
1261 | /* | ||
1262 | * Detects the endpoints for one-port-per-endpoint protocols. | ||
1263 | */ | ||
1264 | static int snd_usbmidi_detect_per_port_endpoints(snd_usb_midi_t* umidi, | ||
1265 | snd_usb_midi_endpoint_info_t* endpoints) | ||
1266 | { | ||
1267 | int err, i; | ||
1268 | |||
1269 | err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS); | ||
1270 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
1271 | if (endpoints[i].out_ep) | ||
1272 | endpoints[i].out_cables = 0x0001; | ||
1273 | if (endpoints[i].in_ep) | ||
1274 | endpoints[i].in_cables = 0x0001; | ||
1275 | } | ||
1276 | return err; | ||
1277 | } | ||
1278 | |||
1279 | /* | ||
1280 | * Detects the endpoints and ports of Yamaha devices. | ||
1281 | */ | ||
1282 | static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi, | ||
1283 | snd_usb_midi_endpoint_info_t* endpoint) | ||
1284 | { | ||
1285 | struct usb_interface* intf; | ||
1286 | struct usb_host_interface *hostif; | ||
1287 | struct usb_interface_descriptor* intfd; | ||
1288 | uint8_t* cs_desc; | ||
1289 | |||
1290 | intf = umidi->iface; | ||
1291 | if (!intf) | ||
1292 | return -ENOENT; | ||
1293 | hostif = intf->altsetting; | ||
1294 | intfd = get_iface_desc(hostif); | ||
1295 | if (intfd->bNumEndpoints < 1) | ||
1296 | return -ENOENT; | ||
1297 | |||
1298 | /* | ||
1299 | * For each port there is one MIDI_IN/OUT_JACK descriptor, not | ||
1300 | * necessarily with any useful contents. So simply count 'em. | ||
1301 | */ | ||
1302 | for (cs_desc = hostif->extra; | ||
1303 | cs_desc < hostif->extra + hostif->extralen && cs_desc[0] >= 2; | ||
1304 | cs_desc += cs_desc[0]) { | ||
1305 | if (cs_desc[1] == CS_AUDIO_INTERFACE) { | ||
1306 | if (cs_desc[2] == MIDI_IN_JACK) | ||
1307 | endpoint->in_cables = (endpoint->in_cables << 1) | 1; | ||
1308 | else if (cs_desc[2] == MIDI_OUT_JACK) | ||
1309 | endpoint->out_cables = (endpoint->out_cables << 1) | 1; | ||
1310 | } | ||
1311 | } | ||
1312 | if (!endpoint->in_cables && !endpoint->out_cables) | ||
1313 | return -ENOENT; | ||
1314 | |||
1315 | return snd_usbmidi_detect_endpoints(umidi, endpoint, 1); | ||
1316 | } | ||
1317 | |||
1318 | /* | ||
1319 | * Creates the endpoints and their ports for Midiman devices. | ||
1320 | */ | ||
1321 | static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi, | ||
1322 | snd_usb_midi_endpoint_info_t* endpoint) | ||
1323 | { | ||
1324 | snd_usb_midi_endpoint_info_t ep_info; | ||
1325 | struct usb_interface* intf; | ||
1326 | struct usb_host_interface *hostif; | ||
1327 | struct usb_interface_descriptor* intfd; | ||
1328 | struct usb_endpoint_descriptor* epd; | ||
1329 | int cable, err; | ||
1330 | |||
1331 | intf = umidi->iface; | ||
1332 | if (!intf) | ||
1333 | return -ENOENT; | ||
1334 | hostif = intf->altsetting; | ||
1335 | intfd = get_iface_desc(hostif); | ||
1336 | /* | ||
1337 | * The various MidiSport devices have more or less random endpoint | ||
1338 | * numbers, so we have to identify the endpoints by their index in | ||
1339 | * the descriptor array, like the driver for that other OS does. | ||
1340 | * | ||
1341 | * There is one interrupt input endpoint for all input ports, one | ||
1342 | * bulk output endpoint for even-numbered ports, and one for odd- | ||
1343 | * numbered ports. Both bulk output endpoints have corresponding | ||
1344 | * input bulk endpoints (at indices 1 and 3) which aren't used. | ||
1345 | */ | ||
1346 | if (intfd->bNumEndpoints < (endpoint->out_cables > 0x0001 ? 5 : 3)) { | ||
1347 | snd_printdd(KERN_ERR "not enough endpoints\n"); | ||
1348 | return -ENOENT; | ||
1349 | } | ||
1350 | |||
1351 | epd = get_endpoint(hostif, 0); | ||
1352 | if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN || | ||
1353 | (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { | ||
1354 | snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n"); | ||
1355 | return -ENXIO; | ||
1356 | } | ||
1357 | epd = get_endpoint(hostif, 2); | ||
1358 | if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || | ||
1359 | (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { | ||
1360 | snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n"); | ||
1361 | return -ENXIO; | ||
1362 | } | ||
1363 | if (endpoint->out_cables > 0x0001) { | ||
1364 | epd = get_endpoint(hostif, 4); | ||
1365 | if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || | ||
1366 | (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { | ||
1367 | snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n"); | ||
1368 | return -ENXIO; | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1373 | ep_info.out_cables = endpoint->out_cables & 0x5555; | ||
1374 | err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); | ||
1375 | if (err < 0) | ||
1376 | return err; | ||
1377 | |||
1378 | ep_info.in_ep = get_endpoint(hostif, 0)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1379 | ep_info.in_interval = get_endpoint(hostif, 0)->bInterval; | ||
1380 | ep_info.in_cables = endpoint->in_cables; | ||
1381 | err = snd_usbmidi_in_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); | ||
1382 | if (err < 0) | ||
1383 | return err; | ||
1384 | |||
1385 | if (endpoint->out_cables > 0x0001) { | ||
1386 | ep_info.out_ep = get_endpoint(hostif, 4)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
1387 | ep_info.out_cables = endpoint->out_cables & 0xaaaa; | ||
1388 | err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[1]); | ||
1389 | if (err < 0) | ||
1390 | return err; | ||
1391 | } | ||
1392 | |||
1393 | for (cable = 0; cable < 0x10; ++cable) { | ||
1394 | if (endpoint->out_cables & (1 << cable)) | ||
1395 | snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_OUTPUT, cable, | ||
1396 | &umidi->endpoints[cable & 1].out->ports[cable].substream); | ||
1397 | if (endpoint->in_cables & (1 << cable)) | ||
1398 | snd_usbmidi_init_substream(umidi, SNDRV_RAWMIDI_STREAM_INPUT, cable, | ||
1399 | &umidi->endpoints[0].in->ports[cable].substream); | ||
1400 | } | ||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1404 | static int snd_usbmidi_create_rawmidi(snd_usb_midi_t* umidi, | ||
1405 | int out_ports, int in_ports) | ||
1406 | { | ||
1407 | snd_rawmidi_t* rmidi; | ||
1408 | int err; | ||
1409 | |||
1410 | err = snd_rawmidi_new(umidi->chip->card, "USB MIDI", | ||
1411 | umidi->chip->next_midi_device++, | ||
1412 | out_ports, in_ports, &rmidi); | ||
1413 | if (err < 0) | ||
1414 | return err; | ||
1415 | strcpy(rmidi->name, umidi->chip->card->shortname); | ||
1416 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | | ||
1417 | SNDRV_RAWMIDI_INFO_INPUT | | ||
1418 | SNDRV_RAWMIDI_INFO_DUPLEX; | ||
1419 | rmidi->private_data = umidi; | ||
1420 | rmidi->private_free = snd_usbmidi_rawmidi_free; | ||
1421 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_usbmidi_output_ops); | ||
1422 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_usbmidi_input_ops); | ||
1423 | |||
1424 | umidi->rmidi = rmidi; | ||
1425 | return 0; | ||
1426 | } | ||
1427 | |||
1428 | /* | ||
1429 | * Temporarily stop input. | ||
1430 | */ | ||
1431 | void snd_usbmidi_input_stop(struct list_head* p) | ||
1432 | { | ||
1433 | snd_usb_midi_t* umidi; | ||
1434 | int i; | ||
1435 | |||
1436 | umidi = list_entry(p, snd_usb_midi_t, list); | ||
1437 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
1438 | snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i]; | ||
1439 | if (ep->in) | ||
1440 | usb_kill_urb(ep->in->urb); | ||
1441 | } | ||
1442 | } | ||
1443 | |||
1444 | static void snd_usbmidi_input_start_ep(snd_usb_midi_in_endpoint_t* ep) | ||
1445 | { | ||
1446 | if (ep) { | ||
1447 | struct urb* urb = ep->urb; | ||
1448 | urb->dev = ep->umidi->chip->dev; | ||
1449 | snd_usbmidi_submit_urb(urb, GFP_KERNEL); | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | /* | ||
1454 | * Resume input after a call to snd_usbmidi_input_stop(). | ||
1455 | */ | ||
1456 | void snd_usbmidi_input_start(struct list_head* p) | ||
1457 | { | ||
1458 | snd_usb_midi_t* umidi; | ||
1459 | int i; | ||
1460 | |||
1461 | umidi = list_entry(p, snd_usb_midi_t, list); | ||
1462 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
1463 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | ||
1464 | } | ||
1465 | |||
1466 | /* | ||
1467 | * Creates and registers everything needed for a MIDI streaming interface. | ||
1468 | */ | ||
1469 | int snd_usb_create_midi_interface(snd_usb_audio_t* chip, | ||
1470 | struct usb_interface* iface, | ||
1471 | const snd_usb_audio_quirk_t* quirk) | ||
1472 | { | ||
1473 | snd_usb_midi_t* umidi; | ||
1474 | snd_usb_midi_endpoint_info_t endpoints[MIDI_MAX_ENDPOINTS]; | ||
1475 | int out_ports, in_ports; | ||
1476 | int i, err; | ||
1477 | |||
1478 | umidi = kcalloc(1, sizeof(*umidi), GFP_KERNEL); | ||
1479 | if (!umidi) | ||
1480 | return -ENOMEM; | ||
1481 | umidi->chip = chip; | ||
1482 | umidi->iface = iface; | ||
1483 | umidi->quirk = quirk; | ||
1484 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | ||
1485 | |||
1486 | /* detect the endpoint(s) to use */ | ||
1487 | memset(endpoints, 0, sizeof(endpoints)); | ||
1488 | if (!quirk) { | ||
1489 | err = snd_usbmidi_get_ms_info(umidi, endpoints); | ||
1490 | } else { | ||
1491 | switch (quirk->type) { | ||
1492 | case QUIRK_MIDI_FIXED_ENDPOINT: | ||
1493 | memcpy(&endpoints[0], quirk->data, | ||
1494 | sizeof(snd_usb_midi_endpoint_info_t)); | ||
1495 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); | ||
1496 | break; | ||
1497 | case QUIRK_MIDI_YAMAHA: | ||
1498 | err = snd_usbmidi_detect_yamaha(umidi, &endpoints[0]); | ||
1499 | break; | ||
1500 | case QUIRK_MIDI_MIDIMAN: | ||
1501 | umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops; | ||
1502 | memcpy(&endpoints[0], quirk->data, | ||
1503 | sizeof(snd_usb_midi_endpoint_info_t)); | ||
1504 | err = 0; | ||
1505 | break; | ||
1506 | case QUIRK_MIDI_NOVATION: | ||
1507 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; | ||
1508 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
1509 | break; | ||
1510 | case QUIRK_MIDI_MOTU: | ||
1511 | umidi->usb_protocol_ops = &snd_usbmidi_motu_ops; | ||
1512 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
1513 | break; | ||
1514 | case QUIRK_MIDI_EMAGIC: | ||
1515 | umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops; | ||
1516 | memcpy(&endpoints[0], quirk->data, | ||
1517 | sizeof(snd_usb_midi_endpoint_info_t)); | ||
1518 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); | ||
1519 | break; | ||
1520 | default: | ||
1521 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | ||
1522 | err = -ENXIO; | ||
1523 | break; | ||
1524 | } | ||
1525 | } | ||
1526 | if (err < 0) { | ||
1527 | kfree(umidi); | ||
1528 | return err; | ||
1529 | } | ||
1530 | |||
1531 | /* create rawmidi device */ | ||
1532 | out_ports = 0; | ||
1533 | in_ports = 0; | ||
1534 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | ||
1535 | out_ports += snd_usbmidi_count_bits(endpoints[i].out_cables); | ||
1536 | in_ports += snd_usbmidi_count_bits(endpoints[i].in_cables); | ||
1537 | } | ||
1538 | err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); | ||
1539 | if (err < 0) { | ||
1540 | kfree(umidi); | ||
1541 | return err; | ||
1542 | } | ||
1543 | |||
1544 | /* create endpoint/port structures */ | ||
1545 | if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN) | ||
1546 | err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]); | ||
1547 | else | ||
1548 | err = snd_usbmidi_create_endpoints(umidi, endpoints); | ||
1549 | if (err < 0) { | ||
1550 | snd_usbmidi_free(umidi); | ||
1551 | return err; | ||
1552 | } | ||
1553 | |||
1554 | list_add(&umidi->list, &umidi->chip->midi_list); | ||
1555 | |||
1556 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
1557 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | ||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | EXPORT_SYMBOL(snd_usb_create_midi_interface); | ||
1562 | EXPORT_SYMBOL(snd_usbmidi_input_stop); | ||
1563 | EXPORT_SYMBOL(snd_usbmidi_input_start); | ||
1564 | EXPORT_SYMBOL(snd_usbmidi_disconnect); | ||