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