Deleted Added
full compact
uchcom.c (187970) uchcom.c (188413)
1/* $NetBSD: uchcom.c,v 1.1 2007/09/03 17:57:37 tshiozak Exp $ */
2
3/*-
4 * Copyright (c) 2007, Takanori Watanabe
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#include <sys/cdefs.h>
1/* $NetBSD: uchcom.c,v 1.1 2007/09/03 17:57:37 tshiozak Exp $ */
2
3/*-
4 * Copyright (c) 2007, Takanori Watanabe
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#include <sys/cdefs.h>
66__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uchcom2.c 187970 2009-02-01 00:51:25Z thompsa $");
66__FBSDID("$FreeBSD: head/sys/dev/usb2/serial/uchcom2.c 188413 2009-02-09 22:05:25Z thompsa $");
67
68/*
69 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
70 */
71
72#include <dev/usb2/include/usb2_devid.h>
73#include <dev/usb2/include/usb2_standard.h>
74#include <dev/usb2/include/usb2_mfunc.h>

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

143#define UCHCOM_INTR_STAT2 0x03
144#define UCHCOM_INTR_LEAST 4
145
146#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */
147
148enum {
149 UCHCOM_BULK_DT_WR,
150 UCHCOM_BULK_DT_RD,
67
68/*
69 * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
70 */
71
72#include <dev/usb2/include/usb2_devid.h>
73#include <dev/usb2/include/usb2_standard.h>
74#include <dev/usb2/include/usb2_mfunc.h>

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

143#define UCHCOM_INTR_STAT2 0x03
144#define UCHCOM_INTR_LEAST 4
145
146#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */
147
148enum {
149 UCHCOM_BULK_DT_WR,
150 UCHCOM_BULK_DT_RD,
151 UCHCOM_BULK_CS_WR,
152 UCHCOM_BULK_CS_RD,
153 UCHCOM_INTR_DT_RD,
151 UCHCOM_INTR_DT_RD,
154 UCHCOM_INTR_CS_RD,
155 UCHCOM_N_TRANSFER = 6,
152 UCHCOM_N_TRANSFER,
156};
157
158struct uchcom_softc {
159 struct usb2_com_super_softc sc_super_ucom;
160 struct usb2_com_softc sc_ucom;
161
162 struct usb2_xfer *sc_xfer[UCHCOM_N_TRANSFER];
163 struct usb2_device *sc_udev;
164
165 uint8_t sc_dtr; /* local copy */
166 uint8_t sc_rts; /* local copy */
167 uint8_t sc_version;
168 uint8_t sc_msr;
169 uint8_t sc_lsr; /* local status register */
153};
154
155struct uchcom_softc {
156 struct usb2_com_super_softc sc_super_ucom;
157 struct usb2_com_softc sc_ucom;
158
159 struct usb2_xfer *sc_xfer[UCHCOM_N_TRANSFER];
160 struct usb2_device *sc_udev;
161
162 uint8_t sc_dtr; /* local copy */
163 uint8_t sc_rts; /* local copy */
164 uint8_t sc_version;
165 uint8_t sc_msr;
166 uint8_t sc_lsr; /* local status register */
170 uint8_t sc_flag;
171#define UCHCOM_FLAG_INTR_STALL 0x01
172#define UCHCOM_FLAG_READ_STALL 0x02
173#define UCHCOM_FLAG_WRITE_STALL 0x04
174};
175
176struct uchcom_divider {
177 uint8_t dv_prescaler;
178 uint8_t dv_div;
179 uint8_t dv_mod;
180};
181

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

225static void uchcom_clear_chip(struct uchcom_softc *);
226static void uchcom_reset_chip(struct uchcom_softc *);
227
228static device_probe_t uchcom_probe;
229static device_attach_t uchcom_attach;
230static device_detach_t uchcom_detach;
231
232static usb2_callback_t uchcom_intr_callback;
167};
168
169struct uchcom_divider {
170 uint8_t dv_prescaler;
171 uint8_t dv_div;
172 uint8_t dv_mod;
173};
174

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

218static void uchcom_clear_chip(struct uchcom_softc *);
219static void uchcom_reset_chip(struct uchcom_softc *);
220
221static device_probe_t uchcom_probe;
222static device_attach_t uchcom_attach;
223static device_detach_t uchcom_detach;
224
225static usb2_callback_t uchcom_intr_callback;
233static usb2_callback_t uchcom_intr_clear_stall_callback;
234static usb2_callback_t uchcom_write_callback;
226static usb2_callback_t uchcom_write_callback;
235static usb2_callback_t uchcom_write_clear_stall_callback;
236static usb2_callback_t uchcom_read_callback;
227static usb2_callback_t uchcom_read_callback;
237static usb2_callback_t uchcom_read_clear_stall_callback;
238
239static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
240
241 [UCHCOM_BULK_DT_WR] = {
242 .type = UE_BULK,
243 .endpoint = UE_ADDR_ANY,
244 .direction = UE_DIR_OUT,
245 .mh.bufsize = UCHCOM_BULK_BUF_SIZE,

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

251 .type = UE_BULK,
252 .endpoint = UE_ADDR_ANY,
253 .direction = UE_DIR_IN,
254 .mh.bufsize = UCHCOM_BULK_BUF_SIZE,
255 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
256 .mh.callback = &uchcom_read_callback,
257 },
258
228
229static const struct usb2_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
230
231 [UCHCOM_BULK_DT_WR] = {
232 .type = UE_BULK,
233 .endpoint = UE_ADDR_ANY,
234 .direction = UE_DIR_OUT,
235 .mh.bufsize = UCHCOM_BULK_BUF_SIZE,

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

241 .type = UE_BULK,
242 .endpoint = UE_ADDR_ANY,
243 .direction = UE_DIR_IN,
244 .mh.bufsize = UCHCOM_BULK_BUF_SIZE,
245 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
246 .mh.callback = &uchcom_read_callback,
247 },
248
259 [UCHCOM_BULK_CS_WR] = {
260 .type = UE_CONTROL,
261 .endpoint = 0x00, /* Control pipe */
262 .direction = UE_DIR_ANY,
263 .mh.bufsize = sizeof(struct usb2_device_request),
264 .mh.callback = &uchcom_write_clear_stall_callback,
265 .mh.timeout = 1000, /* 1 second */
266 .mh.interval = 50, /* 50ms */
267 },
268
269 [UCHCOM_BULK_CS_RD] = {
270 .type = UE_CONTROL,
271 .endpoint = 0x00, /* Control pipe */
272 .direction = UE_DIR_ANY,
273 .mh.bufsize = sizeof(struct usb2_device_request),
274 .mh.callback = &uchcom_read_clear_stall_callback,
275 .mh.timeout = 1000, /* 1 second */
276 .mh.interval = 50, /* 50ms */
277 },
278
279 [UCHCOM_INTR_DT_RD] = {
280 .type = UE_INTERRUPT,
281 .endpoint = UE_ADDR_ANY,
282 .direction = UE_DIR_IN,
283 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
284 .mh.bufsize = 0, /* use wMaxPacketSize */
285 .mh.callback = &uchcom_intr_callback,
286 },
249 [UCHCOM_INTR_DT_RD] = {
250 .type = UE_INTERRUPT,
251 .endpoint = UE_ADDR_ANY,
252 .direction = UE_DIR_IN,
253 .mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
254 .mh.bufsize = 0, /* use wMaxPacketSize */
255 .mh.callback = &uchcom_intr_callback,
256 },
287
288 [UCHCOM_INTR_CS_RD] = {
289 .type = UE_CONTROL,
290 .endpoint = 0x00, /* Control pipe */
291 .direction = UE_DIR_ANY,
292 .mh.bufsize = sizeof(struct usb2_device_request),
293 .mh.callback = &uchcom_intr_clear_stall_callback,
294 .mh.timeout = 1000, /* 1 second */
295 .mh.interval = 50, /* 50ms */
296 },
297};
298
299struct usb2_com_callback uchcom_callback = {
300 .usb2_com_cfg_get_status = &uchcom_cfg_get_status,
301 .usb2_com_cfg_set_dtr = &uchcom_cfg_set_dtr,
302 .usb2_com_cfg_set_rts = &uchcom_cfg_set_rts,
303 .usb2_com_cfg_set_break = &uchcom_cfg_set_break,
304 .usb2_com_cfg_param = &uchcom_cfg_param,

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

373 uchcom_clear_chip(sc);
374 uchcom_reset_chip(sc);
375 uchcom_update_status(sc);
376
377 sc->sc_dtr = 1;
378 sc->sc_rts = 1;
379
380 /* clear stall at first run */
257};
258
259struct usb2_com_callback uchcom_callback = {
260 .usb2_com_cfg_get_status = &uchcom_cfg_get_status,
261 .usb2_com_cfg_set_dtr = &uchcom_cfg_set_dtr,
262 .usb2_com_cfg_set_rts = &uchcom_cfg_set_rts,
263 .usb2_com_cfg_set_break = &uchcom_cfg_set_break,
264 .usb2_com_cfg_param = &uchcom_cfg_param,

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

333 uchcom_clear_chip(sc);
334 uchcom_reset_chip(sc);
335 uchcom_update_status(sc);
336
337 sc->sc_dtr = 1;
338 sc->sc_rts = 1;
339
340 /* clear stall at first run */
381 sc->sc_flag |= (UCHCOM_FLAG_READ_STALL |
382 UCHCOM_FLAG_WRITE_STALL);
341 usb2_transfer_set_stall(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
342 usb2_transfer_set_stall(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
383
384 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
385 &uchcom_callback, &Giant);
386 if (error) {
387 goto detach;
388 }
389 return (0);
390

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

407 return (0);
408}
409
410/* ----------------------------------------------------------------------
411 * low level i/o
412 */
413
414static void
343
344 error = usb2_com_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc,
345 &uchcom_callback, &Giant);
346 if (error) {
347 goto detach;
348 }
349 return (0);
350

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

367 return (0);
368}
369
370/* ----------------------------------------------------------------------
371 * low level i/o
372 */
373
374static void
415uchcom_do_request(struct uchcom_softc *sc,
416 struct usb2_device_request *req, void *data)
417{
418 uint16_t length;
419 uint16_t actlen;
420 usb2_error_t err;
421
422 length = UGETW(req->wLength);
423 actlen = 0;
424
425 if (usb2_com_cfg_is_gone(&sc->sc_ucom)) {
426 goto done;
427 }
428 err = usb2_do_request_flags(sc->sc_udev, &Giant, req,
429 data, USB_SHORT_XFER_OK, &actlen, 1000);
430
431 if (err) {
432 DPRINTFN(0, "device request failed, err=%s "
433 "(ignored)\n", usb2_errstr(err));
434 }
435done:
436 if (length != actlen) {
437 if (req->bmRequestType & UT_READ) {
438 bzero(USB_ADD_BYTES(data, actlen), length - actlen);
439 }
440 }
441}
442
443static void
444uchcom_ctrl_write(struct uchcom_softc *sc, uint8_t reqno,
445 uint16_t value, uint16_t index)
446{
447 struct usb2_device_request req;
448
449 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
450 req.bRequest = reqno;
451 USETW(req.wValue, value);
452 USETW(req.wIndex, index);
453 USETW(req.wLength, 0);
454
375uchcom_ctrl_write(struct uchcom_softc *sc, uint8_t reqno,
376 uint16_t value, uint16_t index)
377{
378 struct usb2_device_request req;
379
380 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
381 req.bRequest = reqno;
382 USETW(req.wValue, value);
383 USETW(req.wIndex, index);
384 USETW(req.wLength, 0);
385
455 uchcom_do_request(sc, &req, NULL);
386 usb2_com_cfg_do_request(sc->sc_udev,
387 &sc->sc_ucom, &req, NULL, 0, 1000);
456}
457
458static void
459uchcom_ctrl_read(struct uchcom_softc *sc, uint8_t reqno,
460 uint16_t value, uint16_t index, void *buf, uint16_t buflen)
461{
462 struct usb2_device_request req;
463
464 req.bmRequestType = UT_READ_VENDOR_DEVICE;
465 req.bRequest = reqno;
466 USETW(req.wValue, value);
467 USETW(req.wIndex, index);
468 USETW(req.wLength, buflen);
469
388}
389
390static void
391uchcom_ctrl_read(struct uchcom_softc *sc, uint8_t reqno,
392 uint16_t value, uint16_t index, void *buf, uint16_t buflen)
393{
394 struct usb2_device_request req;
395
396 req.bmRequestType = UT_READ_VENDOR_DEVICE;
397 req.bRequest = reqno;
398 USETW(req.wValue, value);
399 USETW(req.wIndex, index);
400 USETW(req.wLength, buflen);
401
470 uchcom_do_request(sc, &req, buf);
402 usb2_com_cfg_do_request(sc->sc_udev,
403 &sc->sc_ucom, &req, buf, USB_SHORT_XFER_OK, 1000);
471}
472
473static void
474uchcom_write_reg(struct uchcom_softc *sc,
475 uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
476{
477 DPRINTF("0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
478 (unsigned)reg1, (unsigned)val1,

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

807uchcom_stop_read(struct usb2_com_softc *ucom)
808{
809 struct uchcom_softc *sc = ucom->sc_parent;
810
811 /* stop interrupt endpoint */
812 usb2_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
813
814 /* stop read endpoint */
404}
405
406static void
407uchcom_write_reg(struct uchcom_softc *sc,
408 uint8_t reg1, uint8_t val1, uint8_t reg2, uint8_t val2)
409{
410 DPRINTF("0x%02X<-0x%02X, 0x%02X<-0x%02X\n",
411 (unsigned)reg1, (unsigned)val1,

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

740uchcom_stop_read(struct usb2_com_softc *ucom)
741{
742 struct uchcom_softc *sc = ucom->sc_parent;
743
744 /* stop interrupt endpoint */
745 usb2_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
746
747 /* stop read endpoint */
815 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
816 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
817}
818
819static void
820uchcom_start_write(struct usb2_com_softc *ucom)
821{
822 struct uchcom_softc *sc = ucom->sc_parent;
823
824 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
825}
826
827static void
828uchcom_stop_write(struct usb2_com_softc *ucom)
829{
830 struct uchcom_softc *sc = ucom->sc_parent;
831
748 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
749}
750
751static void
752uchcom_start_write(struct usb2_com_softc *ucom)
753{
754 struct uchcom_softc *sc = ucom->sc_parent;
755
756 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
757}
758
759static void
760uchcom_stop_write(struct usb2_com_softc *ucom)
761{
762 struct uchcom_softc *sc = ucom->sc_parent;
763
832 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
833 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
834}
835
836/* ----------------------------------------------------------------------
837 * callback when the modem status is changed.
838 */
839static void
840uchcom_intr_callback(struct usb2_xfer *xfer)

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

854 DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n",
855 (unsigned)buf[0], (unsigned)buf[1],
856 (unsigned)buf[2], (unsigned)buf[3]);
857
858 uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);
859 usb2_com_status_change(&sc->sc_ucom);
860 }
861 case USB_ST_SETUP:
764 usb2_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
765}
766
767/* ----------------------------------------------------------------------
768 * callback when the modem status is changed.
769 */
770static void
771uchcom_intr_callback(struct usb2_xfer *xfer)

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

785 DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n",
786 (unsigned)buf[0], (unsigned)buf[1],
787 (unsigned)buf[2], (unsigned)buf[3]);
788
789 uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);
790 usb2_com_status_change(&sc->sc_ucom);
791 }
792 case USB_ST_SETUP:
862 if (sc->sc_flag & UCHCOM_FLAG_INTR_STALL) {
863 usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_CS_RD]);
864 } else {
865 xfer->frlengths[0] = xfer->max_data_length;
866 usb2_start_hardware(xfer);
867 }
793tr_setup:
794 xfer->frlengths[0] = xfer->max_data_length;
795 usb2_start_hardware(xfer);
868 break;
869
870 default: /* Error */
871 if (xfer->error != USB_ERR_CANCELLED) {
796 break;
797
798 default: /* Error */
799 if (xfer->error != USB_ERR_CANCELLED) {
872 sc->sc_flag |= UCHCOM_FLAG_INTR_STALL;
873 usb2_transfer_start(sc->sc_xfer[UCHCOM_INTR_CS_RD]);
800 /* try to clear stall first */
801 xfer->flags.stall_pipe = 1;
802 goto tr_setup;
874 }
875 break;
876 }
877}
878
879static void
803 }
804 break;
805 }
806}
807
808static void
880uchcom_intr_clear_stall_callback(struct usb2_xfer *xfer)
881{
882 struct uchcom_softc *sc = xfer->priv_sc;
883 struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_INTR_DT_RD];
884
885 if (usb2_clear_stall_callback(xfer, xfer_other)) {
886 DPRINTF("stall cleared\n");
887 sc->sc_flag &= ~UCHCOM_FLAG_INTR_STALL;
888 usb2_transfer_start(xfer_other);
889 }
890}
891
892static void
893uchcom_write_callback(struct usb2_xfer *xfer)
894{
895 struct uchcom_softc *sc = xfer->priv_sc;
896 uint32_t actlen;
897
898 switch (USB_GET_STATE(xfer)) {
899 case USB_ST_SETUP:
900 case USB_ST_TRANSFERRED:
809uchcom_write_callback(struct usb2_xfer *xfer)
810{
811 struct uchcom_softc *sc = xfer->priv_sc;
812 uint32_t actlen;
813
814 switch (USB_GET_STATE(xfer)) {
815 case USB_ST_SETUP:
816 case USB_ST_TRANSFERRED:
901 if (sc->sc_flag & UCHCOM_FLAG_WRITE_STALL) {
902 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
903 return;
904 }
817tr_setup:
905 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
906 UCHCOM_BULK_BUF_SIZE, &actlen)) {
907
908 DPRINTF("actlen = %d\n", actlen);
909
910 xfer->frlengths[0] = actlen;
911 usb2_start_hardware(xfer);
912 }
913 return;
914
915 default: /* Error */
916 if (xfer->error != USB_ERR_CANCELLED) {
818 if (usb2_com_get_data(&sc->sc_ucom, xfer->frbuffers, 0,
819 UCHCOM_BULK_BUF_SIZE, &actlen)) {
820
821 DPRINTF("actlen = %d\n", actlen);
822
823 xfer->frlengths[0] = actlen;
824 usb2_start_hardware(xfer);
825 }
826 return;
827
828 default: /* Error */
829 if (xfer->error != USB_ERR_CANCELLED) {
917 sc->sc_flag |= UCHCOM_FLAG_WRITE_STALL;
918 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_WR]);
830 /* try to clear stall first */
831 xfer->flags.stall_pipe = 1;
832 goto tr_setup;
919 }
920 return;
921
922 }
923}
924
925static void
833 }
834 return;
835
836 }
837}
838
839static void
926uchcom_write_clear_stall_callback(struct usb2_xfer *xfer)
927{
928 struct uchcom_softc *sc = xfer->priv_sc;
929 struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_BULK_DT_WR];
930
931 if (usb2_clear_stall_callback(xfer, xfer_other)) {
932 DPRINTF("stall cleared\n");
933 sc->sc_flag &= ~UCHCOM_FLAG_WRITE_STALL;
934 usb2_transfer_start(xfer_other);
935 }
936}
937
938static void
939uchcom_read_callback(struct usb2_xfer *xfer)
940{
941 struct uchcom_softc *sc = xfer->priv_sc;
942
943 switch (USB_GET_STATE(xfer)) {
944 case USB_ST_TRANSFERRED:
945 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
946
947 case USB_ST_SETUP:
840uchcom_read_callback(struct usb2_xfer *xfer)
841{
842 struct uchcom_softc *sc = xfer->priv_sc;
843
844 switch (USB_GET_STATE(xfer)) {
845 case USB_ST_TRANSFERRED:
846 usb2_com_put_data(&sc->sc_ucom, xfer->frbuffers, 0, xfer->actlen);
847
848 case USB_ST_SETUP:
948 if (sc->sc_flag & UCHCOM_FLAG_READ_STALL) {
949 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
950 } else {
951 xfer->frlengths[0] = xfer->max_data_length;
952 usb2_start_hardware(xfer);
953 }
849tr_setup:
850 xfer->frlengths[0] = xfer->max_data_length;
851 usb2_start_hardware(xfer);
954 return;
955
956 default: /* Error */
957 if (xfer->error != USB_ERR_CANCELLED) {
852 return;
853
854 default: /* Error */
855 if (xfer->error != USB_ERR_CANCELLED) {
958 sc->sc_flag |= UCHCOM_FLAG_READ_STALL;
959 usb2_transfer_start(sc->sc_xfer[UCHCOM_BULK_CS_RD]);
856 /* try to clear stall first */
857 xfer->flags.stall_pipe = 1;
858 goto tr_setup;
960 }
961 return;
859 }
860 return;
962
963 }
964}
965
861 }
862}
863
966static void
967uchcom_read_clear_stall_callback(struct usb2_xfer *xfer)
968{
969 struct uchcom_softc *sc = xfer->priv_sc;
970 struct usb2_xfer *xfer_other = sc->sc_xfer[UCHCOM_BULK_DT_RD];
971
972 if (usb2_clear_stall_callback(xfer, xfer_other)) {
973 DPRINTF("stall cleared\n");
974 sc->sc_flag &= ~UCHCOM_FLAG_READ_STALL;
975 usb2_transfer_start(xfer_other);
976 }
977}
978
979static device_method_t uchcom_methods[] = {
980 /* Device interface */
981 DEVMETHOD(device_probe, uchcom_probe),
982 DEVMETHOD(device_attach, uchcom_attach),
983 DEVMETHOD(device_detach, uchcom_detach),
984
985 {0, 0}
986};

--- 12 unchanged lines hidden ---
864static device_method_t uchcom_methods[] = {
865 /* Device interface */
866 DEVMETHOD(device_probe, uchcom_probe),
867 DEVMETHOD(device_attach, uchcom_attach),
868 DEVMETHOD(device_detach, uchcom_detach),
869
870 {0, 0}
871};

--- 12 unchanged lines hidden ---