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