Deleted Added
full compact
umoscom.c (187970) umoscom.c (188413)
1/* $FreeBSD: head/sys/dev/usb2/serial/umoscom2.c 187970 2009-02-01 00:51:25Z thompsa $ */
1/* $FreeBSD: head/sys/dev/usb2/serial/umoscom2.c 188413 2009-02-09 22:05:25Z thompsa $ */
2/* $OpenBSD: umoscom.c,v 1.2 2006/10/26 06:02:43 jsg Exp $ */
3
4/*
5 * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.

--- 141 unchanged lines hidden (view full) ---

151#define UMOSCOM_MSR_RI 0x40
152#define UMOSCOM_MSR_CD 0x80
153
154#define UMOSCOM_BAUD_REF 115200
155
156enum {
157 UMOSCOM_BULK_DT_WR,
158 UMOSCOM_BULK_DT_RD,
2/* $OpenBSD: umoscom.c,v 1.2 2006/10/26 06:02:43 jsg Exp $ */
3
4/*
5 * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.

--- 141 unchanged lines hidden (view full) ---

151#define UMOSCOM_MSR_RI 0x40
152#define UMOSCOM_MSR_CD 0x80
153
154#define UMOSCOM_BAUD_REF 115200
155
156enum {
157 UMOSCOM_BULK_DT_WR,
158 UMOSCOM_BULK_DT_RD,
159 UMOSCOM_BULK_CS_WR,
160 UMOSCOM_BULK_CS_RD,
161 UMOSCOM_INTR_DT_RD,
159 UMOSCOM_INTR_DT_RD,
162 UMOSCOM_INTR_CS_RD,
163 UMOSCOM_N_TRANSFER = 6,
160 UMOSCOM_N_TRANSFER,
164};
165
166struct umoscom_softc {
167 struct usb2_com_super_softc sc_super_ucom;
168 struct usb2_com_softc sc_ucom;
169
170 struct usb2_xfer *sc_xfer[UMOSCOM_N_TRANSFER];
171 struct usb2_device *sc_udev;
172
173 uint8_t sc_mcr;
174 uint8_t sc_lcr;
161};
162
163struct umoscom_softc {
164 struct usb2_com_super_softc sc_super_ucom;
165 struct usb2_com_softc sc_ucom;
166
167 struct usb2_xfer *sc_xfer[UMOSCOM_N_TRANSFER];
168 struct usb2_device *sc_udev;
169
170 uint8_t sc_mcr;
171 uint8_t sc_lcr;
175 uint8_t sc_flags;
176#define UMOSCOM_FLAG_READ_STALL 0x01
177#define UMOSCOM_FLAG_WRITE_STALL 0x02
178#define UMOSCOM_FLAG_INTR_STALL 0x04
179};
180
181/* prototypes */
182
183static device_probe_t umoscom_probe;
184static device_attach_t umoscom_attach;
185static device_detach_t umoscom_detach;
186
187static usb2_callback_t umoscom_write_callback;
172};
173
174/* prototypes */
175
176static device_probe_t umoscom_probe;
177static device_attach_t umoscom_attach;
178static device_detach_t umoscom_detach;
179
180static usb2_callback_t umoscom_write_callback;
188static usb2_callback_t umoscom_write_clear_stall_callback;
189static usb2_callback_t umoscom_read_callback;
181static usb2_callback_t umoscom_read_callback;
190static usb2_callback_t umoscom_read_clear_stall_callback;
191static usb2_callback_t umoscom_intr_callback;
182static usb2_callback_t umoscom_intr_callback;
192static usb2_callback_t umoscom_intr_clear_stall_callback;
193
194static void umoscom_cfg_open(struct usb2_com_softc *);
195static void umoscom_cfg_close(struct usb2_com_softc *);
196static void umoscom_cfg_set_break(struct usb2_com_softc *, uint8_t);
197static void umoscom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
198static void umoscom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
199static int umoscom_pre_param(struct usb2_com_softc *, struct termios *);
200static void umoscom_cfg_param(struct usb2_com_softc *, struct termios *);
201static void umoscom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
202 uint8_t *);
203static void umoscom_cfg_write(struct umoscom_softc *, uint16_t, uint16_t);
204static uint8_t umoscom_cfg_read(struct umoscom_softc *, uint16_t);
183
184static void umoscom_cfg_open(struct usb2_com_softc *);
185static void umoscom_cfg_close(struct usb2_com_softc *);
186static void umoscom_cfg_set_break(struct usb2_com_softc *, uint8_t);
187static void umoscom_cfg_set_dtr(struct usb2_com_softc *, uint8_t);
188static void umoscom_cfg_set_rts(struct usb2_com_softc *, uint8_t);
189static int umoscom_pre_param(struct usb2_com_softc *, struct termios *);
190static void umoscom_cfg_param(struct usb2_com_softc *, struct termios *);
191static void umoscom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
192 uint8_t *);
193static void umoscom_cfg_write(struct umoscom_softc *, uint16_t, uint16_t);
194static uint8_t umoscom_cfg_read(struct umoscom_softc *, uint16_t);
205static void umoscom_cfg_do_request(struct umoscom_softc *,
206 struct usb2_device_request *, void *);
207static void umoscom_start_read(struct usb2_com_softc *);
208static void umoscom_stop_read(struct usb2_com_softc *);
209static void umoscom_start_write(struct usb2_com_softc *);
210static void umoscom_stop_write(struct usb2_com_softc *);
211
212static const struct usb2_config umoscom_config_data[UMOSCOM_N_TRANSFER] = {
213
214 [UMOSCOM_BULK_DT_WR] = {

--- 9 unchanged lines hidden (view full) ---

224 .type = UE_BULK,
225 .endpoint = UE_ADDR_ANY,
226 .direction = UE_DIR_IN,
227 .mh.bufsize = UMOSCOM_BUFSIZE,
228 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
229 .mh.callback = &umoscom_read_callback,
230 },
231
195static void umoscom_start_read(struct usb2_com_softc *);
196static void umoscom_stop_read(struct usb2_com_softc *);
197static void umoscom_start_write(struct usb2_com_softc *);
198static void umoscom_stop_write(struct usb2_com_softc *);
199
200static const struct usb2_config umoscom_config_data[UMOSCOM_N_TRANSFER] = {
201
202 [UMOSCOM_BULK_DT_WR] = {

--- 9 unchanged lines hidden (view full) ---

212 .type = UE_BULK,
213 .endpoint = UE_ADDR_ANY,
214 .direction = UE_DIR_IN,
215 .mh.bufsize = UMOSCOM_BUFSIZE,
216 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
217 .mh.callback = &umoscom_read_callback,
218 },
219
232 [UMOSCOM_BULK_CS_WR] = {
233 .type = UE_CONTROL,
234 .endpoint = 0x00, /* Control pipe */
235 .direction = UE_DIR_ANY,
236 .mh.bufsize = sizeof(struct usb2_device_request),
237 .mh.callback = &umoscom_write_clear_stall_callback,
238 .mh.timeout = 1000, /* 1 second */
239 .mh.interval = 50, /* 50ms */
240 },
241
242 [UMOSCOM_BULK_CS_RD] = {
243 .type = UE_CONTROL,
244 .endpoint = 0x00, /* Control pipe */
245 .direction = UE_DIR_ANY,
246 .mh.bufsize = sizeof(struct usb2_device_request),
247 .mh.callback = &umoscom_read_clear_stall_callback,
248 .mh.timeout = 1000, /* 1 second */
249 .mh.interval = 50, /* 50ms */
250 },
251
252 [UMOSCOM_INTR_DT_RD] = {
253 .type = UE_INTERRUPT,
254 .endpoint = UE_ADDR_ANY,
255 .direction = UE_DIR_IN,
256 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
257 .mh.bufsize = 0, /* use wMaxPacketSize */
258 .mh.callback = &umoscom_intr_callback,
259 },
220 [UMOSCOM_INTR_DT_RD] = {
221 .type = UE_INTERRUPT,
222 .endpoint = UE_ADDR_ANY,
223 .direction = UE_DIR_IN,
224 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
225 .mh.bufsize = 0, /* use wMaxPacketSize */
226 .mh.callback = &umoscom_intr_callback,
227 },
260
261 [UMOSCOM_INTR_CS_RD] = {
262 .type = UE_CONTROL,
263 .endpoint = 0x00, /* Control pipe */
264 .direction = UE_DIR_ANY,
265 .mh.bufsize = sizeof(struct usb2_device_request),
266 .mh.callback = &umoscom_intr_clear_stall_callback,
267 .mh.timeout = 1000, /* 1 second */
268 .mh.interval = 50, /* 50ms */
269 },
270};
271
272static const struct usb2_com_callback umoscom_callback = {
273 /* configuration callbacks */
274 .usb2_com_cfg_get_status = &umoscom_cfg_get_status,
275 .usb2_com_cfg_set_dtr = &umoscom_cfg_set_dtr,
276 .usb2_com_cfg_set_rts = &umoscom_cfg_set_rts,
277 .usb2_com_cfg_set_break = &umoscom_cfg_set_break,

--- 68 unchanged lines hidden (view full) ---

346 error = usb2_transfer_setup(uaa->device, &iface_index,
347 sc->sc_xfer, umoscom_config_data,
348 UMOSCOM_N_TRANSFER, sc, &Giant);
349
350 if (error) {
351 goto detach;
352 }
353 /* clear stall at first run */
228};
229
230static const struct usb2_com_callback umoscom_callback = {
231 /* configuration callbacks */
232 .usb2_com_cfg_get_status = &umoscom_cfg_get_status,
233 .usb2_com_cfg_set_dtr = &umoscom_cfg_set_dtr,
234 .usb2_com_cfg_set_rts = &umoscom_cfg_set_rts,
235 .usb2_com_cfg_set_break = &umoscom_cfg_set_break,

--- 68 unchanged lines hidden (view full) ---

304 error = usb2_transfer_setup(uaa->device, &iface_index,
305 sc->sc_xfer, umoscom_config_data,
306 UMOSCOM_N_TRANSFER, sc, &Giant);
307
308 if (error) {
309 goto detach;
310 }
311 /* clear stall at first run */
354 sc->sc_flags |= (UMOSCOM_FLAG_READ_STALL |
355 UMOSCOM_FLAG_WRITE_STALL);
312 usb2_transfer_set_stall(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
313 usb2_transfer_set_stall(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
356
357 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
358 &umoscom_callback, &Giant);
359 if (error) {
360 goto detach;
361 }
362 return (0);
363

--- 189 unchanged lines hidden (view full) ---

553 struct usb2_device_request req;
554
555 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
556 req.bRequest = UMOSCOM_WRITE;
557 USETW(req.wValue, val);
558 USETW(req.wIndex, reg);
559 USETW(req.wLength, 0);
560
314
315 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
316 &umoscom_callback, &Giant);
317 if (error) {
318 goto detach;
319 }
320 return (0);
321

--- 189 unchanged lines hidden (view full) ---

511 struct usb2_device_request req;
512
513 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
514 req.bRequest = UMOSCOM_WRITE;
515 USETW(req.wValue, val);
516 USETW(req.wIndex, reg);
517 USETW(req.wLength, 0);
518
561 umoscom_cfg_do_request(sc, &req, NULL);
519 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
520 &req, NULL, 0, 1000);
562}
563
564static uint8_t
565umoscom_cfg_read(struct umoscom_softc *sc, uint16_t reg)
566{
567 struct usb2_device_request req;
568 uint8_t val;
569
570 req.bmRequestType = UT_READ_VENDOR_DEVICE;
571 req.bRequest = UMOSCOM_READ;
572 USETW(req.wValue, 0);
573 USETW(req.wIndex, reg);
574 USETW(req.wLength, 1);
575
521}
522
523static uint8_t
524umoscom_cfg_read(struct umoscom_softc *sc, uint16_t reg)
525{
526 struct usb2_device_request req;
527 uint8_t val;
528
529 req.bmRequestType = UT_READ_VENDOR_DEVICE;
530 req.bRequest = UMOSCOM_READ;
531 USETW(req.wValue, 0);
532 USETW(req.wIndex, reg);
533 USETW(req.wLength, 1);
534
576 umoscom_cfg_do_request(sc, &req, &val);
535 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
536 &req, &val, 0, 1000);
577
578 DPRINTF("reg=0x%04x, val=0x%02x\n", reg, val);
579
580 return (val);
581}
582
583static void
537
538 DPRINTF("reg=0x%04x, val=0x%02x\n", reg, val);
539
540 return (val);
541}
542
543static void
584umoscom_cfg_do_request(struct umoscom_softc *sc, struct usb2_device_request *req,
585 void *data)
586{
587 uint16_t length;
588 usb2_error_t err;
589
590 if (usb2_com_cfg_is_gone(&sc->sc_ucom))
591 goto error;
592
593 err = usb2_do_request_flags
594 (sc->sc_udev, &Giant, req, data, 0, NULL, 1000);
595
596 if (err) {
597 DPRINTFN(0, "control request failed: %s\n",
598 usb2_errstr(err));
599error:
600 length = UGETW(req->wLength);
601
602 if ((req->bmRequestType & UT_READ) && length) {
603 bzero(data, length);
604 }
605 }
606}
607
608static void
609umoscom_start_read(struct usb2_com_softc *ucom)
610{
611 struct umoscom_softc *sc = ucom->sc_parent;
612
613#if 0
614 /* start interrupt endpoint */
615 usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
616#endif
617 /* start read endpoint */
618 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
619}
620
621static void
622umoscom_stop_read(struct usb2_com_softc *ucom)
623{
624 struct umoscom_softc *sc = ucom->sc_parent;
625
626 /* stop interrupt transfer */
544umoscom_start_read(struct usb2_com_softc *ucom)
545{
546 struct umoscom_softc *sc = ucom->sc_parent;
547
548#if 0
549 /* start interrupt endpoint */
550 usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
551#endif
552 /* start read endpoint */
553 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
554}
555
556static void
557umoscom_stop_read(struct usb2_com_softc *ucom)
558{
559 struct umoscom_softc *sc = ucom->sc_parent;
560
561 /* stop interrupt transfer */
627 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
628 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
629
630 /* stop read endpoint */
562 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_INTR_DT_RD]);
563
564 /* stop read endpoint */
631 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
632 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
633}
634
635static void
636umoscom_start_write(struct usb2_com_softc *ucom)
637{
638 struct umoscom_softc *sc = ucom->sc_parent;
639
640 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
641}
642
643static void
644umoscom_stop_write(struct usb2_com_softc *ucom)
645{
646 struct umoscom_softc *sc = ucom->sc_parent;
647
565 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_RD]);
566}
567
568static void
569umoscom_start_write(struct usb2_com_softc *ucom)
570{
571 struct umoscom_softc *sc = ucom->sc_parent;
572
573 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
574}
575
576static void
577umoscom_stop_write(struct usb2_com_softc *ucom)
578{
579 struct umoscom_softc *sc = ucom->sc_parent;
580
648 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
649 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
650}
651
652static void
653umoscom_write_callback(struct usb2_xfer *xfer)
654{
655 struct umoscom_softc *sc = xfer->priv_sc;
656 uint32_t actlen;
657
658 switch (USB_GET_STATE(xfer)) {
659 case USB_ST_SETUP:
660 case USB_ST_TRANSFERRED:
581 usb2_transfer_stop(sc->sc_xfer[UMOSCOM_BULK_DT_WR]);
582}
583
584static void
585umoscom_write_callback(struct usb2_xfer *xfer)
586{
587 struct umoscom_softc *sc = xfer->priv_sc;
588 uint32_t actlen;
589
590 switch (USB_GET_STATE(xfer)) {
591 case USB_ST_SETUP:
592 case USB_ST_TRANSFERRED:
593tr_setup:
661 DPRINTF("\n");
662
594 DPRINTF("\n");
595
663 if (sc->sc_flags & UMOSCOM_FLAG_WRITE_STALL) {
664 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
665 return;
666 }
667 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
668 UMOSCOM_BUFSIZE, &actlen)) {
669
670 xfer->frlengths[0] = actlen;
671 usb2_start_hardware(xfer);
672 }
673 return;
674
675 default: /* Error */
676 if (xfer->error != USB_ERR_CANCELLED) {
677 DPRINTFN(0, "transfer failed\n");
596 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
597 UMOSCOM_BUFSIZE, &actlen)) {
598
599 xfer->frlengths[0] = actlen;
600 usb2_start_hardware(xfer);
601 }
602 return;
603
604 default: /* Error */
605 if (xfer->error != USB_ERR_CANCELLED) {
606 DPRINTFN(0, "transfer failed\n");
678 sc->sc_flags |= UMOSCOM_FLAG_WRITE_STALL;
679 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_WR]);
607 /* try to clear stall first */
608 xfer->flags.stall_pipe = 1;
609 goto tr_setup;
680 }
681 return;
682 }
683}
684
685static void
610 }
611 return;
612 }
613}
614
615static void
686umoscom_write_clear_stall_callback(struct usb2_xfer *xfer)
687{
688 struct umoscom_softc *sc = xfer->priv_sc;
689 struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_BULK_DT_WR];
690
691 if (usb2_clear_stall_callback(xfer, xfer_other)) {
692 DPRINTF("stall cleared\n");
693 sc->sc_flags &= ~UMOSCOM_FLAG_WRITE_STALL;
694 usb2_transfer_start(xfer_other);
695 }
696}
697
698static void
699umoscom_read_callback(struct usb2_xfer *xfer)
700{
701 struct umoscom_softc *sc = xfer->priv_sc;
702
703 switch (USB_GET_STATE(xfer)) {
704 case USB_ST_TRANSFERRED:
705 DPRINTF("got %d bytes\n", xfer->actlen);
706 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
707
708 case USB_ST_SETUP:
616umoscom_read_callback(struct usb2_xfer *xfer)
617{
618 struct umoscom_softc *sc = xfer->priv_sc;
619
620 switch (USB_GET_STATE(xfer)) {
621 case USB_ST_TRANSFERRED:
622 DPRINTF("got %d bytes\n", xfer->actlen);
623 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
624
625 case USB_ST_SETUP:
626tr_setup:
709 DPRINTF("\n");
710
627 DPRINTF("\n");
628
711 if (sc->sc_flags & UMOSCOM_FLAG_READ_STALL) {
712 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
713 } else {
714 xfer->frlengths[0] = xfer->max_data_length;
715 usb2_start_hardware(xfer);
716 }
629 xfer->frlengths[0] = xfer->max_data_length;
630 usb2_start_hardware(xfer);
717 return;
718
719 default: /* Error */
720 if (xfer->error != USB_ERR_CANCELLED) {
721 DPRINTFN(0, "transfer failed\n");
631 return;
632
633 default: /* Error */
634 if (xfer->error != USB_ERR_CANCELLED) {
635 DPRINTFN(0, "transfer failed\n");
722 sc->sc_flags |= UMOSCOM_FLAG_READ_STALL;
723 usb2_transfer_start(sc->sc_xfer[UMOSCOM_BULK_CS_RD]);
636 /* try to clear stall first */
637 xfer->flags.stall_pipe = 1;
638 goto tr_setup;
724 }
725 return;
639 }
640 return;
726
727 }
728}
729
730static void
641 }
642}
643
644static void
731umoscom_read_clear_stall_callback(struct usb2_xfer *xfer)
732{
733 struct umoscom_softc *sc = xfer->priv_sc;
734 struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_BULK_DT_RD];
735
736 if (usb2_clear_stall_callback(xfer, xfer_other)) {
737 DPRINTF("stall cleared\n");
738 sc->sc_flags &= ~UMOSCOM_FLAG_READ_STALL;
739 usb2_transfer_start(xfer_other);
740 }
741}
742
743static void
744umoscom_intr_callback(struct usb2_xfer *xfer)
745{
746 struct umoscom_softc *sc = xfer->priv_sc;
747
748 switch (USB_GET_STATE(xfer)) {
749 case USB_ST_TRANSFERRED:
750 if (xfer->actlen < 2) {
751 DPRINTF("too short message\n");
752 goto tr_setup;
753 }
754 usb2_com_status_change(&sc->sc_ucom);
755
756 case USB_ST_SETUP:
757tr_setup:
645umoscom_intr_callback(struct usb2_xfer *xfer)
646{
647 struct umoscom_softc *sc = xfer->priv_sc;
648
649 switch (USB_GET_STATE(xfer)) {
650 case USB_ST_TRANSFERRED:
651 if (xfer->actlen < 2) {
652 DPRINTF("too short message\n");
653 goto tr_setup;
654 }
655 usb2_com_status_change(&sc->sc_ucom);
656
657 case USB_ST_SETUP:
658tr_setup:
758 if (sc->sc_flags & UMOSCOM_FLAG_INTR_STALL) {
759 usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
760 } else {
761 xfer->frlengths[0] = xfer->max_data_length;
762 usb2_start_hardware(xfer);
763 }
659 xfer->frlengths[0] = xfer->max_data_length;
660 usb2_start_hardware(xfer);
764 return;
765
766 default: /* Error */
767 if (xfer->error != USB_ERR_CANCELLED) {
768 DPRINTFN(0, "transfer failed\n");
661 return;
662
663 default: /* Error */
664 if (xfer->error != USB_ERR_CANCELLED) {
665 DPRINTFN(0, "transfer failed\n");
769 sc->sc_flags |= UMOSCOM_FLAG_INTR_STALL;
770 usb2_transfer_start(sc->sc_xfer[UMOSCOM_INTR_CS_RD]);
666 /* try to clear stall first */
667 xfer->flags.stall_pipe = 1;
668 goto tr_setup;
771 }
772 return;
773 }
774}
669 }
670 return;
671 }
672}
775
776static void
777umoscom_intr_clear_stall_callback(struct usb2_xfer *xfer)
778{
779 struct umoscom_softc *sc = xfer->priv_sc;
780 struct usb2_xfer *xfer_other = sc->sc_xfer[UMOSCOM_INTR_DT_RD];
781
782 if (usb2_clear_stall_callback(xfer, xfer_other)) {
783 DPRINTF("stall cleared\n");
784 sc->sc_flags &= ~UMOSCOM_FLAG_INTR_STALL;
785 usb2_transfer_start(xfer_other);
786 }
787}