]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/usb/serial/umct.c
Merge ^/vendor/lldb/dist up to its last change, and resolve conflicts.
[FreeBSD/FreeBSD.git] / sys / dev / usb / serial / umct.c
1 #include <sys/cdefs.h>
2 __FBSDID("$FreeBSD$");
3
4 /*-
5  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6  *
7  * Copyright (c) 2003 Scott Long
8  * All rights reserved.
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32
33 /*
34  * Driver for the MCT (Magic Control Technology) USB-RS232 Converter.
35  * Based on the superb documentation from the linux mct_u232 driver by
36  * Wolfgang Grandeggar <wolfgang@cec.ch>.
37  * This device smells a lot like the Belkin F5U103, except that it has
38  * suffered some mild brain-damage.  This driver is based off of the ubsa.c
39  * driver from Alexander Kabaev <kan@FreeBSD.org>.  Merging the two together
40  * might be useful, though the subtle differences might lead to lots of
41  * #ifdef's.
42  */
43
44 /*
45  * NOTE: all function names beginning like "umct_cfg_" can only
46  * be called from within the config thread function !
47  */
48
49 #include <sys/stdint.h>
50 #include <sys/stddef.h>
51 #include <sys/param.h>
52 #include <sys/queue.h>
53 #include <sys/types.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/bus.h>
57 #include <sys/module.h>
58 #include <sys/lock.h>
59 #include <sys/mutex.h>
60 #include <sys/condvar.h>
61 #include <sys/sysctl.h>
62 #include <sys/sx.h>
63 #include <sys/unistd.h>
64 #include <sys/callout.h>
65 #include <sys/malloc.h>
66 #include <sys/priv.h>
67
68 #include <dev/usb/usb.h>
69 #include <dev/usb/usbdi.h>
70 #include <dev/usb/usbdi_util.h>
71 #include "usbdevs.h"
72
73 #define USB_DEBUG_VAR usb_debug
74 #include <dev/usb/usb_debug.h>
75 #include <dev/usb/usb_process.h>
76
77 #include <dev/usb/serial/usb_serial.h>
78
79 /* The UMCT advertises the standard 8250 UART registers */
80 #define UMCT_GET_MSR            2       /* Get Modem Status Register */
81 #define UMCT_GET_MSR_SIZE       1
82 #define UMCT_GET_LCR            6       /* Get Line Control Register */
83 #define UMCT_GET_LCR_SIZE       1
84 #define UMCT_SET_BAUD           5       /* Set the Baud Rate Divisor */
85 #define UMCT_SET_BAUD_SIZE      4
86 #define UMCT_SET_LCR            7       /* Set Line Control Register */
87 #define UMCT_SET_LCR_SIZE       1
88 #define UMCT_SET_MCR            10      /* Set Modem Control Register */
89 #define UMCT_SET_MCR_SIZE       1
90
91 #define UMCT_MSR_CTS_CHG        0x01
92 #define UMCT_MSR_DSR_CHG        0x02
93 #define UMCT_MSR_RI_CHG         0x04
94 #define UMCT_MSR_CD_CHG         0x08
95 #define UMCT_MSR_CTS            0x10
96 #define UMCT_MSR_RTS            0x20
97 #define UMCT_MSR_RI             0x40
98 #define UMCT_MSR_CD             0x80
99
100 #define UMCT_INTR_INTERVAL      100
101 #define UMCT_IFACE_INDEX        0
102 #define UMCT_CONFIG_INDEX       0
103
104 enum {
105         UMCT_BULK_DT_WR,
106         UMCT_BULK_DT_RD,
107         UMCT_INTR_DT_RD,
108         UMCT_N_TRANSFER,
109 };
110
111 struct umct_softc {
112         struct ucom_super_softc sc_super_ucom;
113         struct ucom_softc sc_ucom;
114
115         struct usb_device *sc_udev;
116         struct usb_xfer *sc_xfer[UMCT_N_TRANSFER];
117         struct mtx sc_mtx;
118
119         uint32_t sc_unit;
120
121         uint16_t sc_obufsize;
122
123         uint8_t sc_lsr;
124         uint8_t sc_msr;
125         uint8_t sc_lcr;
126         uint8_t sc_mcr;
127         uint8_t sc_iface_no;
128         uint8_t sc_swap_cb;
129 };
130
131 /* prototypes */
132
133 static device_probe_t umct_probe;
134 static device_attach_t umct_attach;
135 static device_detach_t umct_detach;
136 static void umct_free_softc(struct umct_softc *);
137
138 static usb_callback_t umct_intr_callback;
139 static usb_callback_t umct_intr_callback_sub;
140 static usb_callback_t umct_read_callback;
141 static usb_callback_t umct_read_callback_sub;
142 static usb_callback_t umct_write_callback;
143
144 static void     umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
145                     uint16_t len, uint32_t value);
146 static void     umct_free(struct ucom_softc *);
147 static void     umct_cfg_get_status(struct ucom_softc *, uint8_t *,
148                     uint8_t *);
149 static void     umct_cfg_set_break(struct ucom_softc *, uint8_t);
150 static void     umct_cfg_set_dtr(struct ucom_softc *, uint8_t);
151 static void     umct_cfg_set_rts(struct ucom_softc *, uint8_t);
152 static uint8_t  umct_calc_baud(uint32_t);
153 static int      umct_pre_param(struct ucom_softc *, struct termios *);
154 static void     umct_cfg_param(struct ucom_softc *, struct termios *);
155 static void     umct_start_read(struct ucom_softc *);
156 static void     umct_stop_read(struct ucom_softc *);
157 static void     umct_start_write(struct ucom_softc *);
158 static void     umct_stop_write(struct ucom_softc *);
159 static void     umct_poll(struct ucom_softc *ucom);
160
161 static const struct usb_config umct_config[UMCT_N_TRANSFER] = {
162
163         [UMCT_BULK_DT_WR] = {
164                 .type = UE_BULK,
165                 .endpoint = UE_ADDR_ANY,
166                 .direction = UE_DIR_OUT,
167                 .bufsize = 0,   /* use wMaxPacketSize */
168                 .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
169                 .callback = &umct_write_callback,
170         },
171
172         [UMCT_BULK_DT_RD] = {
173                 .type = UE_INTERRUPT,
174                 .endpoint = UE_ADDR_ANY,
175                 .direction = UE_DIR_IN,
176                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
177                 .bufsize = 0,   /* use wMaxPacketSize */
178                 .callback = &umct_read_callback,
179                 .ep_index = 0,          /* first interrupt endpoint */
180         },
181
182         [UMCT_INTR_DT_RD] = {
183                 .type = UE_INTERRUPT,
184                 .endpoint = UE_ADDR_ANY,
185                 .direction = UE_DIR_IN,
186                 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
187                 .bufsize = 0,   /* use wMaxPacketSize */
188                 .callback = &umct_intr_callback,
189                 .ep_index = 1,          /* second interrupt endpoint */
190         },
191 };
192
193 static const struct ucom_callback umct_callback = {
194         .ucom_cfg_get_status = &umct_cfg_get_status,
195         .ucom_cfg_set_dtr = &umct_cfg_set_dtr,
196         .ucom_cfg_set_rts = &umct_cfg_set_rts,
197         .ucom_cfg_set_break = &umct_cfg_set_break,
198         .ucom_cfg_param = &umct_cfg_param,
199         .ucom_pre_param = &umct_pre_param,
200         .ucom_start_read = &umct_start_read,
201         .ucom_stop_read = &umct_stop_read,
202         .ucom_start_write = &umct_start_write,
203         .ucom_stop_write = &umct_stop_write,
204         .ucom_poll = &umct_poll,
205         .ucom_free = &umct_free,
206 };
207
208 static const STRUCT_USB_HOST_ID umct_devs[] = {
209         {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_USB232, 0)},
210         {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_SITECOM_USB232, 0)},
211         {USB_VPI(USB_VENDOR_MCT, USB_PRODUCT_MCT_DU_H3SP_USB232, 0)},
212         {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U109, 0)},
213         {USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5U409, 0)},
214 };
215
216 static device_method_t umct_methods[] = {
217         DEVMETHOD(device_probe, umct_probe),
218         DEVMETHOD(device_attach, umct_attach),
219         DEVMETHOD(device_detach, umct_detach),
220         DEVMETHOD_END
221 };
222
223 static devclass_t umct_devclass;
224
225 static driver_t umct_driver = {
226         .name = "umct",
227         .methods = umct_methods,
228         .size = sizeof(struct umct_softc),
229 };
230
231 DRIVER_MODULE(umct, uhub, umct_driver, umct_devclass, NULL, 0);
232 MODULE_DEPEND(umct, ucom, 1, 1, 1);
233 MODULE_DEPEND(umct, usb, 1, 1, 1);
234 MODULE_VERSION(umct, 1);
235 USB_PNP_HOST_INFO(umct_devs);
236
237 static int
238 umct_probe(device_t dev)
239 {
240         struct usb_attach_arg *uaa = device_get_ivars(dev);
241
242         if (uaa->usb_mode != USB_MODE_HOST) {
243                 return (ENXIO);
244         }
245         if (uaa->info.bConfigIndex != UMCT_CONFIG_INDEX) {
246                 return (ENXIO);
247         }
248         if (uaa->info.bIfaceIndex != UMCT_IFACE_INDEX) {
249                 return (ENXIO);
250         }
251         return (usbd_lookup_id_by_uaa(umct_devs, sizeof(umct_devs), uaa));
252 }
253
254 static int
255 umct_attach(device_t dev)
256 {
257         struct usb_attach_arg *uaa = device_get_ivars(dev);
258         struct umct_softc *sc = device_get_softc(dev);
259         int32_t error;
260         uint16_t maxp;
261         uint8_t iface_index;
262
263         sc->sc_udev = uaa->device;
264         sc->sc_unit = device_get_unit(dev);
265
266         device_set_usb_desc(dev);
267         mtx_init(&sc->sc_mtx, "umct", NULL, MTX_DEF);
268         ucom_ref(&sc->sc_super_ucom);
269
270         sc->sc_iface_no = uaa->info.bIfaceNum;
271
272         iface_index = UMCT_IFACE_INDEX;
273         error = usbd_transfer_setup(uaa->device, &iface_index,
274             sc->sc_xfer, umct_config, UMCT_N_TRANSFER, sc, &sc->sc_mtx);
275
276         if (error) {
277                 device_printf(dev, "allocating USB "
278                     "transfers failed\n");
279                 goto detach;
280         }
281
282         /*
283          * The real bulk-in endpoint is also marked as an interrupt.
284          * The only way to differentiate it from the real interrupt
285          * endpoint is to look at the wMaxPacketSize field.
286          */
287         maxp = usbd_xfer_max_framelen(sc->sc_xfer[UMCT_BULK_DT_RD]);
288         if (maxp == 0x2) {
289
290                 /* guessed wrong - switch around endpoints */
291
292                 struct usb_xfer *temp = sc->sc_xfer[UMCT_INTR_DT_RD];
293
294                 sc->sc_xfer[UMCT_INTR_DT_RD] = sc->sc_xfer[UMCT_BULK_DT_RD];
295                 sc->sc_xfer[UMCT_BULK_DT_RD] = temp;
296                 sc->sc_swap_cb = 1;
297         }
298
299         sc->sc_obufsize = usbd_xfer_max_len(sc->sc_xfer[UMCT_BULK_DT_WR]);
300
301         if (uaa->info.idProduct == USB_PRODUCT_MCT_SITECOM_USB232) {
302                 if (sc->sc_obufsize > 16) {
303                         sc->sc_obufsize = 16;
304                 }
305         }
306         error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
307             &umct_callback, &sc->sc_mtx);
308         if (error) {
309                 goto detach;
310         }
311         ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev);
312
313         return (0);                     /* success */
314
315 detach:
316         umct_detach(dev);
317         return (ENXIO);                 /* failure */
318 }
319
320 static int
321 umct_detach(device_t dev)
322 {
323         struct umct_softc *sc = device_get_softc(dev);
324
325         ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom);
326         usbd_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER);
327
328         device_claim_softc(dev);
329
330         umct_free_softc(sc);
331
332         return (0);
333 }
334
335 UCOM_UNLOAD_DRAIN(umct);
336
337 static void
338 umct_free_softc(struct umct_softc *sc)
339 {
340         if (ucom_unref(&sc->sc_super_ucom)) {
341                 mtx_destroy(&sc->sc_mtx);
342                 device_free_softc(sc);
343         }
344 }
345
346 static void
347 umct_free(struct ucom_softc *ucom)
348 {
349         umct_free_softc(ucom->sc_parent);
350 }
351
352 static void
353 umct_cfg_do_request(struct umct_softc *sc, uint8_t request,
354     uint16_t len, uint32_t value)
355 {
356         struct usb_device_request req;
357         usb_error_t err;
358         uint8_t temp[4];
359
360         if (len > 4)
361                 len = 4;
362         req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
363         req.bRequest = request;
364         USETW(req.wValue, 0);
365         req.wIndex[0] = sc->sc_iface_no;
366         req.wIndex[1] = 0;
367         USETW(req.wLength, len);
368         USETDW(temp, value);
369
370         err = ucom_cfg_do_request(sc->sc_udev, &sc->sc_ucom, 
371             &req, temp, 0, 1000);
372         if (err) {
373                 DPRINTFN(0, "device request failed, err=%s "
374                     "(ignored)\n", usbd_errstr(err));
375         }
376         return;
377 }
378
379 static void
380 umct_intr_callback_sub(struct usb_xfer *xfer, usb_error_t error)
381 {
382         struct umct_softc *sc = usbd_xfer_softc(xfer);
383         struct usb_page_cache *pc;
384         uint8_t buf[2];
385         int actlen;
386
387         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
388
389         switch (USB_GET_STATE(xfer)) {
390         case USB_ST_TRANSFERRED:
391                 if (actlen < 2) {
392                         DPRINTF("too short message\n");
393                         goto tr_setup;
394                 }
395                 pc = usbd_xfer_get_frame(xfer, 0);
396                 usbd_copy_out(pc, 0, buf, sizeof(buf));
397
398                 /*
399                  * MSR bits need translation from ns16550 to SER_* values.
400                  * LSR bits are ns16550 in hardware and ucom.
401                  */
402                 sc->sc_msr = 0;
403                 if (buf[0] & UMCT_MSR_CTS)
404                         sc->sc_msr |= SER_CTS;
405                 if (buf[0] & UMCT_MSR_CD)
406                         sc->sc_msr |= SER_DCD;
407                 if (buf[0] & UMCT_MSR_RI)
408                         sc->sc_msr |= SER_RI;
409                 if (buf[0] & UMCT_MSR_RTS)
410                         sc->sc_msr |= SER_DSR;
411                 sc->sc_lsr = buf[1];
412
413                 ucom_status_change(&sc->sc_ucom);
414                 /* FALLTHROUGH */
415         case USB_ST_SETUP:
416 tr_setup:
417                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
418                 usbd_transfer_submit(xfer);
419                 return;
420
421         default:                        /* Error */
422                 if (error != USB_ERR_CANCELLED) {
423                         /* try to clear stall first */
424                         usbd_xfer_set_stall(xfer);
425                         goto tr_setup;
426                 }
427                 return;
428         }
429 }
430
431 static void
432 umct_cfg_get_status(struct ucom_softc *ucom, uint8_t *lsr, uint8_t *msr)
433 {
434         struct umct_softc *sc = ucom->sc_parent;
435
436         *lsr = sc->sc_lsr;
437         *msr = sc->sc_msr;
438 }
439
440 static void
441 umct_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
442 {
443         struct umct_softc *sc = ucom->sc_parent;
444
445         if (onoff)
446                 sc->sc_lcr |= 0x40;
447         else
448                 sc->sc_lcr &= ~0x40;
449
450         umct_cfg_do_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, sc->sc_lcr);
451 }
452
453 static void
454 umct_cfg_set_dtr(struct ucom_softc *ucom, uint8_t onoff)
455 {
456         struct umct_softc *sc = ucom->sc_parent;
457
458         if (onoff)
459                 sc->sc_mcr |= 0x01;
460         else
461                 sc->sc_mcr &= ~0x01;
462
463         umct_cfg_do_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
464 }
465
466 static void
467 umct_cfg_set_rts(struct ucom_softc *ucom, uint8_t onoff)
468 {
469         struct umct_softc *sc = ucom->sc_parent;
470
471         if (onoff)
472                 sc->sc_mcr |= 0x02;
473         else
474                 sc->sc_mcr &= ~0x02;
475
476         umct_cfg_do_request(sc, UMCT_SET_MCR, UMCT_SET_MCR_SIZE, sc->sc_mcr);
477 }
478
479 static uint8_t
480 umct_calc_baud(uint32_t baud)
481 {
482         switch (baud) {
483                 case B300:return (0x1);
484         case B600:
485                 return (0x2);
486         case B1200:
487                 return (0x3);
488         case B2400:
489                 return (0x4);
490         case B4800:
491                 return (0x6);
492         case B9600:
493                 return (0x8);
494         case B19200:
495                 return (0x9);
496         case B38400:
497                 return (0xa);
498         case B57600:
499                 return (0xb);
500         case 115200:
501                 return (0xc);
502         case B0:
503         default:
504                 break;
505         }
506         return (0x0);
507 }
508
509 static int
510 umct_pre_param(struct ucom_softc *ucom, struct termios *t)
511 {
512         return (0);                     /* we accept anything */
513 }
514
515 static void
516 umct_cfg_param(struct ucom_softc *ucom, struct termios *t)
517 {
518         struct umct_softc *sc = ucom->sc_parent;
519         uint32_t value;
520
521         value = umct_calc_baud(t->c_ospeed);
522         umct_cfg_do_request(sc, UMCT_SET_BAUD, UMCT_SET_BAUD_SIZE, value);
523
524         value = (sc->sc_lcr & 0x40);
525
526         switch (t->c_cflag & CSIZE) {
527         case CS5:
528                 value |= 0x0;
529                 break;
530         case CS6:
531                 value |= 0x1;
532                 break;
533         case CS7:
534                 value |= 0x2;
535                 break;
536         default:
537         case CS8:
538                 value |= 0x3;
539                 break;
540         }
541
542         value |= (t->c_cflag & CSTOPB) ? 0x4 : 0;
543         if (t->c_cflag & PARENB) {
544                 value |= 0x8;
545                 value |= (t->c_cflag & PARODD) ? 0x0 : 0x10;
546         }
547         /*
548          * XXX There doesn't seem to be a way to tell the device
549          * to use flow control.
550          */
551
552         sc->sc_lcr = value;
553         umct_cfg_do_request(sc, UMCT_SET_LCR, UMCT_SET_LCR_SIZE, value);
554 }
555
556 static void
557 umct_start_read(struct ucom_softc *ucom)
558 {
559         struct umct_softc *sc = ucom->sc_parent;
560
561         /* start interrupt endpoint */
562         usbd_transfer_start(sc->sc_xfer[UMCT_INTR_DT_RD]);
563
564         /* start read endpoint */
565         usbd_transfer_start(sc->sc_xfer[UMCT_BULK_DT_RD]);
566 }
567
568 static void
569 umct_stop_read(struct ucom_softc *ucom)
570 {
571         struct umct_softc *sc = ucom->sc_parent;
572
573         /* stop interrupt endpoint */
574         usbd_transfer_stop(sc->sc_xfer[UMCT_INTR_DT_RD]);
575
576         /* stop read endpoint */
577         usbd_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_RD]);
578 }
579
580 static void
581 umct_start_write(struct ucom_softc *ucom)
582 {
583         struct umct_softc *sc = ucom->sc_parent;
584
585         usbd_transfer_start(sc->sc_xfer[UMCT_BULK_DT_WR]);
586 }
587
588 static void
589 umct_stop_write(struct ucom_softc *ucom)
590 {
591         struct umct_softc *sc = ucom->sc_parent;
592
593         usbd_transfer_stop(sc->sc_xfer[UMCT_BULK_DT_WR]);
594 }
595
596 static void
597 umct_read_callback(struct usb_xfer *xfer, usb_error_t error)
598 {
599         struct umct_softc *sc = usbd_xfer_softc(xfer);
600
601         if (sc->sc_swap_cb)
602                 umct_intr_callback_sub(xfer, error);
603         else
604                 umct_read_callback_sub(xfer, error);
605 }
606
607 static void
608 umct_intr_callback(struct usb_xfer *xfer, usb_error_t error)
609 {
610         struct umct_softc *sc = usbd_xfer_softc(xfer);
611
612         if (sc->sc_swap_cb)
613                 umct_read_callback_sub(xfer, error);
614         else
615                 umct_intr_callback_sub(xfer, error);
616 }
617
618 static void
619 umct_write_callback(struct usb_xfer *xfer, usb_error_t error)
620 {
621         struct umct_softc *sc = usbd_xfer_softc(xfer);
622         struct usb_page_cache *pc;
623         uint32_t actlen;
624
625         switch (USB_GET_STATE(xfer)) {
626         case USB_ST_SETUP:
627         case USB_ST_TRANSFERRED:
628 tr_setup:
629                 pc = usbd_xfer_get_frame(xfer, 0);
630                 if (ucom_get_data(&sc->sc_ucom, pc, 0,
631                     sc->sc_obufsize, &actlen)) {
632
633                         usbd_xfer_set_frame_len(xfer, 0, actlen);
634                         usbd_transfer_submit(xfer);
635                 }
636                 return;
637
638         default:                        /* Error */
639                 if (error != USB_ERR_CANCELLED) {
640                         /* try to clear stall first */
641                         usbd_xfer_set_stall(xfer);
642                         goto tr_setup;
643                 }
644                 return;
645         }
646 }
647
648 static void
649 umct_read_callback_sub(struct usb_xfer *xfer, usb_error_t error)
650 {
651         struct umct_softc *sc = usbd_xfer_softc(xfer);
652         struct usb_page_cache *pc;
653         int actlen;
654
655         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
656
657         switch (USB_GET_STATE(xfer)) {
658         case USB_ST_TRANSFERRED:
659                 pc = usbd_xfer_get_frame(xfer, 0);
660                 ucom_put_data(&sc->sc_ucom, pc, 0, actlen);
661
662         case USB_ST_SETUP:
663 tr_setup:
664                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
665                 usbd_transfer_submit(xfer);
666                 return;
667
668         default:                        /* Error */
669                 if (error != USB_ERR_CANCELLED) {
670                         /* try to clear stall first */
671                         usbd_xfer_set_stall(xfer);
672                         goto tr_setup;
673                 }
674                 return;
675         }
676 }
677
678 static void
679 umct_poll(struct ucom_softc *ucom)
680 {
681         struct umct_softc *sc = ucom->sc_parent;
682         usbd_transfer_poll(sc->sc_xfer, UMCT_N_TRANSFER);
683 }