Deleted Added
full compact
uplcom.c (187970) uplcom.c (188413)
1/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */
2
3#include <sys/cdefs.h>
1/* $NetBSD: uplcom.c,v 1.21 2001/11/13 06:24:56 lukem Exp $ */
2
3#include <sys/cdefs.h>
4__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uplcom2.c 187970 2009-02-01 00:51:25Z thompsa $");
4__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uplcom2.c 188413 2009-02-09 22:05:25Z thompsa $");
5
6/*-
7 * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
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:

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

130#define RSAQ_STATUS_DCD 0x01
131
132#define TYPE_PL2303 0
133#define TYPE_PL2303X 1
134
135enum {
136 UPLCOM_BULK_DT_WR,
137 UPLCOM_BULK_DT_RD,
5
6/*-
7 * Copyright (c) 2001-2003, 2005 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>.
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:

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

130#define RSAQ_STATUS_DCD 0x01
131
132#define TYPE_PL2303 0
133#define TYPE_PL2303X 1
134
135enum {
136 UPLCOM_BULK_DT_WR,
137 UPLCOM_BULK_DT_RD,
138 UPLCOM_BULK_CS_WR,
139 UPLCOM_BULK_CS_RD,
140 UPLCOM_INTR_DT_RD,
138 UPLCOM_INTR_DT_RD,
141 UPLCOM_INTR_CS_RD,
142 UPLCOM_N_TRANSFER = 6,
139 UPLCOM_N_TRANSFER,
143};
144
145struct uplcom_softc {
146 struct usb2_com_super_softc sc_super_ucom;
147 struct usb2_com_softc sc_ucom;
148
149 struct usb2_xfer *sc_xfer[UPLCOM_N_TRANSFER];
150 struct usb2_device *sc_udev;
151
152 uint16_t sc_line;
153
140};
141
142struct uplcom_softc {
143 struct usb2_com_super_softc sc_super_ucom;
144 struct usb2_com_softc sc_ucom;
145
146 struct usb2_xfer *sc_xfer[UPLCOM_N_TRANSFER];
147 struct usb2_device *sc_udev;
148
149 uint16_t sc_line;
150
154 uint8_t sc_flag;
155#define UPLCOM_FLAG_INTR_STALL 0x01
156#define UPLCOM_FLAG_READ_STALL 0x02
157#define UPLCOM_FLAG_WRITE_STALL 0x04
158
159 uint8_t sc_lsr; /* local status register */
160 uint8_t sc_msr; /* uplcom status register */
161 uint8_t sc_chiptype; /* type of chip */
162 uint8_t sc_ctrl_iface_no;
163 uint8_t sc_data_iface_no;
164 uint8_t sc_iface_index[2];
165};
166

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

174static int uplcom_pre_param(struct usb2_com_softc *, struct termios *);
175static void uplcom_cfg_param(struct usb2_com_softc *, struct termios *);
176static void uplcom_start_read(struct usb2_com_softc *);
177static void uplcom_stop_read(struct usb2_com_softc *);
178static void uplcom_start_write(struct usb2_com_softc *);
179static void uplcom_stop_write(struct usb2_com_softc *);
180static void uplcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
181 uint8_t *);
151 uint8_t sc_lsr; /* local status register */
152 uint8_t sc_msr; /* uplcom status register */
153 uint8_t sc_chiptype; /* type of chip */
154 uint8_t sc_ctrl_iface_no;
155 uint8_t sc_data_iface_no;
156 uint8_t sc_iface_index[2];
157};
158

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

166static int uplcom_pre_param(struct usb2_com_softc *, struct termios *);
167static void uplcom_cfg_param(struct usb2_com_softc *, struct termios *);
168static void uplcom_start_read(struct usb2_com_softc *);
169static void uplcom_stop_read(struct usb2_com_softc *);
170static void uplcom_start_write(struct usb2_com_softc *);
171static void uplcom_stop_write(struct usb2_com_softc *);
172static void uplcom_cfg_get_status(struct usb2_com_softc *, uint8_t *,
173 uint8_t *);
182static void uplcom_cfg_do_request(struct uplcom_softc *,
183 struct usb2_device_request *, void *);
184
185static device_probe_t uplcom_probe;
186static device_attach_t uplcom_attach;
187static device_detach_t uplcom_detach;
188
189static usb2_callback_t uplcom_intr_callback;
174
175static device_probe_t uplcom_probe;
176static device_attach_t uplcom_attach;
177static device_detach_t uplcom_detach;
178
179static usb2_callback_t uplcom_intr_callback;
190static usb2_callback_t uplcom_intr_clear_stall_callback;
191static usb2_callback_t uplcom_write_callback;
180static usb2_callback_t uplcom_write_callback;
192static usb2_callback_t uplcom_write_clear_stall_callback;
193static usb2_callback_t uplcom_read_callback;
181static usb2_callback_t uplcom_read_callback;
194static usb2_callback_t uplcom_read_clear_stall_callback;
195
196static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
197
198 [UPLCOM_BULK_DT_WR] = {
199 .type = UE_BULK,
200 .endpoint = UE_ADDR_ANY,
201 .direction = UE_DIR_OUT,
202 .mh.bufsize = UPLCOM_BULK_BUF_SIZE,

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

210 .endpoint = UE_ADDR_ANY,
211 .direction = UE_DIR_IN,
212 .mh.bufsize = UPLCOM_BULK_BUF_SIZE,
213 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
214 .mh.callback = &uplcom_read_callback,
215 .if_index = 0,
216 },
217
182
183static const struct usb2_config uplcom_config_data[UPLCOM_N_TRANSFER] = {
184
185 [UPLCOM_BULK_DT_WR] = {
186 .type = UE_BULK,
187 .endpoint = UE_ADDR_ANY,
188 .direction = UE_DIR_OUT,
189 .mh.bufsize = UPLCOM_BULK_BUF_SIZE,

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

197 .endpoint = UE_ADDR_ANY,
198 .direction = UE_DIR_IN,
199 .mh.bufsize = UPLCOM_BULK_BUF_SIZE,
200 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
201 .mh.callback = &uplcom_read_callback,
202 .if_index = 0,
203 },
204
218 [UPLCOM_BULK_CS_WR] = {
219 .type = UE_CONTROL,
220 .endpoint = 0x00, /* Control pipe */
221 .direction = UE_DIR_ANY,
222 .mh.bufsize = sizeof(struct usb2_device_request),
223 .mh.callback = &uplcom_write_clear_stall_callback,
224 .mh.timeout = 1000, /* 1 second */
225 .mh.interval = 50, /* 50ms */
226 .if_index = 0,
227 },
228
229 [UPLCOM_BULK_CS_RD] = {
230 .type = UE_CONTROL,
231 .endpoint = 0x00, /* Control pipe */
232 .direction = UE_DIR_ANY,
233 .mh.bufsize = sizeof(struct usb2_device_request),
234 .mh.callback = &uplcom_read_clear_stall_callback,
235 .mh.timeout = 1000, /* 1 second */
236 .mh.interval = 50, /* 50ms */
237 .if_index = 0,
238 },
239
240 [UPLCOM_INTR_DT_RD] = {
241 .type = UE_INTERRUPT,
242 .endpoint = UE_ADDR_ANY,
243 .direction = UE_DIR_IN,
244 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
245 .mh.bufsize = 0, /* use wMaxPacketSize */
246 .mh.callback = &uplcom_intr_callback,
247 .if_index = 1,
248 },
205 [UPLCOM_INTR_DT_RD] = {
206 .type = UE_INTERRUPT,
207 .endpoint = UE_ADDR_ANY,
208 .direction = UE_DIR_IN,
209 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
210 .mh.bufsize = 0, /* use wMaxPacketSize */
211 .mh.callback = &uplcom_intr_callback,
212 .if_index = 1,
213 },
249
250 [UPLCOM_INTR_CS_RD] = {
251 .type = UE_CONTROL,
252 .endpoint = 0x00, /* Control pipe */
253 .direction = UE_DIR_ANY,
254 .mh.bufsize = sizeof(struct usb2_device_request),
255 .mh.callback = &uplcom_intr_clear_stall_callback,
256 .mh.timeout = 1000, /* 1 second */
257 .mh.interval = 50, /* 50ms */
258 .if_index = 1,
259 },
260};
261
262struct usb2_com_callback uplcom_callback = {
263 .usb2_com_cfg_get_status = &uplcom_cfg_get_status,
264 .usb2_com_cfg_set_dtr = &uplcom_cfg_set_dtr,
265 .usb2_com_cfg_set_rts = &uplcom_cfg_set_rts,
266 .usb2_com_cfg_set_break = &uplcom_cfg_set_break,
267 .usb2_com_cfg_param = &uplcom_cfg_param,

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

424 }
425 error = uplcom_reset(sc, uaa->device);
426 if (error) {
427 device_printf(dev, "reset failed, error=%s\n",
428 usb2_errstr(error));
429 goto detach;
430 }
431 /* clear stall at first run */
214};
215
216struct usb2_com_callback uplcom_callback = {
217 .usb2_com_cfg_get_status = &uplcom_cfg_get_status,
218 .usb2_com_cfg_set_dtr = &uplcom_cfg_set_dtr,
219 .usb2_com_cfg_set_rts = &uplcom_cfg_set_rts,
220 .usb2_com_cfg_set_break = &uplcom_cfg_set_break,
221 .usb2_com_cfg_param = &uplcom_cfg_param,

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

378 }
379 error = uplcom_reset(sc, uaa->device);
380 if (error) {
381 device_printf(dev, "reset failed, error=%s\n",
382 usb2_errstr(error));
383 goto detach;
384 }
385 /* clear stall at first run */
432 sc->sc_flag |= (UPLCOM_FLAG_READ_STALL |
433 UPLCOM_FLAG_WRITE_STALL);
386 usb2_transfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
387 usb2_transfer_set_stall(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
434
435 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
436 &uplcom_callback, &Giant);
437 if (error) {
438 goto detach;
439 }
440 /*
441 * do the initialization during attach so that the system does not

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

548
549 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
550 req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
551 USETW(req.wValue, sc->sc_line);
552 req.wIndex[0] = sc->sc_data_iface_no;
553 req.wIndex[1] = 0;
554 USETW(req.wLength, 0);
555
388
389 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
390 &uplcom_callback, &Giant);
391 if (error) {
392 goto detach;
393 }
394 /*
395 * do the initialization during attach so that the system does not

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

502
503 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
504 req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
505 USETW(req.wValue, sc->sc_line);
506 req.wIndex[0] = sc->sc_data_iface_no;
507 req.wIndex[1] = 0;
508 USETW(req.wLength, 0);
509
556 uplcom_cfg_do_request(sc, &req, NULL);
510 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
511 &req, NULL, 0, 1000);
557}
558
559static void
560uplcom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
561{
562 struct uplcom_softc *sc = ucom->sc_parent;
563 struct usb2_device_request req;
564

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

571
572 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
573 req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
574 USETW(req.wValue, sc->sc_line);
575 req.wIndex[0] = sc->sc_data_iface_no;
576 req.wIndex[1] = 0;
577 USETW(req.wLength, 0);
578
512}
513
514static void
515uplcom_cfg_set_rts(struct usb2_com_softc *ucom, uint8_t onoff)
516{
517 struct uplcom_softc *sc = ucom->sc_parent;
518 struct usb2_device_request req;
519

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

526
527 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
528 req.bRequest = UCDC_SET_CONTROL_LINE_STATE;
529 USETW(req.wValue, sc->sc_line);
530 req.wIndex[0] = sc->sc_data_iface_no;
531 req.wIndex[1] = 0;
532 USETW(req.wLength, 0);
533
579 uplcom_cfg_do_request(sc, &req, NULL);
534 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
535 &req, NULL, 0, 1000);
580}
581
582static void
583uplcom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
584{
585 struct uplcom_softc *sc = ucom->sc_parent;
586 struct usb2_device_request req;
587 uint16_t temp;

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

592
593 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
594 req.bRequest = UCDC_SEND_BREAK;
595 USETW(req.wValue, temp);
596 req.wIndex[0] = sc->sc_data_iface_no;
597 req.wIndex[1] = 0;
598 USETW(req.wLength, 0);
599
536}
537
538static void
539uplcom_cfg_set_break(struct usb2_com_softc *ucom, uint8_t onoff)
540{
541 struct uplcom_softc *sc = ucom->sc_parent;
542 struct usb2_device_request req;
543 uint16_t temp;

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

548
549 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
550 req.bRequest = UCDC_SEND_BREAK;
551 USETW(req.wValue, temp);
552 req.wIndex[0] = sc->sc_data_iface_no;
553 req.wIndex[1] = 0;
554 USETW(req.wLength, 0);
555
600 uplcom_cfg_do_request(sc, &req, NULL);
556 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
557 &req, NULL, 0, 1000);
601}
602
603static const int32_t uplcom_rates[] = {
604 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400,
605 19200, 28800, 38400, 57600, 115200,
606 /*
607 * Higher speeds are probably possible. PL2303X supports up to
608 * 6Mb and can set any rate

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

686
687 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
688 req.bRequest = UCDC_SET_LINE_CODING;
689 USETW(req.wValue, 0);
690 req.wIndex[0] = sc->sc_data_iface_no;
691 req.wIndex[1] = 0;
692 USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
693
558}
559
560static const int32_t uplcom_rates[] = {
561 75, 150, 300, 600, 1200, 1800, 2400, 3600, 4800, 7200, 9600, 14400,
562 19200, 28800, 38400, 57600, 115200,
563 /*
564 * Higher speeds are probably possible. PL2303X supports up to
565 * 6Mb and can set any rate

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

643
644 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
645 req.bRequest = UCDC_SET_LINE_CODING;
646 USETW(req.wValue, 0);
647 req.wIndex[0] = sc->sc_data_iface_no;
648 req.wIndex[1] = 0;
649 USETW(req.wLength, UCDC_LINE_STATE_LENGTH);
650
694 uplcom_cfg_do_request(sc, &req, &ls);
651 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
652 &req, &ls, 0, 1000);
695
696 if (t->c_cflag & CRTSCTS) {
697
698 DPRINTF("crtscts = on\n");
699
700 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
701 req.bRequest = UPLCOM_SET_REQUEST;
702 USETW(req.wValue, 0);
703 if (sc->sc_chiptype == TYPE_PL2303X)
704 USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
705 else
706 USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
707 USETW(req.wLength, 0);
708
653
654 if (t->c_cflag & CRTSCTS) {
655
656 DPRINTF("crtscts = on\n");
657
658 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
659 req.bRequest = UPLCOM_SET_REQUEST;
660 USETW(req.wValue, 0);
661 if (sc->sc_chiptype == TYPE_PL2303X)
662 USETW(req.wIndex, UPLCOM_SET_CRTSCTS_PL2303X);
663 else
664 USETW(req.wIndex, UPLCOM_SET_CRTSCTS);
665 USETW(req.wLength, 0);
666
709 uplcom_cfg_do_request(sc, &req, NULL);
667 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
668 &req, NULL, 0, 1000);
710 } else {
711 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
712 req.bRequest = UPLCOM_SET_REQUEST;
713 USETW(req.wValue, 0);
714 USETW(req.wIndex, 0);
715 USETW(req.wLength, 0);
669 } else {
670 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
671 req.bRequest = UPLCOM_SET_REQUEST;
672 USETW(req.wValue, 0);
673 USETW(req.wIndex, 0);
674 USETW(req.wLength, 0);
716 uplcom_cfg_do_request(sc, &req, NULL);
675 usb2_com_cfg_do_request(sc->sc_udev, &sc->sc_ucom,
676 &req, NULL, 0, 1000);
717 }
718}
719
720static void
721uplcom_start_read(struct usb2_com_softc *ucom)
722{
723 struct uplcom_softc *sc = ucom->sc_parent;
724

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

733uplcom_stop_read(struct usb2_com_softc *ucom)
734{
735 struct uplcom_softc *sc = ucom->sc_parent;
736
737 /* stop interrupt endpoint */
738 usb2_transfer_stop(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
739
740 /* stop read endpoint */
677 }
678}
679
680static void
681uplcom_start_read(struct usb2_com_softc *ucom)
682{
683 struct uplcom_softc *sc = ucom->sc_parent;
684

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

693uplcom_stop_read(struct usb2_com_softc *ucom)
694{
695 struct uplcom_softc *sc = ucom->sc_parent;
696
697 /* stop interrupt endpoint */
698 usb2_transfer_stop(sc->sc_xfer[UPLCOM_INTR_DT_RD]);
699
700 /* stop read endpoint */
741 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
742 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
743}
744
745static void
746uplcom_start_write(struct usb2_com_softc *ucom)
747{
748 struct uplcom_softc *sc = ucom->sc_parent;
749
750 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
751}
752
753static void
754uplcom_stop_write(struct usb2_com_softc *ucom)
755{
756 struct uplcom_softc *sc = ucom->sc_parent;
757
701 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_RD]);
702}
703
704static void
705uplcom_start_write(struct usb2_com_softc *ucom)
706{
707 struct uplcom_softc *sc = ucom->sc_parent;
708
709 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
710}
711
712static void
713uplcom_stop_write(struct usb2_com_softc *ucom)
714{
715 struct uplcom_softc *sc = ucom->sc_parent;
716
758 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
759 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
760}
761
762static void
763uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
764{
765 struct uplcom_softc *sc = ucom->sc_parent;
766

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

797 sc->sc_msr |= SER_DSR;
798 }
799 if (buf[8] & RSAQ_STATUS_DCD) {
800 sc->sc_msr |= SER_DCD;
801 }
802 usb2_com_status_change(&sc->sc_ucom);
803 }
804 case USB_ST_SETUP:
717 usb2_transfer_stop(sc->sc_xfer[UPLCOM_BULK_DT_WR]);
718}
719
720static void
721uplcom_cfg_get_status(struct usb2_com_softc *ucom, uint8_t *lsr, uint8_t *msr)
722{
723 struct uplcom_softc *sc = ucom->sc_parent;
724

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

755 sc->sc_msr |= SER_DSR;
756 }
757 if (buf[8] & RSAQ_STATUS_DCD) {
758 sc->sc_msr |= SER_DCD;
759 }
760 usb2_com_status_change(&sc->sc_ucom);
761 }
762 case USB_ST_SETUP:
805 if (sc->sc_flag & UPLCOM_FLAG_INTR_STALL) {
806 usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]);
807 } else {
808 xfer->frlengths[0] = xfer->max_data_length;
809 usb2_start_hardware(xfer);
810 }
763tr_setup:
764 xfer->frlengths[0] = xfer->max_data_length;
765 usb2_start_hardware(xfer);
811 return;
812
813 default: /* Error */
814 if (xfer->error != USB_ERR_CANCELLED) {
766 return;
767
768 default: /* Error */
769 if (xfer->error != USB_ERR_CANCELLED) {
815 sc->sc_flag |= UPLCOM_FLAG_INTR_STALL;
816 usb2_transfer_start(sc->sc_xfer[UPLCOM_INTR_CS_RD]);
770 /* try to clear stall first */
771 xfer->flags.stall_pipe = 1;
772 goto tr_setup;
817 }
818 return;
773 }
774 return;
819
820 }
821}
822
823static void
775 }
776}
777
778static void
824uplcom_intr_clear_stall_callback(struct usb2_xfer *xfer)
825{
826 struct uplcom_softc *sc = xfer->priv_sc;
827 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_INTR_DT_RD];
828
829 if (usb2_clear_stall_callback(xfer, xfer_other)) {
830 DPRINTF("stall cleared\n");
831 sc->sc_flag &= ~UPLCOM_FLAG_INTR_STALL;
832 usb2_transfer_start(xfer_other);
833 }
834}
835
836static void
837uplcom_write_callback(struct usb2_xfer *xfer)
838{
839 struct uplcom_softc *sc = xfer->priv_sc;
840 uint32_t actlen;
841
842 switch (USB_GET_STATE(xfer)) {
843 case USB_ST_SETUP:
844 case USB_ST_TRANSFERRED:
779uplcom_write_callback(struct usb2_xfer *xfer)
780{
781 struct uplcom_softc *sc = xfer->priv_sc;
782 uint32_t actlen;
783
784 switch (USB_GET_STATE(xfer)) {
785 case USB_ST_SETUP:
786 case USB_ST_TRANSFERRED:
845 if (sc->sc_flag & UPLCOM_FLAG_WRITE_STALL) {
846 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
847 return;
848 }
787tr_setup:
849 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
850 UPLCOM_BULK_BUF_SIZE, &actlen)) {
851
852 DPRINTF("actlen = %d\n", actlen);
853
854 xfer->frlengths[0] = actlen;
855 usb2_start_hardware(xfer);
856 }
857 return;
858
859 default: /* Error */
860 if (xfer->error != USB_ERR_CANCELLED) {
788 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
789 UPLCOM_BULK_BUF_SIZE, &actlen)) {
790
791 DPRINTF("actlen = %d\n", actlen);
792
793 xfer->frlengths[0] = actlen;
794 usb2_start_hardware(xfer);
795 }
796 return;
797
798 default: /* Error */
799 if (xfer->error != USB_ERR_CANCELLED) {
861 sc->sc_flag |= UPLCOM_FLAG_WRITE_STALL;
862 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_WR]);
800 /* try to clear stall first */
801 xfer->flags.stall_pipe = 1;
802 goto tr_setup;
863 }
864 return;
803 }
804 return;
865
866 }
867}
868
869static void
805 }
806}
807
808static void
870uplcom_write_clear_stall_callback(struct usb2_xfer *xfer)
871{
872 struct uplcom_softc *sc = xfer->priv_sc;
873 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_WR];
874
875 if (usb2_clear_stall_callback(xfer, xfer_other)) {
876 DPRINTF("stall cleared\n");
877 sc->sc_flag &= ~UPLCOM_FLAG_WRITE_STALL;
878 usb2_transfer_start(xfer_other);
879 }
880}
881
882static void
883uplcom_read_callback(struct usb2_xfer *xfer)
884{
885 struct uplcom_softc *sc = xfer->priv_sc;
886
887 switch (USB_GET_STATE(xfer)) {
888 case USB_ST_TRANSFERRED:
889 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
890
891 case USB_ST_SETUP:
809uplcom_read_callback(struct usb2_xfer *xfer)
810{
811 struct uplcom_softc *sc = xfer->priv_sc;
812
813 switch (USB_GET_STATE(xfer)) {
814 case USB_ST_TRANSFERRED:
815 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
816
817 case USB_ST_SETUP:
892 if (sc->sc_flag & UPLCOM_FLAG_READ_STALL) {
893 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
894 } else {
895 xfer->frlengths[0] = xfer->max_data_length;
896 usb2_start_hardware(xfer);
897 }
818tr_setup:
819 xfer->frlengths[0] = xfer->max_data_length;
820 usb2_start_hardware(xfer);
898 return;
899
900 default: /* Error */
901 if (xfer->error != USB_ERR_CANCELLED) {
821 return;
822
823 default: /* Error */
824 if (xfer->error != USB_ERR_CANCELLED) {
902 sc->sc_flag |= UPLCOM_FLAG_READ_STALL;
903 usb2_transfer_start(sc->sc_xfer[UPLCOM_BULK_CS_RD]);
825 /* try to clear stall first */
826 xfer->flags.stall_pipe = 1;
827 goto tr_setup;
904 }
905 return;
828 }
829 return;
906
907 }
908}
830 }
831}
909
910static void
911uplcom_read_clear_stall_callback(struct usb2_xfer *xfer)
912{
913 struct uplcom_softc *sc = xfer->priv_sc;
914 struct usb2_xfer *xfer_other = sc->sc_xfer[UPLCOM_BULK_DT_RD];
915
916 if (usb2_clear_stall_callback(xfer, xfer_other)) {
917 DPRINTF("stall cleared\n");
918 sc->sc_flag &= ~UPLCOM_FLAG_READ_STALL;
919 usb2_transfer_start(xfer_other);
920 }
921}
922
923static void
924uplcom_cfg_do_request(struct uplcom_softc *sc, struct usb2_device_request *req,
925 void *data)
926{
927 uint16_t length;
928 usb2_error_t err;
929
930 if (usb2_com_cfg_is_gone(&sc->sc_ucom)) {
931 goto error;
932 }
933 err = usb2_do_request_flags(sc->sc_udev, &Giant, req,
934 data, 0, NULL, 1000);
935
936 if (err) {
937
938 DPRINTFN(0, "device request failed, err=%s "
939 "(ignored)\n", usb2_errstr(err));
940
941error:
942 length = UGETW(req->wLength);
943
944 if ((req->bmRequestType & UT_READ) && length) {
945 bzero(data, length);
946 }
947 }
948}