diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c index c0cd54bb7..cd80c3201 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; diff --git a/src/drivers/usb/ehci.c b/src/drivers/usb/ehci.c index 4124692a6..0a89ec133 100644 --- a/src/drivers/usb/ehci.c +++ b/src/drivers/usb/ehci.c @@ -1223,11 +1223,11 @@ static int ehci_endpoint_message ( struct usb_endpoint *ep, * * @v ep USB endpoint * @v iobuf I/O buffer - * @v terminate Terminate using a short packet + * @v zlp Append a zero-length packet * @ret rc Return status code */ static int ehci_endpoint_stream ( struct usb_endpoint *ep, - struct io_buffer *iobuf, int terminate ) { + struct io_buffer *iobuf, int zlp ) { struct ehci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep ); struct ehci_device *ehci = endpoint->ehci; unsigned int input = ( ep->address & USB_DIR_IN ); @@ -1242,7 +1242,7 @@ static int ehci_endpoint_stream ( struct usb_endpoint *ep, xfer->flags = ( EHCI_FL_IOC | ( input ? EHCI_FL_PID_IN : EHCI_FL_PID_OUT ) ); xfer++; - if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) { + if ( zlp ) { xfer->data = NULL; xfer->len = 0; assert ( ! input ); diff --git a/src/drivers/usb/uhci.c b/src/drivers/usb/uhci.c index b6bb92560..4220bef72 100644 --- a/src/drivers/usb/uhci.c +++ b/src/drivers/usb/uhci.c @@ -835,22 +835,20 @@ static int uhci_endpoint_message ( struct usb_endpoint *ep, * * @v ep USB endpoint * @v iobuf I/O buffer - * @v terminate Terminate using a short packet + * @v zlp Append a zero-length packet * @ret rc Return status code */ static int uhci_endpoint_stream ( struct usb_endpoint *ep, - struct io_buffer *iobuf, int terminate ) { + struct io_buffer *iobuf, int zlp ) { struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep ); struct uhci_ring *ring = &endpoint->ring; unsigned int count; size_t len; int input; - int zlp; int rc; /* Calculate number of descriptors */ len = iob_len ( iobuf ); - zlp = ( terminate && ( ( len & ( ring->mtu - 1 ) ) == 0 ) ); count = ( ( ( len + ring->mtu - 1 ) / ring->mtu ) + ( zlp ? 1 : 0 ) ); /* Enqueue transfer */ diff --git a/src/drivers/usb/usbio.c b/src/drivers/usb/usbio.c index 70aa50951..a80f7c8fc 100644 --- a/src/drivers/usb/usbio.c +++ b/src/drivers/usb/usbio.c @@ -1005,17 +1005,14 @@ static int usbio_endpoint_message ( struct usb_endpoint *ep, * * @v ep USB endpoint * @v iobuf I/O buffer - * @v terminate Terminate using a short packet + * @v zlp Append a zero-length packet * @ret rc Return status code */ static int usbio_endpoint_stream ( struct usb_endpoint *ep, - struct io_buffer *iobuf, int terminate ) { - size_t len = iob_len ( iobuf ); - int zlen; + struct io_buffer *iobuf, int zlp ) { /* Enqueue transfer */ - zlen = ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ); - return usbio_endpoint_enqueue ( ep, iobuf, ( zlen ? USBIO_ZLEN : 0 ) ); + return usbio_endpoint_enqueue ( ep, iobuf, ( zlp ? USBIO_ZLEN : 0 ) ); } /** diff --git a/src/drivers/usb/xhci.c b/src/drivers/usb/xhci.c index 49e67316b..f0f8eb1d9 100644 --- a/src/drivers/usb/xhci.c +++ b/src/drivers/usb/xhci.c @@ -2546,11 +2546,11 @@ static int xhci_endpoint_message ( struct usb_endpoint *ep, * * @v ep USB endpoint * @v iobuf I/O buffer - * @v terminate Terminate using a short packet + * @v zlp Append a zero-length packet * @ret rc Return status code */ static int xhci_endpoint_stream ( struct usb_endpoint *ep, - struct io_buffer *iobuf, int terminate ) { + struct io_buffer *iobuf, int zlp ) { struct xhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep ); union xhci_trb trbs[ 1 /* Normal */ + 1 /* Possible zero-length */ ]; union xhci_trb *trb = trbs; @@ -2567,7 +2567,7 @@ static int xhci_endpoint_stream ( struct usb_endpoint *ep, normal->data = cpu_to_le64 ( virt_to_phys ( iobuf->data ) ); normal->len = cpu_to_le32 ( len ); normal->type = XHCI_TRB_NORMAL; - if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) { + if ( zlp ) { normal->flags = XHCI_TRB_CH; normal = &(trb++)->normal; normal->type = XHCI_TRB_NORMAL; diff --git a/src/include/ipxe/usb.h b/src/include/ipxe/usb.h index dfe0f3482..0640f9e38 100644 --- a/src/include/ipxe/usb.h +++ b/src/include/ipxe/usb.h @@ -458,11 +458,11 @@ struct usb_endpoint_host_operations { * * @v ep USB endpoint * @v iobuf I/O buffer - * @v terminate Terminate using a short packet + * @v zlp Append a zero-length packet * @ret rc Return status code */ int ( * stream ) ( struct usb_endpoint *ep, struct io_buffer *iobuf, - int terminate ); + int zlp ); }; /** USB endpoint driver operations */