diff options
author | Michael Brown | 2015-09-13 01:49:56 +0200 |
---|---|---|
committer | Michael Brown | 2015-09-13 13:54:30 +0200 |
commit | f9e192605c7095497438398c2653ede3c78ebe1b (patch) | |
tree | 10ee45b16836a8e4bebbce1eb0d506bb98d29620 /src/drivers/bus | |
parent | [tcpip] Avoid generating positive zero for transmitted UDP checksums (diff) | |
download | ipxe-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.c | 8 |
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; |