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