summaryrefslogtreecommitdiffstats
path: root/src/drivers/usb
diff options
context:
space:
mode:
authorMichael Brown2015-12-07 23:30:27 +0100
committerMichael Brown2015-12-07 23:40:47 +0100
commitee8388ec6950ea596ddb374dcc2abb940db70aea (patch)
tree5d479d9c4fad8f8ddd3fe18a23a30b0d24301d75 /src/drivers/usb
parent[intel] Add INTEL_NO_PHY_RST for I217-LM (diff)
downloadipxe-ee8388ec6950ea596ddb374dcc2abb940db70aea.tar.gz
ipxe-ee8388ec6950ea596ddb374dcc2abb940db70aea.tar.xz
ipxe-ee8388ec6950ea596ddb374dcc2abb940db70aea.zip
[xhci] Ensure that zero-length packets are not part of a TRB chain
Some xHCI controllers (such as qemu's emulated xHCI controller) do not correctly handle zero-length packets that are part of a TRB chain. The zero-length TRB ends up being squashed and does not result in a zero-length packet as seen by the device. Work around this problem by marking the zero-length packet as belonging to a separate transfer descriptor. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/usb')
-rw-r--r--src/drivers/usb/xhci.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/drivers/usb/xhci.c b/src/drivers/usb/xhci.c
index 67de0a83..48ac6a30 100644
--- a/src/drivers/usb/xhci.c
+++ b/src/drivers/usb/xhci.c
@@ -2606,6 +2606,12 @@ static int xhci_endpoint_stream ( struct usb_endpoint *ep,
len -= trb_len;
trb++;
}
+
+ /* Mark zero-length packet (if present) as a separate transfer */
+ if ( zlp && ( count > 1 ) )
+ trb[-2].normal.flags = 0;
+
+ /* Generate completion for final TRB */
trb[-1].normal.flags = XHCI_TRB_IOC;
/* Enqueue TRBs */