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