Skip to content

Commit 28d85db

Browse files
committed
xhci: Do not drop and add bits in xhci
Drop and Add bits reset the data toggle for high-speed devices in XHCI. The toggle bit represents the sequence number in USB 2.0 transfers. However, a device can only recognize that the toggle bit has been reset while in the HALT state. As a result, the host and device toggle values may become mismatched, causing xHCI to reject the packet. This issue was observed while testing the EZ-USB FX2 device. The transfer may then return to the original value after a bi-directional TD because the toggle field is only one bit wide. This explains the reson that we can only receive packets bi-transfer in some case. Therefore, we do not reset the toggle bit here. Reviewed by: adrian MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D57146
1 parent 0c85df0 commit 28d85db

1 file changed

Lines changed: 9 additions & 5 deletions

File tree

sys/dev/usb/controller/xhci.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,10 +3898,8 @@ xhci_configure_reset_endpoint(struct usb_xfer *xfer)
38983898
*/
38993899
switch (xhci_get_endpoint_state(udev, epno)) {
39003900
case XHCI_EPCTX_0_EPSTATE_DISABLED:
3901-
drop = 0;
3902-
break;
39033901
case XHCI_EPCTX_0_EPSTATE_STOPPED:
3904-
drop = 1;
3902+
drop = 0;
39053903
break;
39063904
case XHCI_EPCTX_0_EPSTATE_HALTED:
39073905
err = xhci_cmd_reset_ep(sc, 0, epno, index);
@@ -3910,9 +3908,15 @@ xhci_configure_reset_endpoint(struct usb_xfer *xfer)
39103908
DPRINTF("Could not reset endpoint %u\n", epno);
39113909
break;
39123910
default:
3913-
drop = 1;
3911+
/*
3912+
* xHCI spec 4.6.8:
3913+
* The Drop and Add operation resets the toggle bit, which can
3914+
* cause a toggle mismatch between the device and host. As a
3915+
* result, xHCI may refuse to receive or process the packet.
3916+
*/
39143917
err = xhci_cmd_stop_ep(sc, 0, epno, index);
3915-
if (err != 0)
3918+
drop = (err != 0);
3919+
if (drop)
39163920
DPRINTF("Could not stop endpoint %u\n", epno);
39173921
break;
39183922
}

0 commit comments

Comments
 (0)