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