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