diff options
author | Michael Brown <mcb30@ipxe.org> | 2015-09-13 00:49:56 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2015-09-13 12:54:30 +0100 |
commit | f9e192605c7095497438398c2653ede3c78ebe1b (patch) | |
tree | 10ee45b16836a8e4bebbce1eb0d506bb98d29620 /src/drivers | |
parent | 8baefad65915defc493f28c6d8ac313b1152c858 (diff) | |
download | ipxe-f9e192605c7095497438398c2653ede3c78ebe1b.zip ipxe-f9e192605c7095497438398c2653ede3c78ebe1b.tar.gz ipxe-f9e192605c7095497438398c2653ede3c78ebe1b.tar.bz2 |
[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')
-rw-r--r-- | src/drivers/bus/usb.c | 8 | ||||
-rw-r--r-- | src/drivers/usb/ehci.c | 6 | ||||
-rw-r--r-- | src/drivers/usb/uhci.c | 6 | ||||
-rw-r--r-- | src/drivers/usb/usbio.c | 9 | ||||
-rw-r--r-- | src/drivers/usb/xhci.c | 6 |
5 files changed, 18 insertions, 17 deletions
diff --git a/src/drivers/bus/usb.c b/src/drivers/bus/usb.c index c0cd54b..cd80c32 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 4124692..0a89ec1 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 b6bb925..4220bef 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 70aa509..a80f7c8 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 49e6731..f0f8eb1 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; |