xref: /openbsd-src/sys/dev/usb/umidi.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: umidi.c,v 1.9 2003/05/19 00:36:33 nate 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 void 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 
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 
161 USB_ATTACH(umidi)
162 {
163 	usbd_status err;
164 	USB_ATTACH_START(umidi, sc, uaa);
165 	char devinfo[1024];
166 
167 	DPRINTFN(1,("umidi_attach\n"));
168 
169 	usbd_devinfo(uaa->device, 0, devinfo, sizeof devinfo);
170 	printf("\n%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
171 
172 	sc->sc_iface = uaa->iface;
173 	sc->sc_udev = uaa->device;
174 
175 	sc->sc_quirk =
176 	    umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno);
177 	printf("%s: ", USBDEVNAME(sc->sc_dev));
178 	umidi_print_quirk(sc->sc_quirk);
179 
180 
181 	err = alloc_all_endpoints(sc);
182 	if (err!=USBD_NORMAL_COMPLETION) {
183 		printf("%s: alloc_all_endpoints failed. (err=%d)\n",
184 		       USBDEVNAME(sc->sc_dev), err);
185 		goto error;
186 	}
187 	err = alloc_all_jacks(sc);
188 	if (err!=USBD_NORMAL_COMPLETION) {
189 		free_all_endpoints(sc);
190 		printf("%s: alloc_all_jacks failed. (err=%d)\n",
191 		       USBDEVNAME(sc->sc_dev), err);
192 		goto error;
193 	}
194 	printf("%s: out=%d, in=%d\n",
195 	       USBDEVNAME(sc->sc_dev),
196 	       sc->sc_out_num_jacks, sc->sc_in_num_jacks);
197 
198 	err = assign_all_jacks_automatically(sc);
199 	if (err!=USBD_NORMAL_COMPLETION) {
200 		unbind_all_jacks(sc);
201 		free_all_jacks(sc);
202 		free_all_endpoints(sc);
203 		printf("%s: assign_all_jacks_automatically failed. (err=%d)\n",
204 		       USBDEVNAME(sc->sc_dev), err);
205 		goto error;
206 	}
207 	err = attach_all_mididevs(sc);
208 	if (err!=USBD_NORMAL_COMPLETION) {
209 		free_all_jacks(sc);
210 		free_all_endpoints(sc);
211 		printf("%s: attach_all_mididevs failed. (err=%d)\n",
212 		       USBDEVNAME(sc->sc_dev), err);
213 	}
214 
215 #ifdef UMIDI_DEBUG
216 	dump_sc(sc);
217 #endif
218 
219 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH,
220 			   sc->sc_udev, USBDEV(sc->sc_dev));
221 
222 	USB_ATTACH_SUCCESS_RETURN;
223 error:
224 	printf("%s: disabled.\n", USBDEVNAME(sc->sc_dev));
225 	sc->sc_dying = 1;
226 	USB_ATTACH_ERROR_RETURN;
227 }
228 
229 int
230 umidi_activate(device_ptr_t self, enum devact act)
231 {
232 	struct umidi_softc *sc = (struct umidi_softc *)self;
233 
234 	switch (act) {
235 	case DVACT_ACTIVATE:
236 		DPRINTFN(1,("umidi_activate (activate)\n"));
237 
238 		return EOPNOTSUPP;
239 		break;
240 	case DVACT_DEACTIVATE:
241 		DPRINTFN(1,("umidi_activate (deactivate)\n"));
242 		sc->sc_dying = 1;
243 		deactivate_all_mididevs(sc);
244 		break;
245 	}
246 	return 0;
247 }
248 
249 USB_DETACH(umidi)
250 {
251 	USB_DETACH_START(umidi, sc);
252 
253 	DPRINTFN(1,("umidi_detach\n"));
254 
255 	sc->sc_dying = 1;
256 	detach_all_mididevs(sc, flags);
257 	free_all_mididevs(sc);
258 	free_all_jacks(sc);
259 	free_all_endpoints(sc);
260 
261 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
262 			   USBDEV(sc->sc_dev));
263 
264 	return 0;
265 }
266 
267 
268 /*
269  * midi_if stuffs
270  */
271 int
272 umidi_open(void *addr,
273 	   int flags,
274 	   void (*iintr)(void *, int),
275 	   void (*ointr)(void *),
276 	   void *arg)
277 {
278 	struct umidi_mididev *mididev = addr;
279 	struct umidi_softc *sc = mididev->sc;
280 
281 	DPRINTF(("umidi_open: sc=%p\n", sc));
282 
283 	if (!sc)
284 		return ENXIO;
285 	if (mididev->opened)
286 		return EBUSY;
287 	if (sc->sc_dying)
288 		return EIO;
289 
290 	mididev->opened = 1;
291 	mididev->flags = flags;
292 	if ((mididev->flags & FWRITE) && mididev->out_jack)
293 		open_out_jack(mididev->out_jack, arg, ointr);
294 	if ((mididev->flags & FREAD) && mididev->in_jack) {
295 		open_in_jack(mididev->in_jack, arg, iintr);
296 	}
297 
298 	return 0;
299 }
300 
301 void
302 umidi_close(void *addr)
303 {
304 	int s;
305 	struct umidi_mididev *mididev = addr;
306 
307 	s = splusb();
308 	if ((mididev->flags & FWRITE) && mididev->out_jack)
309 		close_out_jack(mididev->out_jack);
310 	if ((mididev->flags & FREAD) && mididev->in_jack)
311 		close_in_jack(mididev->in_jack);
312 	mididev->opened = 0;
313 	splx(s);
314 }
315 
316 int
317 umidi_output(void *addr, int d)
318 {
319 	struct umidi_mididev *mididev = addr;
320 
321 	if (!mididev->out_jack || !mididev->opened)
322 		return EIO;
323 
324 	return out_jack_output(mididev->out_jack, d);
325 }
326 
327 void
328 umidi_getinfo(void *addr, struct midi_info *mi)
329 {
330 	struct umidi_mididev *mididev = addr;
331 /*	struct umidi_softc *sc = mididev->sc; */
332 
333 	mi->name = "USB MIDI I/F"; /* XXX: model name */
334 	mi->props = MIDI_PROP_OUT_INTR;
335 	if (mididev->in_jack)
336 		mi->props |= MIDI_PROP_CAN_INPUT;
337 }
338 
339 
340 /*
341  * each endpoint stuffs
342  */
343 
344 /* alloc/free pipe */
345 static usbd_status
346 alloc_pipe(struct umidi_endpoint *ep)
347 {
348 	struct umidi_softc *sc = ep->sc;
349 	usbd_status err;
350 
351 	DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep));
352 	LIST_INIT(&ep->queue_head);
353 	ep->xfer = usbd_alloc_xfer(sc->sc_udev);
354 	if (ep->xfer == NULL) {
355 	    err = USBD_NOMEM;
356 	    goto quit;
357 	}
358 	ep->buffer = usbd_alloc_buffer(ep->xfer, UMIDI_PACKET_SIZE);
359 	if (ep->buffer == NULL) {
360 	    usbd_free_xfer(ep->xfer);
361 	    err = USBD_NOMEM;
362 	    goto quit;
363 	}
364 	err = usbd_open_pipe(sc->sc_iface, ep->addr, 0, &ep->pipe);
365 	if (err)
366 	    usbd_free_xfer(ep->xfer);
367 quit:
368 	return err;
369 }
370 
371 static void
372 free_pipe(struct umidi_endpoint *ep)
373 {
374 	DPRINTF(("%s: free_pipe %p\n", USBDEVNAME(ep->sc->sc_dev), ep));
375 	usbd_abort_pipe(ep->pipe);
376 	usbd_close_pipe(ep->pipe);
377 	usbd_free_xfer(ep->xfer);
378 }
379 
380 
381 /* alloc/free the array of endpoint structures */
382 
383 static usbd_status alloc_all_endpoints_fixed_ep(struct umidi_softc *);
384 static usbd_status alloc_all_endpoints_yamaha(struct umidi_softc *);
385 static usbd_status alloc_all_endpoints_genuine(struct umidi_softc *);
386 
387 static usbd_status
388 alloc_all_endpoints(struct umidi_softc *sc)
389 {
390 	usbd_status err;
391 	struct umidi_endpoint *ep;
392 	int i;
393 
394 	if (UMQ_ISTYPE(sc, UMQ_TYPE_FIXED_EP)) {
395 		err = alloc_all_endpoints_fixed_ep(sc);
396 	} else if (UMQ_ISTYPE(sc, UMQ_TYPE_YAMAHA)) {
397 		err = alloc_all_endpoints_yamaha(sc);
398 	} else {
399 		err = alloc_all_endpoints_genuine(sc);
400 	}
401 	if (err!=USBD_NORMAL_COMPLETION)
402 		return err;
403 
404 	ep = sc->sc_endpoints;
405 	for (i=sc->sc_out_num_endpoints+sc->sc_in_num_endpoints; i>0; i--) {
406 		err = alloc_pipe(ep++);
407 		if (err!=USBD_NORMAL_COMPLETION) {
408 			for (; ep!=sc->sc_endpoints; ep--)
409 				free_pipe(ep-1);
410 			free(sc->sc_endpoints, M_USBDEV);
411 			sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
412 			break;
413 		}
414 	}
415 	return err;
416 }
417 
418 static void
419 free_all_endpoints(struct umidi_softc *sc)
420 {
421 	int i;
422 	for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++)
423 	    free_pipe(&sc->sc_endpoints[i]);
424 	if (sc->sc_endpoints != NULL)
425 		free(sc->sc_endpoints, M_USBDEV);
426 	sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
427 }
428 
429 static usbd_status
430 alloc_all_endpoints_fixed_ep(struct umidi_softc *sc)
431 {
432 	usbd_status err;
433 	struct umq_fixed_ep_desc *fp;
434 	struct umidi_endpoint *ep;
435 	usb_endpoint_descriptor_t *epd;
436 	int i;
437 
438 	fp = umidi_get_quirk_data_from_type(sc->sc_quirk,
439 					    UMQ_TYPE_FIXED_EP);
440 	sc->sc_out_num_jacks = 0;
441 	sc->sc_in_num_jacks = 0;
442 	sc->sc_out_num_endpoints = fp->num_out_ep;
443 	sc->sc_in_num_endpoints = fp->num_in_ep;
444 	sc->sc_endpoints = malloc(sizeof(*sc->sc_out_ep)*
445 				  (sc->sc_out_num_endpoints+
446 				   sc->sc_in_num_endpoints),
447 				  M_USBDEV, M_WAITOK);
448 	if (!sc->sc_endpoints) {
449 		return USBD_NOMEM;
450 	}
451 	sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
452 	sc->sc_in_ep =
453 	    sc->sc_in_num_endpoints ?
454 		sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
455 
456 	ep = &sc->sc_out_ep[0];
457 	for (i=0; i<sc->sc_out_num_endpoints; i++) {
458 		epd = usbd_interface2endpoint_descriptor(
459 			sc->sc_iface,
460 			fp->out_ep[i].ep);
461 		if (!epd) {
462 			printf("%s: cannot get endpoint descriptor(out:%d)\n",
463 			       USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
464 			err = USBD_INVAL;
465 			goto error;
466 		}
467 		if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
468 		    UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_OUT) {
469 			printf("%s: illegal endpoint(out:%d)\n",
470 			       USBDEVNAME(sc->sc_dev), fp->out_ep[i].ep);
471 			err = USBD_INVAL;
472 			goto error;
473 		}
474 		ep->sc = sc;
475 		ep->addr = epd->bEndpointAddress;
476 		ep->num_jacks = fp->out_ep[i].num_jacks;
477 		sc->sc_out_num_jacks += fp->out_ep[i].num_jacks;
478 		ep->num_open = 0;
479 		memset(ep->jacks, 0, sizeof(ep->jacks));
480 		LIST_INIT(&ep->queue_head);
481 		ep++;
482 	}
483 	ep = &sc->sc_in_ep[0];
484 	for (i=0; i<sc->sc_in_num_endpoints; i++) {
485 		epd = usbd_interface2endpoint_descriptor(
486 			sc->sc_iface,
487 			fp->in_ep[i].ep);
488 		if (!epd) {
489 			printf("%s: cannot get endpoint descriptor(in:%d)\n",
490 			       USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
491 			err = USBD_INVAL;
492 			goto error;
493 		}
494 		if (UE_GET_XFERTYPE(epd->bmAttributes)!=UE_BULK ||
495 		    UE_GET_DIR(epd->bEndpointAddress)!=UE_DIR_IN) {
496 			printf("%s: illegal endpoint(in:%d)\n",
497 			       USBDEVNAME(sc->sc_dev), fp->in_ep[i].ep);
498 			err = USBD_INVAL;
499 			goto error;
500 		}
501 		ep->sc = sc;
502 		ep->addr = epd->bEndpointAddress;
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
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, 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 		}
541 	}
542 	desc = NEXT_D(desc);
543 
544 	/* count jacks */
545 	if (!(desc->bDescriptorType==UDESC_CS_INTERFACE &&
546 	      desc->bDescriptorSubtype==UMIDI_MS_HEADER))
547 		return USBD_INVAL;
548 	remain = (size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
549 		(size_t)desc->bLength;
550 	desc = NEXT_D(desc);
551 
552 	while (remain>=sizeof(usb_descriptor_t)) {
553 		descsize = desc->bLength;
554 		if (descsize>remain || descsize==0)
555 			break;
556 		if (desc->bDescriptorType==UDESC_CS_INTERFACE &&
557 		    remain>=UMIDI_JACK_DESCRIPTOR_SIZE) {
558 			if (desc->bDescriptorSubtype==UMIDI_OUT_JACK)
559 				sc->sc_out_num_jacks++;
560 			else if (desc->bDescriptorSubtype==UMIDI_IN_JACK)
561 				sc->sc_in_num_jacks++;
562 		}
563 		desc = NEXT_D(desc);
564 		remain-=descsize;
565 	}
566 
567 	/* validate some parameters */
568 	if (sc->sc_out_num_jacks>UMIDI_MAX_EPJACKS)
569 		sc->sc_out_num_jacks = UMIDI_MAX_EPJACKS;
570 	if (sc->sc_in_num_jacks>UMIDI_MAX_EPJACKS)
571 		sc->sc_in_num_jacks = UMIDI_MAX_EPJACKS;
572 	if (sc->sc_out_num_jacks && out_addr) {
573 		sc->sc_out_num_endpoints = 1;
574 	} else {
575 		sc->sc_out_num_endpoints = 0;
576 		sc->sc_out_num_jacks = 0;
577 	}
578 	if (sc->sc_in_num_jacks && in_addr) {
579 		sc->sc_in_num_endpoints = 1;
580 	} else {
581 		sc->sc_in_num_endpoints = 0;
582 		sc->sc_in_num_jacks = 0;
583 	}
584 	sc->sc_endpoints = malloc(sizeof(struct umidi_endpoint)*
585 				  (sc->sc_out_num_endpoints+
586 				   sc->sc_in_num_endpoints),
587 				  M_USBDEV, M_WAITOK);
588 	if (!sc->sc_endpoints)
589 		return USBD_NOMEM;
590 	if (sc->sc_out_num_endpoints) {
591 		sc->sc_out_ep = sc->sc_endpoints;
592 		sc->sc_out_ep->sc = sc;
593 		sc->sc_out_ep->addr = out_addr;
594 		sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks;
595 		sc->sc_out_ep->num_open = 0;
596 		memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks));
597 	} else
598 		sc->sc_out_ep = NULL;
599 
600 	if (sc->sc_in_num_endpoints) {
601 		sc->sc_in_ep = sc->sc_endpoints+sc->sc_out_num_endpoints;
602 		sc->sc_in_ep->sc = sc;
603 		sc->sc_in_ep->addr = in_addr;
604 		sc->sc_in_ep->num_jacks = sc->sc_in_num_jacks;
605 		sc->sc_in_ep->num_open = 0;
606 		memset(sc->sc_in_ep->jacks, 0, sizeof(sc->sc_in_ep->jacks));
607 	} else
608 		sc->sc_in_ep = NULL;
609 
610 	return USBD_NORMAL_COMPLETION;
611 }
612 
613 static usbd_status
614 alloc_all_endpoints_genuine(struct umidi_softc *sc)
615 {
616 	usb_descriptor_t *desc;
617 	int num_ep;
618 	size_t remain, descsize;
619 	struct umidi_endpoint *p, *q, *lowest, *endep, tmpep;
620 	int epaddr;
621 
622 	desc = TO_D(usbd_get_interface_descriptor(sc->sc_iface));
623 	num_ep = TO_IFD(desc)->bNumEndpoints;
624 	desc = NEXT_D(desc); /* ifd -> csifd */
625 	remain = ((size_t)UGETW(TO_CSIFD(desc)->wTotalLength) -
626 		  (size_t)desc->bLength);
627 	desc = NEXT_D(desc);
628 
629 	sc->sc_endpoints = p = malloc(sizeof(struct umidi_endpoint)*num_ep,
630 				      M_USBDEV, M_WAITOK);
631 	if (!p)
632 		return USBD_NOMEM;
633 
634 	sc->sc_out_num_jacks = sc->sc_in_num_jacks = 0;
635 	sc->sc_out_num_endpoints = sc->sc_in_num_endpoints = 0;
636 	epaddr = -1;
637 
638 	/* get the list of endpoints for midi stream */
639 	while (remain>=sizeof(usb_descriptor_t)) {
640 		descsize = desc->bLength;
641 		if (descsize>remain || descsize==0)
642 			break;
643 		if (desc->bDescriptorType==UDESC_ENDPOINT &&
644 		    remain>=USB_ENDPOINT_DESCRIPTOR_SIZE &&
645 		    UE_GET_XFERTYPE(TO_EPD(desc)->bmAttributes) == UE_BULK) {
646 			epaddr = TO_EPD(desc)->bEndpointAddress;
647 		} else if (desc->bDescriptorType==UDESC_CS_ENDPOINT &&
648 			   remain>=UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE &&
649 			   epaddr!=-1) {
650 			if (num_ep>0) {
651 				num_ep--;
652 				p->sc = sc;
653 				p->addr = epaddr;
654 				p->num_jacks = TO_CSEPD(desc)->bNumEmbMIDIJack;
655 				if (UE_GET_DIR(epaddr)==UE_DIR_OUT) {
656 					sc->sc_out_num_endpoints++;
657 					sc->sc_out_num_jacks += p->num_jacks;
658 				} else {
659 					sc->sc_in_num_endpoints++;
660 					sc->sc_in_num_jacks += p->num_jacks;
661 				}
662 				p++;
663 			}
664 		} else
665 			epaddr = -1;
666 		desc = NEXT_D(desc);
667 		remain-=descsize;
668 	}
669 
670 	/* sort endpoints */
671 	num_ep = sc->sc_out_num_endpoints + sc->sc_in_num_endpoints;
672 	p = sc->sc_endpoints;
673 	endep = p + num_ep;
674 	while (p<endep) {
675 		lowest = p;
676 		for (q=p+1; q<endep; q++) {
677 			if ((UE_GET_DIR(lowest->addr)==UE_DIR_IN &&
678 			     UE_GET_DIR(q->addr)==UE_DIR_OUT) ||
679 			    ((UE_GET_DIR(lowest->addr)==
680 			      UE_GET_DIR(q->addr)) &&
681 			     (UE_GET_ADDR(lowest->addr)>
682 			      UE_GET_ADDR(q->addr))))
683 				lowest = q;
684 		}
685 		if (lowest != p) {
686 			memcpy((void *)&tmpep, (void *)p, sizeof(tmpep));
687 			memcpy((void *)p, (void *)lowest, sizeof(tmpep));
688 			memcpy((void *)lowest, (void *)&tmpep, sizeof(tmpep));
689 		}
690 		p->num_open = 0;
691 		p++;
692 	}
693 
694 	sc->sc_out_ep = sc->sc_out_num_endpoints ? sc->sc_endpoints : NULL;
695 	sc->sc_in_ep =
696 	    sc->sc_in_num_endpoints ?
697 		sc->sc_endpoints+sc->sc_out_num_endpoints : NULL;
698 
699 	return USBD_NORMAL_COMPLETION;
700 }
701 
702 
703 /*
704  * jack stuffs
705  */
706 
707 static usbd_status
708 alloc_all_jacks(struct umidi_softc *sc)
709 {
710 	int i, j;
711 	struct umidi_endpoint *ep;
712 	struct umidi_jack *jack, **rjack;
713 
714 	/* allocate/initialize structures */
715 	sc->sc_jacks =
716 	    malloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+
717 					      sc->sc_out_num_jacks),
718 		   M_USBDEV, M_WAITOK);
719 	if (!sc->sc_jacks)
720 		return USBD_NOMEM;
721 	sc->sc_out_jacks =
722 	    sc->sc_out_num_jacks ? sc->sc_jacks : NULL;
723 	sc->sc_in_jacks =
724 	    sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL;
725 
726 	jack = &sc->sc_out_jacks[0];
727 	for (i=0; i<sc->sc_out_num_jacks; i++) {
728 		jack->opened = 0;
729 		jack->binded = 0;
730 		jack->arg = NULL;
731 		jack->u.out.intr = NULL;
732 		jack->cable_number = i;
733 		jack++;
734 	}
735 	jack = &sc->sc_in_jacks[0];
736 	for (i=0; i<sc->sc_in_num_jacks; i++) {
737 		jack->opened = 0;
738 		jack->binded = 0;
739 		jack->arg = NULL;
740 		jack->u.in.intr = NULL;
741 		jack->cable_number = i;
742 		jack++;
743 	}
744 
745 	/* assign each jacks to each endpoints */
746 	jack = &sc->sc_out_jacks[0];
747 	ep = &sc->sc_out_ep[0];
748 	for (i=0; i<sc->sc_out_num_endpoints; i++) {
749 		rjack = &ep->jacks[0];
750 		for (j=0; j<ep->num_jacks; j++) {
751 			*rjack = jack;
752 			jack->endpoint = ep;
753 			jack++;
754 			rjack++;
755 		}
756 		ep++;
757 	}
758 	jack = &sc->sc_in_jacks[0];
759 	ep = &sc->sc_in_ep[0];
760 	for (i=0; i<sc->sc_in_num_endpoints; i++) {
761 		rjack = &ep->jacks[0];
762 		for (j=0; j<ep->num_jacks; j++) {
763 			*rjack = jack;
764 			jack->endpoint = ep;
765 			jack++;
766 			rjack++;
767 		}
768 		ep++;
769 	}
770 
771 	return USBD_NORMAL_COMPLETION;
772 }
773 
774 static void
775 free_all_jacks(struct umidi_softc *sc)
776 {
777 	int s;
778 
779 	s = splaudio();
780 	if (sc->sc_out_jacks) {
781 		free(sc->sc_jacks, M_USBDEV);
782 		sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
783 	}
784 	splx(s);
785 }
786 
787 static usbd_status
788 bind_jacks_to_mididev(struct umidi_softc *sc,
789 		      struct umidi_jack *out_jack,
790 		      struct umidi_jack *in_jack,
791 		      struct umidi_mididev *mididev)
792 {
793 	if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded))
794 		return USBD_IN_USE;
795 	if (mididev->out_jack || mididev->in_jack)
796 		return USBD_IN_USE;
797 
798 	if (out_jack)
799 		out_jack->binded = 1;
800 	if (in_jack)
801 		in_jack->binded = 1;
802 	mididev->in_jack = in_jack;
803 	mididev->out_jack = out_jack;
804 
805 	return USBD_NORMAL_COMPLETION;
806 }
807 
808 static void
809 unbind_jacks_from_mididev(struct umidi_mididev *mididev)
810 {
811 	if ((mididev->flags & FWRITE) && mididev->out_jack)
812 		close_out_jack(mididev->out_jack);
813 	if ((mididev->flags & FREAD) && mididev->in_jack)
814 		close_in_jack(mididev->in_jack);
815 
816 	if (mididev->out_jack)
817 		mididev->out_jack->binded = 0;
818 	if (mididev->in_jack)
819 		mididev->in_jack->binded = 0;
820 	mididev->out_jack = mididev->in_jack = NULL;
821 }
822 
823 static void
824 unbind_all_jacks(struct umidi_softc *sc)
825 {
826 	int i;
827 
828 	if (sc->sc_mididevs)
829 		for (i=0; i<sc->sc_num_mididevs; i++) {
830 			unbind_jacks_from_mididev(&sc->sc_mididevs[i]);
831 		}
832 }
833 
834 static usbd_status
835 assign_all_jacks_automatically(struct umidi_softc *sc)
836 {
837 	usbd_status err;
838 	int i;
839 	struct umidi_jack *out, *in;
840 
841 	err =
842 	    alloc_all_mididevs(sc,
843 			       max(sc->sc_out_num_jacks, sc->sc_in_num_jacks));
844 	if (err!=USBD_NORMAL_COMPLETION)
845 		return err;
846 
847 	for (i=0; i<sc->sc_num_mididevs; i++) {
848 		out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]:NULL;
849 		in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]:NULL;
850 		err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]);
851 		if (err!=USBD_NORMAL_COMPLETION) {
852 			free_all_mididevs(sc);
853 			return err;
854 		}
855 	}
856 
857 	return USBD_NORMAL_COMPLETION;
858 }
859 
860 static usbd_status
861 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
862 {
863 	struct umidi_endpoint *ep = jack->endpoint;
864 
865 	if (jack->opened)
866 		return USBD_IN_USE;
867 
868 	jack->arg = arg;
869 	jack->u.out.intr = intr;
870 	init_packet(&jack->packet);
871 	jack->opened = 1;
872 	ep->num_open++;
873 
874 	return USBD_NORMAL_COMPLETION;
875 }
876 
877 static usbd_status
878 open_in_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *, int))
879 {
880 	usbd_status err = USBD_NORMAL_COMPLETION;
881 	struct umidi_endpoint *ep = jack->endpoint;
882 
883 	if (jack->opened)
884 		return USBD_IN_USE;
885 
886 	jack->arg = arg;
887 	jack->u.in.intr = intr;
888 	jack->opened = 1;
889 	if (ep->num_open++==0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) {
890 		err = start_input_transfer(ep);
891 		if (err!=USBD_NORMAL_COMPLETION) {
892 			ep->num_open--;
893 		}
894 	}
895 
896 	return err;
897 }
898 
899 static void
900 close_out_jack(struct umidi_jack *jack)
901 {
902 	struct umidi_jack *tail;
903 	int s;
904 
905 	if (jack->opened) {
906 		s = splusb();
907 		LIST_FOREACH(tail,
908 			     &jack->endpoint->queue_head,
909 			     u.out.queue_entry)
910 			if (tail == jack) {
911 				LIST_REMOVE(jack, u.out.queue_entry);
912 				break;
913 			}
914 		if (jack == jack->endpoint->queue_tail) {
915 			/* find tail */
916 			LIST_FOREACH(tail,
917 				     &jack->endpoint->queue_head,
918 				     u.out.queue_entry) {
919 				if (!LIST_NEXT(tail, u.out.queue_entry)) {
920 					jack->endpoint->queue_tail = tail;
921 				}
922 			}
923 		}
924 		splx(s);
925 		jack->opened = 0;
926 		jack->endpoint->num_open--;
927 	}
928 }
929 
930 static void
931 close_in_jack(struct umidi_jack *jack)
932 {
933 	if (jack->opened) {
934 		jack->opened = 0;
935 		jack->endpoint->num_open--;
936 	}
937 }
938 
939 static usbd_status
940 attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev)
941 {
942 	if (mididev->sc)
943 		return USBD_IN_USE;
944 
945 	mididev->sc = sc;
946 
947 	mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, &sc->sc_dev);
948 
949 	return USBD_NORMAL_COMPLETION;
950 }
951 
952 static usbd_status
953 detach_mididev(struct umidi_mididev *mididev, int flags)
954 {
955 	if (!mididev->sc)
956 		return USBD_NO_ADDR;
957 
958 	if (mididev->opened) {
959 		umidi_close(mididev);
960 	}
961 	unbind_jacks_from_mididev(mididev);
962 
963 	if (mididev->mdev)
964 		config_detach(mididev->mdev, flags);
965 
966 	mididev->sc = NULL;
967 
968 	return USBD_NORMAL_COMPLETION;
969 }
970 
971 static usbd_status
972 deactivate_mididev(struct umidi_mididev *mididev)
973 {
974 	if (mididev->out_jack)
975 		mididev->out_jack->binded = 0;
976 	if (mididev->in_jack)
977 		mididev->in_jack->binded = 0;
978 	config_deactivate(mididev->mdev);
979 
980 	return USBD_NORMAL_COMPLETION;
981 }
982 
983 static usbd_status
984 alloc_all_mididevs(struct umidi_softc *sc, int nmidi)
985 {
986 	sc->sc_num_mididevs = nmidi;
987 	sc->sc_mididevs = malloc(sizeof(*sc->sc_mididevs)*nmidi,
988 				 M_USBDEV, M_WAITOK);
989 	if (!sc->sc_mididevs)
990 		return USBD_NOMEM;
991 	memset(sc->sc_mididevs, 0, sizeof(*sc->sc_mididevs)*nmidi);
992 
993 	return USBD_NORMAL_COMPLETION;
994 }
995 
996 static void
997 free_all_mididevs(struct umidi_softc *sc)
998 {
999 	sc->sc_num_mididevs = 0;
1000 	if (sc->sc_mididevs)
1001 		free(sc->sc_mididevs, M_USBDEV);
1002 }
1003 
1004 static usbd_status
1005 attach_all_mididevs(struct umidi_softc *sc)
1006 {
1007 	usbd_status err;
1008 	int i;
1009 
1010 	if (sc->sc_mididevs)
1011 		for (i=0; i<sc->sc_num_mididevs; i++) {
1012 			err = attach_mididev(sc, &sc->sc_mididevs[i]);
1013 			if (err!=USBD_NORMAL_COMPLETION)
1014 				return err;
1015 		}
1016 
1017 	return USBD_NORMAL_COMPLETION;
1018 }
1019 
1020 static usbd_status
1021 detach_all_mididevs(struct umidi_softc *sc, int flags)
1022 {
1023 	usbd_status err;
1024 	int i;
1025 
1026 	if (sc->sc_mididevs)
1027 		for (i=0; i<sc->sc_num_mididevs; i++) {
1028 			err = detach_mididev(&sc->sc_mididevs[i], flags);
1029 			if (err!=USBD_NORMAL_COMPLETION)
1030 				return err;
1031 		}
1032 
1033 	return USBD_NORMAL_COMPLETION;
1034 }
1035 
1036 static usbd_status
1037 deactivate_all_mididevs(struct umidi_softc *sc)
1038 {
1039 	usbd_status err;
1040 	int i;
1041 
1042 	if (sc->sc_mididevs)
1043 		for (i=0; i<sc->sc_num_mididevs; i++) {
1044 			err = deactivate_mididev(&sc->sc_mididevs[i]);
1045 			if (err!=USBD_NORMAL_COMPLETION)
1046 				return err;
1047 		}
1048 
1049 	return USBD_NORMAL_COMPLETION;
1050 }
1051 
1052 #ifdef UMIDI_DEBUG
1053 static void
1054 dump_sc(struct umidi_softc *sc)
1055 {
1056 	int i;
1057 
1058 	DPRINTFN(10, ("%s: dump_sc\n", USBDEVNAME(sc->sc_dev)));
1059 	for (i=0; i<sc->sc_out_num_endpoints; i++) {
1060 		DPRINTFN(10, ("\tout_ep(%p):\n", &sc->sc_out_ep[i]));
1061 		dump_ep(&sc->sc_out_ep[i]);
1062 	}
1063 	for (i=0; i<sc->sc_in_num_endpoints; i++) {
1064 		DPRINTFN(10, ("\tin_ep(%p):\n", &sc->sc_in_ep[i]));
1065 		dump_ep(&sc->sc_in_ep[i]);
1066 	}
1067 }
1068 
1069 static void
1070 dump_ep(struct umidi_endpoint *ep)
1071 {
1072 	int i;
1073 	for (i=0; i<ep->num_jacks; i++) {
1074 		DPRINTFN(10, ("\t\tjack(%p):\n", ep->jacks[i]));
1075 		dump_jack(ep->jacks[i]);
1076 	}
1077 }
1078 static void
1079 dump_jack(struct umidi_jack *jack)
1080 {
1081 	DPRINTFN(10, ("\t\t\tep=%p\n",
1082 		      jack->endpoint));
1083 }
1084 
1085 #endif /* UMIDI_DEBUG */
1086 
1087 
1088 
1089 /*
1090  * MUX MIDI PACKET
1091  */
1092 
1093 static const int packet_length[16] = {
1094 	/*0*/	-1,
1095 	/*1*/	-1,
1096 	/*2*/	2,
1097 	/*3*/	3,
1098 	/*4*/	3,
1099 	/*5*/	1,
1100 	/*6*/	2,
1101 	/*7*/	3,
1102 	/*8*/	3,
1103 	/*9*/	3,
1104 	/*A*/	3,
1105 	/*B*/	3,
1106 	/*C*/	2,
1107 	/*D*/	2,
1108 	/*E*/	3,
1109 	/*F*/	1,
1110 };
1111 
1112 static const struct {
1113 	int		cin;
1114 	packet_state_t	next;
1115 } packet_0xFX[16] = {
1116 	/*F0: SysEx */	{ 0x04, PS_EXCL_1 },
1117 	/*F1: MTC */	{ 0x02, PS_NORMAL_1OF2 },
1118 	/*F2: S.POS */	{ 0x03, PS_NORMAL_1OF3 },
1119 	/*F3: S.SEL */	{ 0x02, PS_NORMAL_1OF2 },
1120 	/*F4: UNDEF */	{ 0x00, PS_INITIAL },
1121 	/*F5: UNDEF */	{ 0x00, PS_INITIAL },
1122 	/*F6: Tune */	{ 0x0F, PS_END },
1123 	/*F7: EofEx */	{ 0x00, PS_INITIAL },
1124 	/*F8: Timing */	{ 0x0F, PS_END },
1125 	/*F9: UNDEF */	{ 0x00, PS_INITIAL },
1126 	/*FA: Start */	{ 0x0F, PS_END },
1127 	/*FB: Cont */	{ 0x0F, PS_END },
1128 	/*FC: Stop */	{ 0x0F, PS_END },
1129 	/*FD: UNDEF */	{ 0x00, PS_INITIAL },
1130 	/*FE: ActS */	{ 0x0F, PS_END },
1131 	/*FF: Reset */	{ 0x0F, PS_END },
1132 };
1133 
1134 #define	GET_CN(p)		(((unsigned char)(p)>>4)&0x0F)
1135 #define GET_CIN(p)		((unsigned char)(p)&0x0F)
1136 #define MIX_CN_CIN(cn, cin) \
1137 	((unsigned char)((((unsigned char)(cn)&0x0F)<<4)| \
1138 			  ((unsigned char)(cin)&0x0F)))
1139 
1140 static void
1141 init_packet(struct umidi_packet *packet)
1142 {
1143 	memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
1144 	packet->state = PS_INITIAL;
1145 }
1146 
1147 static usbd_status
1148 start_input_transfer(struct umidi_endpoint *ep)
1149 {
1150 	usbd_setup_xfer(ep->xfer, ep->pipe,
1151 			(usbd_private_handle)ep,
1152 			ep->buffer, UMIDI_PACKET_SIZE,
1153 			USBD_NO_COPY, USBD_NO_TIMEOUT, in_intr);
1154 	return usbd_transfer(ep->xfer);
1155 }
1156 
1157 static usbd_status
1158 start_output_transfer(struct umidi_endpoint *ep)
1159 {
1160 	usbd_setup_xfer(ep->xfer, ep->pipe,
1161 			(usbd_private_handle)ep,
1162 			ep->buffer, UMIDI_PACKET_SIZE,
1163 			USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
1164 	return usbd_transfer(ep->xfer);
1165 }
1166 
1167 #ifdef UMIDI_DEBUG
1168 #define DPR_PACKET(dir, sc, p)						\
1169 if ((unsigned char)(p)->buffer[1]!=0xFE)				\
1170 	DPRINTFN(500,							\
1171 		 ("%s: umidi packet(" #dir "): %02X %02X %02X %02X\n",	\
1172 		  USBDEVNAME(sc->sc_dev),				\
1173 		  (unsigned char)(p)->buffer[0],			\
1174 		  (unsigned char)(p)->buffer[1],			\
1175 		  (unsigned char)(p)->buffer[2],			\
1176 		  (unsigned char)(p)->buffer[3]));
1177 #else
1178 #define DPR_PACKET(dir, sc, p)
1179 #endif
1180 
1181 static int
1182 out_jack_output(struct umidi_jack *out_jack, int d)
1183 {
1184 	struct umidi_endpoint *ep = out_jack->endpoint;
1185 	struct umidi_softc *sc = ep->sc;
1186 	int error;
1187 	int s;
1188 
1189 	if (sc->sc_dying)
1190 		return EIO;
1191 
1192 	error = 0;
1193 	if (out_jack->opened) {
1194 		DPRINTFN(1000, ("umidi_output: ep=%p 0x%02x\n", ep, d));
1195 		out_build_packet(out_jack->cable_number, &out_jack->packet, d);
1196 		switch (out_jack->packet.state) {
1197 		case PS_EXCL_0:
1198 		case PS_END:
1199 			DPR_PACKET(out, sc, &out_jack->packet);
1200 			s = splusb();
1201 			if (LIST_EMPTY(&ep->queue_head)) {
1202 				memcpy(ep->buffer,
1203 				       out_jack->packet.buffer,
1204 				       UMIDI_PACKET_SIZE);
1205 				start_output_transfer(ep);
1206 			}
1207 			if (LIST_EMPTY(&ep->queue_head))
1208 				LIST_INSERT_HEAD(&ep->queue_head,
1209 						 out_jack, u.out.queue_entry);
1210 			else
1211 				LIST_INSERT_AFTER(ep->queue_tail,
1212 						  out_jack, u.out.queue_entry);
1213 			ep->queue_tail = out_jack;
1214 			splx(s);
1215 			break;
1216 		default:
1217 			error = EINPROGRESS;
1218 		}
1219 	} else
1220 		error = ENODEV;
1221 
1222 	return error;
1223 }
1224 
1225 static void
1226 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1227 {
1228 	int cn, len, i;
1229 	struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1230 	struct umidi_jack *jack;
1231 
1232 	if (ep->sc->sc_dying || !ep->num_open)
1233 		return;
1234 
1235 	cn = GET_CN(ep->buffer[0]);
1236 	len = packet_length[GET_CIN(ep->buffer[0])];
1237 	jack = ep->jacks[cn];
1238 	if (cn>=ep->num_jacks || !jack) {
1239 		DPRINTF(("%s: stray umidi packet (in): %02X %02X %02X %02X\n",
1240 			 USBDEVNAME(ep->sc->sc_dev),
1241 			 (unsigned)ep->buffer[0],
1242 			 (unsigned)ep->buffer[1],
1243 			 (unsigned)ep->buffer[2],
1244 			 (unsigned)ep->buffer[3]));
1245 		return;
1246 	}
1247 	if (!jack->binded || !jack->opened)
1248 		return;
1249 	DPR_PACKET(in, ep->sc, &jack->packet);
1250 	if (jack->u.in.intr) {
1251 		for (i=0; i<len; i++) {
1252 			(*jack->u.in.intr)(jack->arg, ep->buffer[i+1]);
1253 		}
1254 	}
1255 
1256 	(void)start_input_transfer(ep);
1257 }
1258 
1259 static void
1260 out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1261 {
1262 	struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1263 	struct umidi_softc *sc = ep->sc;
1264 	struct umidi_jack *jack;
1265 
1266 	if (sc->sc_dying || !ep->num_open)
1267 		return;
1268 
1269 	jack = LIST_FIRST(&ep->queue_head);
1270 	if (jack && jack->opened) {
1271 		LIST_REMOVE(jack, u.out.queue_entry);
1272 		if (!LIST_EMPTY(&ep->queue_head)) {
1273 			memcpy(ep->buffer,
1274 			       LIST_FIRST(&ep->queue_head)->packet.buffer,
1275 			       UMIDI_PACKET_SIZE);
1276 			(void)start_output_transfer(ep);
1277 		}
1278 		if (jack->u.out.intr) {
1279 			(*jack->u.out.intr)(jack->arg);
1280 		}
1281 	}
1282 }
1283 
1284 static void
1285 out_build_packet(int cable_number, struct umidi_packet *packet, uByte in)
1286 {
1287 	int cin;
1288 	uByte prev;
1289 
1290 retry:
1291 	switch (packet->state) {
1292 	case PS_END:
1293 	case PS_INITIAL:
1294 		prev = packet->buffer[1];
1295 		memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
1296 		if (in<0x80) {
1297 			if (prev>=0x80 && prev<0xf0) {
1298 				/* running status */
1299 				out_build_packet(cable_number, packet, prev);
1300 				goto retry;
1301 			}
1302 			/* ??? */
1303 			break;
1304 		}
1305 		if (in>=0xf0) {
1306 			cin=packet_0xFX[in&0x0F].cin;
1307 			packet->state=packet_0xFX[in&0x0F].next;
1308 		} else {
1309 			cin=(unsigned char)in>>4;
1310 			switch (packet_length[cin]) {
1311 			case 2:
1312 				packet->state = PS_NORMAL_1OF2;
1313 				break;
1314 			case 3:
1315 				packet->state = PS_NORMAL_1OF3;
1316 				break;
1317 			default:
1318 				/* ??? */
1319 				packet->state = PS_INITIAL;
1320 			}
1321 		}
1322 		packet->buffer[0] = MIX_CN_CIN(cable_number, cin);
1323 		packet->buffer[1] = in;
1324 		break;
1325 	case PS_NORMAL_1OF3:
1326 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1327 		packet->buffer[2] = in;
1328 		packet->state = PS_NORMAL_2OF3;
1329 		break;
1330 	case PS_NORMAL_2OF3:
1331 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1332 		packet->buffer[3] = in;
1333 		packet->state = PS_END;
1334 		break;
1335 	case PS_NORMAL_1OF2:
1336 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1337 		packet->buffer[2] = in;
1338 		packet->state = PS_END;
1339 		break;
1340 	case PS_EXCL_0:
1341 		memset(packet->buffer, 0, UMIDI_PACKET_SIZE);
1342 		if (in==0xF7) {
1343 			packet->buffer[0] = MIX_CN_CIN(cable_number, 0x05);
1344 			packet->buffer[1] = 0xF7;
1345 			packet->state = PS_END;
1346 			break;
1347 		}
1348 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1349 		packet->buffer[1] = in;
1350 		packet->state = PS_EXCL_1;
1351 		break;
1352 	case PS_EXCL_1:
1353 		if (in==0xF7) {
1354 			packet->buffer[0] = MIX_CN_CIN(cable_number, 0x06);
1355 			packet->buffer[2] = 0xF7;
1356 			packet->state = PS_END;
1357 			break;
1358 		}
1359 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1360 		packet->buffer[2] = in;
1361 		packet->state = PS_EXCL_2;
1362 		break;
1363 	case PS_EXCL_2:
1364 		if (in==0xF7) {
1365 			packet->buffer[0] = MIX_CN_CIN(cable_number, 0x07);
1366 			packet->buffer[3] = 0xF7;
1367 			packet->state = PS_END;
1368 			break;
1369 		}
1370 		if (in>=0x80) { /* ??? */ packet->state = PS_END; break; }
1371 		packet->buffer[0] = MIX_CN_CIN(cable_number, 0x04);
1372 		packet->buffer[3] = in;
1373 		packet->state = PS_EXCL_0;
1374 		break;
1375 	default:
1376 		printf("umidi: ambiguous state.\n");
1377 		packet->state = PS_INITIAL;
1378 		goto retry;
1379 	}
1380 }
1381 
1382