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 --- |