summaryrefslogtreecommitdiffstats
path: root/src/drivers/bus
diff options
context:
space:
mode:
authorMichael Brown2015-09-13 01:49:56 +0200
committerMichael Brown2015-09-13 13:54:30 +0200
commitf9e192605c7095497438398c2653ede3c78ebe1b (patch)
tree10ee45b16836a8e4bebbce1eb0d506bb98d29620 /src/drivers/bus
parent[tcpip] Avoid generating positive zero for transmitted UDP checksums (diff)
downloadipxe-f9e192605c7095497438398c2653ede3c78ebe1b.tar.gz
ipxe-f9e192605c7095497438398c2653ede3c78ebe1b.tar.xz
ipxe-f9e192605c7095497438398c2653ede3c78ebe1b.zip
[usb] Generalise zero-length packet generation logic
The decision on whether or not a zero-length packet needs to be transmitted is independent of the host controller and belongs in the USB core. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/bus')
-rw-r--r--src/drivers/bus/usb.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c
index c0cd54bb..cd80c320 100644
--- a/src/drivers/bus/usb.c
+++ b/src/drivers/bus/usb.c
@@ -530,6 +530,7 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
int terminate ) {
struct usb_device *usb = ep->usb;
struct usb_port *port = usb->port;
+ int zlp;
int rc;
/* Fail immediately if device has been unplugged */
@@ -541,8 +542,13 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
return rc;
+ /* Append a zero-length packet if necessary */
+ zlp = terminate;
+ if ( iob_len ( iobuf ) & ( ep->mtu - 1 ) )
+ zlp = 0;
+
/* Enqueue stream transfer */
- if ( ( rc = ep->host->stream ( ep, iobuf, terminate ) ) != 0 ) {
+ if ( ( rc = ep->host->stream ( ep, iobuf, zlp ) ) != 0 ) {
DBGC ( usb, "USB %s %s could not enqueue stream transfer: %s\n",
usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
return rc;