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