1 /* $OpenBSD: umidi.c,v 1.11 2004/11/20 01:29:37 jsg Exp $ */
2 /* $NetBSD: umidi.c,v 1.16 2002/07/11 21:14:32 augustss Exp $ */
3 /*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@netbsd.org).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/device.h>
44 #include <sys/ioctl.h>
45 #include <sys/conf.h>
46 #include <sys/file.h>
47 #include <sys/select.h>
48 #include <sys/proc.h>
49 #include <sys/vnode.h>
50 #include <sys/poll.h>
51 #include <sys/lock.h>
52
53 #include <dev/usb/usb.h>
54 #include <dev/usb/usbdi.h>
55 #include <dev/usb/usbdi_util.h>
56
57 #include <dev/usb/usbdevs.h>
58 #include <dev/usb/uaudioreg.h>
59 #include <dev/usb/umidireg.h>
60 #include <dev/usb/umidivar.h>
61 #include <dev/usb/umidi_quirks.h>
62
63 #include <dev/midi_if.h>
64
65 #ifdef UMIDI_DEBUG
66 #define DPRINTF(x) if (umididebug) printf x
67 #define DPRINTFN(n,x) if (umididebug >= (n)) printf x
68 int umididebug = 0;
69 #else
70 #define DPRINTF(x)
71 #define DPRINTFN(n,x)
72 #endif
73
74
75 static int umidi_open(void *, int,
76 void (*)(void *, int), void (*)(void *), void *);
77 static void umidi_close(void *);
78 static int umidi_output(void *, int);
79 static void umidi_getinfo(void *, struct midi_info *);
80
81 static usbd_status alloc_pipe(struct umidi_endpoint *);
82 static void free_pipe(struct umidi_endpoint *);
83
84 static usbd_status alloc_all_endpoints(struct umidi_softc *);
85 static void free_all_endpoints(struct umidi_softc *);
86
87 static usbd_status alloc_all_jacks(struct umidi_softc *);
88 static void free_all_jacks(struct umidi_softc *);
89 static usbd_status bind_jacks_to_mididev(struct umidi_softc *,
90 struct umidi_jack *,
91 struct umidi_jack *,
92 struct umidi_mididev *);
93 static void unbind_jacks_from_mididev(struct umidi_mididev *);
94 static void unbind_all_jacks(struct umidi_softc *);
95 static usbd_status assign_all_jacks_automatically(struct umidi_softc *);
96 static usbd_status open_out_jack(struct umidi_jack *, void *,
97 void (*)(void *));
98 static usbd_status open_in_jack(struct umidi_jack *, void *,
99 void (*)(void *, int));
100 static void close_out_jack(struct umidi_jack *);
101 static void close_in_jack(struct umidi_jack *);
102
103 static usbd_status attach_mididev(struct umidi_softc *,
104 struct umidi_mididev *);
105 static usbd_status detach_mididev(struct umidi_mididev *, int);
106 static usbd_status deactivate_mididev(struct umidi_mididev *);
107 static usbd_status alloc_all_mididevs(struct umidi_softc *, int);
108 static void free_all_mididevs(struct umidi_softc *);
109 static usbd_status attach_all_mididevs(struct umidi_softc *);
110 static usbd_status detach_all_mididevs(struct umidi_softc *, int);
111 static usbd_status deactivate_all_mididevs(struct umidi_softc *);
112
113 #ifdef UMIDI_DEBUG
114 static void dump_sc(struct umidi_softc *);
115 static void dump_ep(struct umidi_endpoint *);
116 static void dump_jack(struct umidi_jack *);
117 #endif
118
119 static void init_packet(struct umidi_packet *);
120
121 static usbd_status start_input_transfer(struct umidi_endpoint *);
122 static usbd_status start_output_transfer(struct umidi_endpoint *);
123 static int out_jack_output(struct umidi_jack *, int);
124 static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
125 static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
126 static int out_build_packet(int, struct umidi_packet *, uByte);
127
128
129 struct midi_hw_if umidi_hw_if = {
130 umidi_open,
131 umidi_close,
132 umidi_output,
133 umidi_getinfo,
134 0, /* ioctl */
135 };
136
137 USB_DECLARE_DRIVER(umidi);
138
USB_MATCH(umidi)139 USB_MATCH(umidi)
140 {
141 USB_MATCH_START(umidi, uaa);
142 usb_interface_descriptor_t *id;
143
144 DPRINTFN(1,("umidi_match\n"));
145
146 if (uaa->iface == NULL)
147 return UMATCH_NONE;
148
149 if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno))
150 return UMATCH_IFACECLASS_IFACESUBCLASS;
151
152 id = usbd_get_interface_descriptor(uaa->iface);
153 if (id!=NULL &&
154 id->bInterfaceClass==UICLASS_AUDIO &&
155 id->bInterfaceSubClass==UISUBCLASS_MIDISTREAM)
156 return UMATCH_IFACECLASS_IFACESUBCLASS;
157
158 return UMATCH_NONE;
159 }
160
USB_ATTACH(umidi)161 USB_ATTACH(umidi)
162 {
163 usbd_status err;
164 USB_ATTACH_START(umidi, sc, uaa);
165 char devinfo[1024];
166 int i;
167
168 DPRINTFN(1,("umidi_attach\n"));
169
170 usbd_devinfo(uaa->device, 0, devinfo, sizeof devinfo);
171 printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
172
173 sc->sc_iface = uaa->iface;
174 sc->sc_udev = uaa->device;
175
176 sc->sc_quirk =
177 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno);
178 printf("%s: ", USBDEVNAME(sc->sc_dev));
179 umidi_print_quirk(sc->sc_quirk);
180
181
182 err = alloc_all_endpoints(sc);
183 if (err!=USBD_NORMAL_COMPLETION) {
184 goto error;
185 }
186 err = alloc_all_jacks(sc);
187 if (err!=USBD_NORMAL_COMPLETION) {
188 free_all_endpoints(sc);
189 goto error;
190 }
191 printf("%s: out=%d, in=%d\n",
192 USBDEVNAME(sc->sc_dev),
193 sc->sc_out_num_jacks, sc->sc_in_num_jacks);
194
195 err = assign_all_jacks_automatically(sc);
196 if (err!=USBD_NORMAL_COMPLETION) {
197 unbind_all_jacks(sc);
198 free_all_jacks(sc);
199 free_all_endpoints(sc);
200 goto error;
201 }
202 err = attach_all_mididevs(sc);
203 if (err!=USBD_NORMAL_COMPLETION) {
204 free_all_jacks(sc);
205 free_all_endpoints(sc);
206 }
207
208 #ifdef UMIDI_DEBUG
209 dump_sc(sc);
210 #endif
211
212 for (i = 0; i < sc->sc_in_num_endpoints; i++) {
213 (void)start_input_transfer(&sc->sc_in_ep[i]);
214 }
215
216 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH,
217 sc->sc_udev, USBDEV(sc->sc_dev));
218
219 USB_ATTACH_SUCCESS_RETURN;
220 error:
221 printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev));
222 sc->sc_dying = 1;
223 USB_ATTACH_ERROR_RETURN;
224 }
225
226 int
umidi_activate(device_ptr_t self,enum devact act)227 umidi_activate(device_ptr_t self, enum devact act)
228 {
229 struct umidi_softc *sc = (struct umidi_softc *)self;
230
231 switch (act) {
232 case DVACT_ACTIVATE:
233 DPRINTFN(1,("umidi_activate (activate)\n"));
234
235 return EOPNOTSUPP;
236 break;
237 case DVACT_DEACTIVATE:
238 DPRINTFN(1,("umidi_activate (deactivate)\n"));
239 sc->sc_dying = 1;
240 deactivate_all_mididevs(sc);
241 break;
242 }
243 return 0;
244 }
245
USB_DETACH(umidi)246 USB_DETACH(umidi)
247 {
248 USB_DETACH_START(umidi, sc);
249
250 DPRINTFN(1,("umidi_detach\n"));
251
252 sc->sc_dying = 1;
253 detach_all_mididevs(sc, flags);
254 free_all_mididevs(sc);
255 free_all_jacks(sc);
256 free_all_endpoints(sc);
257
258 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
259 USBDEV(sc->sc_dev));
260
261 return 0;
262 }
263
264
265 /*
266 * midi_if stuffs
267 */
268 int
umidi_open(void * addr,int flags,void (* iintr)(void *,int),void (* ointr)(void *),void * arg)269 umidi_open(void *addr,
270 int flags,
271 void (*iintr)(void *, int),
272 void (*ointr)(void *),
273 void *arg)
274 {
275 struct umidi_mididev *mididev = addr;
276 struct umidi_softc *sc = mididev->sc;
277
278 DPRINTF(("umidi_open: sc=%p\n", sc));
279
280 if (!sc)
281 return ENXIO;
282 if (mididev->opened)
283 return EBUSY;
284 if (sc->sc_dying)
285 return EIO;
286
287 mididev->opened = 1;
288 mididev->flags = flags;
289 if ((mididev->flags & FWRITE) && mididev->out_jack)
290 open_out_jack(mididev->out_jack, arg, ointr);
291 if ((mididev->flags & FREAD) && mididev->in_jack) {
292 open_in_jack(mididev->in_jack, arg, iintr);
293 }
294
295 return 0;
296 }
297
298 void
umidi_close(void * addr)299 umidi_close(void *addr)
300 {
301 int s;
302 struct umidi_mididev *mididev = addr;
303
304 s = splusb();
305 if ((mididev->flags & FWRITE) && mididev->out_jack)
306 close_out_jack(mididev->out_jack);
307 if ((mididev->flags & FREAD) && mididev->in_jack)
308 close_in_jack(mididev->in_jack);
309 mididev->opened = 0;
310 splx(s);
311 }
312
313 int
umidi_output(void * addr,int d)314 umidi_output(void *addr, int d)
315 {
316 struct umidi_mididev *mididev = addr;
317
318 if (!mididev->out_jack || !mididev->opened)
319 return EIO;
320
321 return out_jack_output(mididev->out_jack, d);
322 }
323
324 void
umidi_getinfo(void * addr,struct midi_info * mi)325 umidi_getinfo(void *addr, struct midi_info *mi)
326 {
327 struct umidi_mididev *mididev = addr;
328
329 mi->name = "USB MIDI I/F"; /* XXX: model name */
330 mi->props = MIDI_PROP_OUT_INTR;
331 if (mididev->in_jack)
332 mi->props |= MIDI_PROP_CAN_INPUT;
333 }
334
335
336 /*
337 * each endpoint stuffs
338 */
339
340 /* alloc/free pipe */
341 static usbd_status
alloc_pipe(struct umidi_endpoint * ep)342 alloc_pipe(struct umidi_endpoint *ep)
343 {
344 struct umidi_softc *sc = ep->sc;
345 usbd_status err;
346
347 DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep));
348 TAILQ_INIT(&ep->queue_head);
349 ep->xfer = usbd_alloc_xfer(sc->sc_udev);
350 if (ep->xfer == NULL) {
351 return USBD_NOMEM;
352 }
353 ep->buffer = usbd_alloc_buffer(ep->xfer, ep->packetsize);
354 if (ep->buffer == NULL) {
355 usbd_free_xfer(ep->xfer);
356 return USBD_NOMEM;
357 }
358 err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe);
359 if (err != USBD_NORMAL_COMPLETION) {
360 usbd_free_xfer(ep->xfer);
361 return err;
362 }
363 return USBD_NORMAL_COMPLETION;
364 }
365
366 static void
free_pipe(struct umidi_endpoint * ep)367 free_pipe(struct umidi_endpoint *ep)
368 {
369 DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep));
370 usbd_abort_pipe(ep->pipe);
371 usbd_close_pipe(ep->pipe);
372 usbd_free_xfer(ep->xfer);
373 }
374
375
376 /* alloc/free the array of endpoint structures */
377
378 static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *);
379 static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *);
380 static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *);
381
382 static usbd_status
alloc_all_endpoints(struct umidi_softc * sc)383 alloc_all_endpoints(struct umidi_softc *sc)
384 {
385 usbd_status err;
386 struct umidi_endpoint *ep;
387 int i;
388
389 if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) {
390 err = alloc_all_endpoints_fixed_ep(sc);
391 } else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) {
392 err = alloc_all_endpoints_yamaha(sc);
393 } else {
394 err = alloc_all_endpoints_genuine(sc);
395 }
396 if (err!=USBD_NORMAL_COMPLETION)
397 return err;
398
399 ep = sc->sc_endpoints;
400 for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) {
401 err = alloc_pipe(ep);
402 if (err!=USBD_NORMAL_COMPLETION) {
403 while(ep != sc->sc_endpoints) {
404 ep--;
405 free_pipe(ep);
406 }
407 free(sc->sc_endpoints, M_USBDEV);
408 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
409 break;
410 }
411 ep++;
412 }
413 return err;
414 }
415
416 static void
free_all_endpoints(struct umidi_softc * sc)417 free_all_endpoints(struct umidi_softc *sc)
418 {
419 int i;
420 for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++)
421 free_pipe(&sc->sc_endpoints[i]);
422 if (sc->sc_endpoints != NULL)
423 free(sc->sc_endpoints, M_USBDEV);
424 sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
425 }
426
427 static usbd_status
alloc_all_endpoints_fixed_ep(struct umidi_softc * sc)428 alloc_all_endpoints_fixed_ep(struct umidi_softc *sc)
429 {
430 usbd_status err;
431 struct umq_fixed_ep_desc *fp;
432 struct umidi_endpoint *ep;
433 usb_endpoint_descriptor_t *epd;
434 int i;
435
436 fp = umidi_get_quirk_data_from_type(sc->sc_quirk,
437 UMQ_TYPE_FIXED_EP);
438 sc->sc_out_num_jacks = 0;
439 sc->sc_in_num_jacks = 0;
440 sc->sc_out_num_endpoints = fp->num_out_ep;
441 sc->sc_in_num_endpoints = fp->num_in_ep;
442 sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)*
443 (sc->sc_out_num_endpoints+
444 sc->sc_in_num_endpoints),
445 M_USBDEV, M_WAITOK);
446 if (!sc->sc_endpoints) {
447 return USBD_NOMEM;
448 }
449 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
450 sc->sc_in_ep =
451 sc->sc_in_num_endpoints ?
452 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
453
454 ep = &sc->sc_out_ep[0];
455 for (i=0; i<sc->sc_out_num_endpoints; i++) {
456 epd = usbd_interface2endpoint_descriptor(
457 sc->sc_iface,
458 fp->out_ep[i].ep);
459 if (!epd) {
460 DPRINTF(("%s: cannot get endpoint descriptor(out:%d)\n",
461 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep));
462 err = USBD_INVAL;
463 goto error;
464 }
465 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
466 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) {
467 printf("%s: illegal endpoint(out:%d)\n",
468 USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
469 err = USBD_INVAL;
470 goto error;
471 }
472 ep->sc = sc;
473 ep->packetsize = UGETW(epd->wMaxPacketSize);
474 ep->addr = epd->bEndpointAddress;
475 ep->num_jacks = fp->out_ep[i].num_jacks;
476 sc->sc_out_num_jacks += fp->out_ep[i].num_jacks;
477 ep->num_open = 0;
478 memset(ep->jacks, 0, sizeof(ep->jacks));
479 TAILQ_INIT(&ep->queue_head);
480 ep++;
481 }
482 ep = &sc->sc_in_ep[0];
483 for (i=0; i<sc->sc_in_num_endpoints; i++) {
484 epd = usbd_interface2endpoint_descriptor(
485 sc->sc_iface,
486 fp->in_ep[i].ep);
487 if (!epd) {
488 DPRINTF(("%s: cannot get endpoint descriptor(in:%d)\n",
489 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep));
490 err = USBD_INVAL;
491 goto error;
492 }
493 if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
494 UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) {
495 printf("%s: illegal endpoint(in:%d)\n",
496 USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
497 err = USBD_INVAL;
498 goto error;
499 }
500 ep->sc = sc;
501 ep->addr = epd->bEndpointAddress;
502 ep->packetsize = UGETW(epd->wMaxPacketSize);
503 ep->num_jacks = fp->in_ep[i].num_jacks;
504 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks;
505 ep->num_open = 0;
506 memset(ep->jacks, 0, sizeof(ep->jacks));
507 ep++;
508 }
509
510 return USBD_NORMAL_COMPLETION;
511 error:
512 free(sc->sc_endpoints, M_USBDEV);
513 sc->sc_endpoints = NULL;
514 return err;
515 }
516
517 static usbd_status
alloc_all_endpoints_yamaha(struct umidi_softc * sc)518 alloc_all_endpoints_yamaha(struct umidi_softc *sc)
519 {
520 /* This driver currently supports max 1in/1out bulk endpoints */
521 usb_descriptor_t *desc;
522 usb_endpoint_descriptor_t *epd;
523 int out_addr, in_addr, in_packetsize, i;
524 int dir;
525 size_t remain, descsize;
526
527 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
528 out_addr = in_addr = 0;
529
530 /* detect endpoints */
531 desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
532 for (i=(int)TO_IFD(desc)->bNumEndpoints-1; i>=0; i--) {
533 epd = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
534 if (UE_GET_XFERTYPE(epd->bmAttributes) == UE_BULK) {
535 dir = UE_GET_DIR(epd->bEndpointAddress);
536 if (dir==UE_DIR_OUT && !out_addr)
537 out_addr = epd->bEndpointAddress;
538 else if (dir==UE_DIR_IN && !in_addr) {
539 in_addr = epd->bEndpointAddress;
540 in_packetsize = UGETW(epd->wMaxPacketSize);
541 }
542 }
543 }
544 desc = NEXT_D(desc);
545
546 /* count jacks */
547 if (!(desc->bDescriptorType==UDESC_CS_INTERFACE &&
548 desc->bDescriptorSubtype==UMIDI_MS_HEADER))
549 return USBD_INVAL;
550 remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
551 (size_t)desc->bLength;
552 desc = NEXT_D(desc);
553
554 while (remain>=sizeof(usb_descriptor_t)) {
555 descsize = desc->bLength;
556 if (descsize>remain || descsize==0)
557 break;
558 if (desc->bDescriptorType==UDESC_CS_INTERFACE &&
559 remain>=UMIDI_JACK_DESCRIPTOR_SIZE) {
560 if (desc->bDescriptorSubtype==UMIDI_OUT_JACK)
561 sc->sc_out_num_jacks++;
562 else if (desc->bDescriptorSubtype==UMIDI_IN_JACK)
563 sc->sc_in_num_jacks++;
564 }
565 desc = NEXT_D(desc);
566 remain-=descsize;
567 }
568
569 /* validate some parameters */
570 if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS)
571 sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS;
572 if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS)
573 sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS;
574 if (sc->sc_out_num_jacks && out_addr) {
575 sc->sc_out_num_endpoints = 1;
576 } else {
577 sc->sc_out_num_endpoints = 0;
578 sc->sc_out_num_jacks = 0;
579 }
580 if (sc->sc_in_num_jacks && in_addr) {
581 sc->sc_in_num_endpoints = 1;
582 } else {
583 sc->sc_in_num_endpoints = 0;
584 sc->sc_in_num_jacks = 0;
585 }
586 sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)*
587 (sc->sc_out_num_endpoints+
588 sc->sc_in_num_endpoints),
589 M_USBDEV, M_WAITOK);
590 if (!sc->sc_endpoints)
591 return USBD_NOMEM;
592 if (sc->sc_out_num_endpoints) {
593 sc->sc_out_ep = sc->sc_endpoints;
594 sc->sc_out_ep->sc = sc;
595 sc->sc_out_ep->addr = out_addr;
596 sc->sc_out_ep->packetsize = UMIDI_PACKET_SIZE;
597 sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks;
598 sc->sc_out_ep->num_open = 0;
599 memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks));
600 } else
601 sc->sc_out_ep = NULL;
602
603 if (sc->sc_in_num_endpoints) {
604 sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints;
605 sc->sc_in_ep->sc = sc;
606 sc->sc_in_ep->addr = in_addr;
607 sc->sc_in_ep->packetsize = in_packetsize;
608 sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks;
609 sc->sc_in_ep->num_open = 0;
610 memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks));
611 } else
612 sc->sc_in_ep = NULL;
613
614 return USBD_NORMAL_COMPLETION;
615 }
616
617 static usbd_status
alloc_all_endpoints_genuine(struct umidi_softc * sc)618 alloc_all_endpoints_genuine(struct umidi_softc *sc)
619 {
620 usb_interface_descriptor_t *interface_desc;
621 usb_config_descriptor_t *config_desc;
622 usb_descriptor_t *desc;
623 int num_ep;
624 size_t remain, descsize;
625 struct umidi_endpoint *p, *q, *lowest, *endep, tmpep;
626 int epaddr, eppacketsize;
627
628 interface_desc = usbd_get_interface_descriptor(sc->sc_iface);
629 num_ep = interface_desc->bNumEndpoints;
630 sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint) * num_ep,
631 M_USBDEV, M_WAITOK);
632 if (!p)
633 return USBD_NOMEM;
634
635 sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
636 sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0;
637 epaddr = -1;
638
639 /* get the list of endpoints for midi stream */
640 config_desc = usbd_get_config_descriptor(sc->sc_udev);
641 desc = (usb_descriptor_t *) config_desc;
642 remain = (size_t)UGETW(config_desc->wTotalLength);
643 while (remain>=sizeof(usb_descriptor_t)) {
644 descsize = desc->bLength;
645 if (descsize>remain || descsize==0)
646 break;
647 if (desc->bDescriptorType==UDESC_ENDPOINT &&
648 remain>=USB_ENDPOINT_DESCRIPTOR_SIZE &&
649 UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) {
650 epaddr = TO_EPD(desc)->bEndpointAddress;
651 eppacketsize = UGETW(TO_EPD(desc)->wMaxPacketSize);
652 } else if (desc->bDescriptorType==UDESC_CS_ENDPOINT &&
653 remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE &&
654 epaddr!=-1) {
655 if (num_ep>0) {
656 num_ep--;
657 p->sc = sc;
658 p->addr = epaddr;
659 p->packetsize = eppacketsize;
660 p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack;
661 if (UE_GET_DIR(epaddr)==UE_DIR_OUT) {
662 sc->sc_out_num_endpoints++;
663 sc->sc_out_num_jacks += p->num_jacks;
664 } else {
665 sc->sc_in_num_endpoints++;
666 sc->sc_in_num_jacks += p->num_jacks;
667 }
668 p++;
669 }
670 } else
671 epaddr = -1;
672 desc = NEXT_D(desc);
673 remain-=descsize;
674 }
675
676 /* sort endpoints */
677 num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints;
678 p = sc->sc_endpoints;
679 endep = p + num_ep;
680 while (p<endep) {
681 lowest = p;
682 for (q=p+1; q<endep; q++) {
683 if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN &&
684 UE_GET_DIR(q->addr)==UE_DIR_OUT) ||
685 ((UE_GET_DIR(lowest->addr)==
686 UE_GET_DIR(q->addr)) &&
687 (UE_GET_ADDR(lowest->addr)>
688 UE_GET_ADDR(q->addr))))
689 lowest = q;
690 }
691 if (lowest != p) {
692 memcpy((void *)&tmpep, (void *)p, sizeof(tmpep));
693 memcpy((void *)p, (void *)lowest, sizeof(tmpep));
694 memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep));
695 }
696 p->num_open = 0;
697 p++;
698 }
699
700 sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
701 sc->sc_in_ep =
702 sc->sc_in_num_endpoints ?
703 sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
704
705 return USBD_NORMAL_COMPLETION;
706 }
707
708
709 /*
710 * jack stuffs
711 */
712
713 static usbd_status
alloc_all_jacks(struct umidi_softc * sc)714 alloc_all_jacks(struct umidi_softc *sc)
715 {
716 int i, j;
717 struct umidi_endpoint *ep;
718 struct umidi_jack *jack, **rjack;
719
720 /* allocate/initialize structures */
721 sc->sc_jacks =
722 malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+
723 sc->sc_out_num_jacks),
724 M_USBDEV, M_WAITOK);
725 if (!sc->sc_jacks)
726 return USBD_NOMEM;
727 sc->sc_out_jacks =
728 sc->sc_out_num_jacks ? sc->sc_jacks : NULL;
729 sc->sc_in_jacks =
730 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL;
731
732 jack = &sc->sc_out_jacks[0];
733 for (i=0; i<sc->sc_out_num_jacks; i++) {
734 jack->opened = 0;
735 jack->binded = 0;
736 jack->arg = NULL;
737 jack->u.out.intr = NULL;
738 jack->cable_number = i;
739 jack++;
740 }
741 jack = &sc->sc_in_jacks[0];
742 for (i=0; i<sc->sc_in_num_jacks; i++) {
743 jack->opened = 0;
744 jack->binded = 0;
745 jack->arg = NULL;
746 jack->u.in.intr = NULL;
747 jack->cable_number = i;
748 jack++;
749 }
750
751 /* assign each jacks to each endpoints */
752 jack = &sc->sc_out_jacks[0];
753 ep = &sc->sc_out_ep[0];
754 for (i=0; i<sc->sc_out_num_endpoints; i++) {
755 rjack = &ep->jacks[0];
756 for (j=0; j<ep->num_jacks; j++) {
757 *rjack = jack;
758 jack->endpoint = ep;
759 jack++;
760 rjack++;
761 }
762 ep++;
763 }
764 jack = &sc->sc_in_jacks[0];
765 ep = &sc->sc_in_ep[0];
766 for (i=0; i<sc->sc_in_num_endpoints; i++) {
767 rjack = &ep->jacks[0];
768 for (j=0; j<ep->num_jacks; j++) {
769 *rjack = jack;
770 jack->endpoint = ep;
771 jack++;
772 rjack++;
773 }
774 ep++;
775 }
776
777 return USBD_NORMAL_COMPLETION;
778 }
779
780 static void
free_all_jacks(struct umidi_softc * sc)781 free_all_jacks(struct umidi_softc *sc)
782 {
783 int s;
784
785 s = splaudio();
786 if (sc->sc_out_jacks) {
787 free(sc->sc_jacks, M_USBDEV);
788 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
789 }
790 splx(s);
791 }
792
793 static usbd_status
bind_jacks_to_mididev(struct umidi_softc * sc,struct umidi_jack * out_jack,struct umidi_jack * in_jack,struct umidi_mididev * mididev)794 bind_jacks_to_mididev(struct umidi_softc *sc,
795 struct umidi_jack *out_jack,
796 struct umidi_jack *in_jack,
797 struct umidi_mididev *mididev)
798 {
799 if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded))
800 return USBD_IN_USE;
801 if (mididev->out_jack || mididev->in_jack)
802 return USBD_IN_USE;
803
804 if (out_jack)
805 out_jack->binded = 1;
806 if (in_jack)
807 in_jack->binded = 1;
808 mididev->in_jack = in_jack;
809 mididev->out_jack = out_jack;
810
811 return USBD_NORMAL_COMPLETION;
812 }
813
814 static void
unbind_jacks_from_mididev(struct umidi_mididev * mididev)815 unbind_jacks_from_mididev(struct umidi_mididev *mididev)
816 {
817 if ((mididev->flags & FWRITE) && mididev->out_jack)
818 close_out_jack(mididev->out_jack);
819 if ((mididev->flags & FREAD) && mididev->in_jack)
820 close_in_jack(mididev->in_jack);
821
822 if (mididev->out_jack)
823 mididev->out_jack->binded = 0;
824 if (mididev->in_jack)
825 mididev->in_jack->binded = 0;
826 mididev->out_jack = mididev->in_jack = NULL;
827 }
828
829 static void
unbind_all_jacks(struct umidi_softc * sc)830 unbind_all_jacks(struct umidi_softc *sc)
831 {
832 int i;
833
834 if (sc->sc_mididevs)
835 for (i=0; i<sc->sc_num_mididevs; i++) {
836 unbind_jacks_from_mididev(&sc->sc_mididevs[i]);
837 }
838 }
839
840 static usbd_status
assign_all_jacks_automatically(struct umidi_softc * sc)841 assign_all_jacks_automatically(struct umidi_softc *sc)
842 {
843 usbd_status err;
844 int i;
845 struct umidi_jack *out, *in;
846
847 err =
848 alloc_all_mididevs(sc,
849 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks));
850 if (err!=USBD_NORMAL_COMPLETION)
851 return err;
852
853 for (i=0; i<sc->sc_num_mididevs; i++) {
854 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL;
855 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL;
856 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]);
857 if (err!=USBD_NORMAL_COMPLETION) {
858 free_all_mididevs(sc);
859 return err;
860 }
861 }
862
863 return USBD_NORMAL_COMPLETION;
864 }
865
866 static usbd_status
open_out_jack(struct umidi_jack * jack,void * arg,void (* intr)(void *))867 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
868 {
869 if (jack->opened)
870 return USBD_IN_USE;
871
872 jack->arg = arg;
873 jack->u.out.intr = intr;
874 init_packet(&jack->packet);
875 jack->opened = 1;
876 jack->endpoint->num_open++;
877
878 return USBD_NORMAL_COMPLETION;
879 }
880
881 static usbd_status
open_in_jack(struct umidi_jack * jack,void * arg,void (* intr)(void *,int))882 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int))
883 {
884 if (jack->opened)
885 return USBD_IN_USE;
886
887 jack->arg = arg;
888 jack->u.in.intr = intr;
889 jack->opened = 1;
890 jack->endpoint->num_open++;
891
892 return USBD_NORMAL_COMPLETION;
893 }
894
895 static void
close_out_jack(struct umidi_jack * jack)896 close_out_jack(struct umidi_jack *jack)
897 {
898 if (jack->opened) {
899 #ifdef UMIDI_DEBUG
900 if (!TAILQ_EMPTY(&jack->endpoint->queue_head)) {
901 printf("close_out_jack: queue_head still not empty\n");
902 }
903 #endif
904 jack->opened = 0;
905 jack->endpoint->num_open--;
906 }
907 }
908
909 static void
close_in_jack(struct umidi_jack * jack)910 close_in_jack(struct umidi_jack *jack)
911 {
912 if (jack->opened) {
913 jack->opened = 0;
914 jack->endpoint->num_open--;
915 }
916 }
917
918 static usbd_status
attach_mididev(struct umidi_softc * sc,struct umidi_mididev * mididev)919 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev)
920 {
921 if (mididev->sc)
922 return USBD_IN_USE;
923
924 mididev->sc = sc;
925
926 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev);
927
928 return USBD_NORMAL_COMPLETION;
929 }
930
931 static usbd_status
detach_mididev(struct umidi_mididev * mididev,int flags)932 detach_mididev(struct umidi_mididev *mididev, int flags)
933 {
934 if (!mididev->sc)
935 return USBD_NO_ADDR;
936
937 if (mididev->opened) {
938 umidi_close(mididev);
939 }
940 unbind_jacks_from_mididev(mididev);
941
942 if (mididev->mdev)
943 config_detach(mididev->mdev, flags);
944
945 mididev->sc = NULL;
946
947 return USBD_NORMAL_COMPLETION;
948 }
949
950 static usbd_status
deactivate_mididev(struct umidi_mididev * mididev)951 deactivate_mididev(struct umidi_mididev *mididev)
952 {
953 if (mididev->out_jack)
954 mididev->out_jack->binded = 0;
955 if (mididev->in_jack)
956 mididev->in_jack->binded = 0;
957 config_deactivate(mididev->mdev);
958
959 return USBD_NORMAL_COMPLETION;
960 }
961
962 static usbd_status
alloc_all_mididevs(struct umidi_softc * sc,int nmidi)963 alloc_all_mididevs(struct umidi_softc *sc, int nmidi)
964 {
965 sc->sc_num_mididevs = nmidi;
966 sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi,
967 M_USBDEV, M_WAITOK);
968 if (!sc->sc_mididevs)
969 return USBD_NOMEM;
970 memset(sc->sc_mididevs, 0, sizeof(*sc->sc_mididevs)*nmidi);
971
972 return USBD_NORMAL_COMPLETION;
973 }
974
975 static void
free_all_mididevs(struct umidi_softc * sc)976 free_all_mididevs(struct umidi_softc *sc)
977 {
978 sc->sc_num_mididevs = 0;
979 if (sc->sc_mididevs)
980 free(sc->sc_mididevs, M_USBDEV);
981 }
982
983 static usbd_status
attach_all_mididevs(struct umidi_softc * sc)984 attach_all_mididevs(struct umidi_softc *sc)
985 {
986 usbd_status err;
987 int i;
988
989 if (sc->sc_mididevs)
990 for (i=0; i<sc->sc_num_mididevs; i++) {
991 err = attach_mididev(sc, &sc->sc_mididevs[i]);
992 if (err!=USBD_NORMAL_COMPLETION)
993 return err;
994 }
995
996 return USBD_NORMAL_COMPLETION;
997 }
998
999 static usbd_status
detach_all_mididevs(struct umidi_softc * sc,int flags)1000 detach_all_mididevs(struct umidi_softc *sc, int flags)
1001 {
1002 usbd_status err;
1003 int i;
1004
1005 if (sc->sc_mididevs)
1006 for (i=0; i<sc->sc_num_mididevs; i++) {
1007 err = detach_mididev(&sc->sc_mididevs[i], flags);
1008 if (err!=USBD_NORMAL_COMPLETION)
1009 return err;
1010 }
1011
1012 return USBD_NORMAL_COMPLETION;
1013 }
1014
1015 static usbd_status
deactivate_all_mididevs(struct umidi_softc * sc)1016 deactivate_all_mididevs(struct umidi_softc *sc)
1017 {
1018 usbd_status err;
1019 int i;
1020
1021 if (sc->sc_mididevs)
1022 for (i=0; i<sc->sc_num_mididevs; i++) {
1023 err = deactivate_mididev(&sc->sc_mididevs[i]);
1024 if (err!=USBD_NORMAL_COMPLETION)
1025 return err;
1026 }
1027
1028 return USBD_NORMAL_COMPLETION;
1029 }
1030
1031 #ifdef UMIDI_DEBUG
1032 static void
dump_sc(struct umidi_softc * sc)1033 dump_sc(struct umidi_softc *sc)
1034 {
1035 int i;
1036
1037 DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev)));
1038 for (i=0; i<sc->sc_out_num_endpoints; i++) {
1039 DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i]));
1040 dump_ep(&sc->sc_out_ep[i]);
1041 }
1042 for (i=0; i<sc->sc_in_num_endpoints; i++) {
1043 DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i]));
1044 dump_ep(&sc->sc_in_ep[i]);
1045 }
1046 }
1047
1048 static void
dump_ep(struct umidi_endpoint * ep)1049 dump_ep(struct umidi_endpoint *ep)
1050 {
1051 int i;
1052 for (i=0; i<ep->num_jacks; i++) {
1053 DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i]));
1054 dump_jack(ep->jacks[i]);
1055 }
1056 }
1057 static void
dump_jack(struct umidi_jack * jack)1058 dump_jack(struct umidi_jack *jack)
1059 {
1060 DPRINTFN(10, ("\t\t\tep=%p\n",
1061 jack->endpoint));
1062 }
1063
1064 #endif /* UMIDI_DEBUG */
1065
1066
1067
1068 /*
1069 * MUX MIDI PACKET
1070 */
1071
1072 static const int packet_length[16] = {
1073 /*0*/ -1,
1074 /*1*/ -1,
1075 /*2*/ 2,
1076 /*3*/ 3,
1077 /*4*/ 3,
1078 /*5*/ 1,
1079 /*6*/ 2,
1080 /*7*/ 3,
1081 /*8*/ 3,
1082 /*9*/ 3,
1083 /*A*/ 3,
1084 /*B*/ 3,
1085 /*C*/ 2,
1086 /*D*/ 2,
1087 /*E*/ 3,
1088 /*F*/ 1,
1089 };
1090
1091 #define GET_CN(p) (((unsigned char)(p)>>4)&0x0F)
1092 #define GET_CIN(p) ((unsigned char)(p)&0x0F)
1093 #define MIX_CN_CIN(cn, cin) \
1094 ((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \
1095 ((unsigned char)(cin)&0x0F)))
1096
1097 static void
init_packet(struct umidi_packet * packet)1098 init_packet(struct umidi_packet *packet)
1099 {
1100 packet->status = 0;
1101 packet->index = 0;
1102 }
1103
1104 static usbd_status
start_input_transfer(struct umidi_endpoint * ep)1105 start_input_transfer(struct umidi_endpoint *ep)
1106 {
1107 usbd_status err;
1108 usbd_setup_xfer(ep->xfer, ep->pipe,
1109 (usbd_private_handle)ep,
1110 ep->buffer, ep->packetsize,
1111 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr);
1112 err = usbd_transfer(ep->xfer);
1113 if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
1114 DPRINTF(("%s: start_input_transfer: usbd_transfer() failed err=%s\n",
1115 USBDEVNAME(ep->sc->sc_dev), usbd_errstr(err)));
1116 return err;
1117 }
1118 return USBD_NORMAL_COMPLETION;
1119 }
1120
1121 static usbd_status
start_output_transfer(struct umidi_endpoint * ep)1122 start_output_transfer(struct umidi_endpoint *ep)
1123 {
1124 usbd_status err;
1125 usbd_setup_xfer(ep->xfer, ep->pipe,
1126 (usbd_private_handle)ep,
1127 ep->buffer, UMIDI_PACKET_SIZE,
1128 USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
1129 err = usbd_transfer(ep->xfer);
1130 if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
1131 DPRINTF(("%s: start_output_transfer: usbd_transfer() failed err=%s\n",
1132 USBDEVNAME(ep->sc->sc_dev), usbd_errstr(err)));
1133 return err;
1134 }
1135 return USBD_NORMAL_COMPLETION;
1136 }
1137
1138 #ifdef UMIDI_DEBUG
1139 #define DPR_PACKET(dir, sc, p) \
1140 DPRINTFN(500, \
1141 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n", \
1142 USBDEVNAME(sc->sc_dev), \
1143 (unsigned char)(p)->buffer[0], \
1144 (unsigned char)(p)->buffer[1], \
1145 (unsigned char)(p)->buffer[2], \
1146 (unsigned char)(p)->buffer[3]));
1147 #else
1148 #define DPR_PACKET(dir, sc, p)
1149 #endif
1150
1151 static int
out_jack_output(struct umidi_jack * out_jack,int d)1152 out_jack_output(struct umidi_jack *out_jack, int d)
1153 {
1154 struct umidi_endpoint *ep = out_jack->endpoint;
1155 struct umidi_softc *sc = ep->sc;
1156 int s;
1157
1158 if (sc->sc_dying)
1159 return EIO;
1160
1161 if (!out_jack->opened) {
1162 return ENODEV;
1163 }
1164
1165 if (out_build_packet(out_jack->cable_number, &out_jack->packet, d)) {
1166 DPR_PACKET(out, sc, &out_jack->packet);
1167 s = splusb();
1168 if (TAILQ_EMPTY(&ep->queue_head)) {
1169 memcpy(ep->buffer,
1170 out_jack->packet.buffer,
1171 UMIDI_PACKET_SIZE);
1172 TAILQ_INSERT_TAIL(&ep->queue_head,
1173 out_jack, u.out.queue_entry);
1174 start_output_transfer(ep);
1175 } else {
1176 DPRINTF(("%s: out_jack_output: packet ignored\n", USBDEVNAME(sc->sc_dev)));
1177 }
1178 splx(s);
1179 return 0;
1180 }
1181
1182 return EINPROGRESS;
1183 }
1184
1185 static void
in_intr(usbd_xfer_handle xfer,usbd_private_handle priv,usbd_status status)1186 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1187 {
1188 int cn, evlen, remain, i;
1189 unsigned char *buf;
1190 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1191 struct umidi_jack *jack;
1192
1193 if (ep->sc->sc_dying)
1194 return;
1195
1196 usbd_get_xfer_status(xfer, NULL, NULL, &remain, NULL);
1197 if (status != USBD_NORMAL_COMPLETION) {
1198 DPRINTF(("umidi: in_intr: abnormal status: %s\n", usbd_errstr(status)));
1199 goto quit;
1200 }
1201 buf = ep->buffer;
1202 while (remain >= UMIDI_PACKET_SIZE) {
1203 cn = GET_CN(buf[0]);
1204 if (cn < ep->num_jacks && (jack = ep->jacks[cn]) &&
1205 jack->binded && jack->opened && jack->u.in.intr) {
1206 evlen = packet_length[GET_CIN(buf[0])];
1207 for (i=0; i<evlen; i++)
1208 (*jack->u.in.intr)(jack->arg, buf[i+1]);
1209 } else
1210 DPRINTFN(10, ("in_intr: unused packet %02x %02x %02x %02x\n",
1211 buf[0], buf[1], buf[2], buf[3]));
1212
1213 buf += UMIDI_PACKET_SIZE;
1214 remain -= UMIDI_PACKET_SIZE;
1215 }
1216
1217 #ifdef UMIDI_DEBUG
1218 if (remain != 0) {
1219 DPRINTF(("umidi: in_intr: remain != 0\n"));
1220 }
1221 #endif
1222
1223 quit:
1224 (void)start_input_transfer(ep);
1225 }
1226
1227 static void
out_intr(usbd_xfer_handle xfer,usbd_private_handle priv,usbd_status status)1228 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1229 {
1230 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1231 struct umidi_softc *sc = ep->sc;
1232 struct umidi_jack *jack;
1233 int s;
1234
1235 if (sc->sc_dying)
1236 return;
1237
1238 s = splusb();
1239 jack = TAILQ_FIRST(&ep->queue_head);
1240 if (jack) {
1241 TAILQ_REMOVE(&ep->queue_head, jack, u.out.queue_entry);
1242 if (!TAILQ_EMPTY(&ep->queue_head)) {
1243 memcpy(ep->buffer,
1244 TAILQ_FIRST(&ep->queue_head)->packet.buffer,
1245 UMIDI_PACKET_SIZE);
1246 (void)start_output_transfer(ep);
1247 }
1248 if (jack->opened && jack->u.out.intr)
1249 (*jack->u.out.intr)(jack->arg);
1250 }
1251 splx(s);
1252 }
1253
1254 #define UMIDI_VOICELEN(status) (umidi_evlen[((status) >> 4) & 7])
1255 unsigned umidi_evlen[] = { 4, 4, 4, 4, 3, 3, 4 };
1256
1257 #define EV_SYSEX 0xf0
1258 #define EV_MTC 0xf1
1259 #define EV_SPP 0xf2
1260 #define EV_SONGSEL 0xf3
1261 #define EV_TUNE_REQ 0xf6
1262 #define EV_SYSEX_STOP 0xf7
1263
1264 static int
out_build_packet(int cable_number,struct umidi_packet * packet,uByte data)1265 out_build_packet(int cable_number, struct umidi_packet *packet, uByte data)
1266 {
1267 if (data >= 0xf8) { /* is it a realtime message ? */
1268 packet->buffer[0] = data >> 4 | cable_number << 4;
1269 packet->buffer[1] = data;
1270 packet->buffer[2] = 0;
1271 packet->buffer[3] = 0;
1272 return 1;
1273 }
1274 if (data >= 0xf0) { /* is it a common message ? */
1275 switch(data) {
1276 case EV_SYSEX:
1277 packet->buffer[1] = packet->status = data;
1278 packet->index = 2;
1279 break;
1280 case EV_SYSEX_STOP:
1281 if (packet->status != EV_SYSEX) break;
1282 if (packet->index == 0)
1283 packet->index = 1;
1284 packet->status = data;
1285 packet->buffer[packet->index++] = data;
1286 packet->buffer[0] = (0x4 - 1 + packet->index) | cable_number << 4;
1287 goto packetready;
1288 case EV_TUNE_REQ:
1289 packet->status = data;
1290 packet->buffer[0] = 0x5 | cable_number << 4;
1291 packet->index = 1;
1292 goto packetready;
1293 default:
1294 packet->status = data;
1295 break;
1296 }
1297 return 0;
1298 }
1299 if (data >= 0x80) { /* is it a voice message ? */
1300 packet->status = data;
1301 packet->index = 0;
1302 return 0;
1303 }
1304
1305 /* else it is a data byte */
1306 if (packet->status >= 0xf0) {
1307 switch(packet->status) {
1308 case EV_SYSEX: /* sysex starts or continues */
1309 if (packet->index == 0)
1310 packet->index = 1;
1311
1312 packet->buffer[packet->index++] = data;
1313 if (packet->index >= UMIDI_PACKET_SIZE) {
1314 packet->buffer[0] = 0x4 | cable_number << 4;
1315 goto packetready;
1316 }
1317 break;
1318 case EV_MTC: /* messages with 1 data byte */
1319 case EV_SONGSEL:
1320 packet->buffer[0] = 0x2 | cable_number << 4;
1321 packet->buffer[1] = packet->status;
1322 packet->buffer[2] = data;
1323 packet->index = 3;
1324 goto packetready;
1325 case EV_SPP: /* messages with 2 data bytes */
1326 if (packet->index == 0) {
1327 packet->buffer[0] = 0x3 | cable_number << 4;
1328 packet->index = 1;
1329 }
1330 packet->buffer[packet->index++] = data;
1331 if (packet->index >= UMIDI_PACKET_SIZE) {
1332 packet->buffer[1] = packet->status;
1333 goto packetready;
1334 }
1335 break;
1336 default: /* ignore data with unknown status */
1337 break;
1338 }
1339 return 0;
1340 }
1341 if (packet->status >= 0x80) { /* is it a voice message ? */
1342 if (packet->index == 0) {
1343 packet->buffer[0] = packet->status >> 4 | cable_number << 4;
1344 packet->buffer[1] = packet->status;
1345 packet->index = 2;
1346 }
1347 packet->buffer[packet->index++] = data;
1348 if (packet->index >= UMIDI_VOICELEN(packet->status))
1349 goto packetready;
1350 }
1351 /* ignore data with unknown status */
1352 return 0;
1353
1354 packetready:
1355 while (packet->index < UMIDI_PACKET_SIZE)
1356 packet->buffer[packet->index++] = 0;
1357
1358 packet->index = 0;
1359 return 1;
1360 }
1361