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