Browse Source

[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>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
f9e192605c

+ 7
- 1
src/drivers/bus/usb.c View File

@@ -530,6 +530,7 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
530 530
 		 int terminate ) {
531 531
 	struct usb_device *usb = ep->usb;
532 532
 	struct usb_port *port = usb->port;
533
+	int zlp;
533 534
 	int rc;
534 535
 
535 536
 	/* Fail immediately if device has been unplugged */
@@ -541,8 +542,13 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
541 542
 	     ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
542 543
 		return rc;
543 544
 
545
+	/* Append a zero-length packet if necessary */
546
+	zlp = terminate;
547
+	if ( iob_len ( iobuf ) & ( ep->mtu - 1 ) )
548
+		zlp = 0;
549
+
544 550
 	/* Enqueue stream transfer */
545
-	if ( ( rc = ep->host->stream ( ep, iobuf, terminate ) ) != 0 ) {
551
+	if ( ( rc = ep->host->stream ( ep, iobuf, zlp ) ) != 0 ) {
546 552
 		DBGC ( usb, "USB %s %s could not enqueue stream transfer: %s\n",
547 553
 		       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
548 554
 		return rc;

+ 3
- 3
src/drivers/usb/ehci.c View File

@@ -1223,11 +1223,11 @@ static int ehci_endpoint_message ( struct usb_endpoint *ep,
1223 1223
  *
1224 1224
  * @v ep		USB endpoint
1225 1225
  * @v iobuf		I/O buffer
1226
- * @v terminate		Terminate using a short packet
1226
+ * @v zlp		Append a zero-length packet
1227 1227
  * @ret rc		Return status code
1228 1228
  */
1229 1229
 static int ehci_endpoint_stream ( struct usb_endpoint *ep,
1230
-				  struct io_buffer *iobuf, int terminate ) {
1230
+				  struct io_buffer *iobuf, int zlp ) {
1231 1231
 	struct ehci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
1232 1232
 	struct ehci_device *ehci = endpoint->ehci;
1233 1233
 	unsigned int input = ( ep->address & USB_DIR_IN );
@@ -1242,7 +1242,7 @@ static int ehci_endpoint_stream ( struct usb_endpoint *ep,
1242 1242
 	xfer->flags = ( EHCI_FL_IOC |
1243 1243
 			( input ? EHCI_FL_PID_IN : EHCI_FL_PID_OUT ) );
1244 1244
 	xfer++;
1245
-	if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) {
1245
+	if ( zlp ) {
1246 1246
 		xfer->data = NULL;
1247 1247
 		xfer->len = 0;
1248 1248
 		assert ( ! input );

+ 2
- 4
src/drivers/usb/uhci.c View File

@@ -835,22 +835,20 @@ static int uhci_endpoint_message ( struct usb_endpoint *ep,
835 835
  *
836 836
  * @v ep		USB endpoint
837 837
  * @v iobuf		I/O buffer
838
- * @v terminate		Terminate using a short packet
838
+ * @v zlp		Append a zero-length packet
839 839
  * @ret rc		Return status code
840 840
  */
841 841
 static int uhci_endpoint_stream ( struct usb_endpoint *ep,
842
-				  struct io_buffer *iobuf, int terminate ) {
842
+				  struct io_buffer *iobuf, int zlp ) {
843 843
 	struct uhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
844 844
 	struct uhci_ring *ring = &endpoint->ring;
845 845
 	unsigned int count;
846 846
 	size_t len;
847 847
 	int input;
848
-	int zlp;
849 848
 	int rc;
850 849
 
851 850
 	/* Calculate number of descriptors */
852 851
 	len = iob_len ( iobuf );
853
-	zlp = ( terminate && ( ( len & ( ring->mtu - 1 ) ) == 0 ) );
854 852
 	count = ( ( ( len + ring->mtu - 1 ) / ring->mtu ) + ( zlp ? 1 : 0 ) );
855 853
 
856 854
 	/* Enqueue transfer */

+ 3
- 6
src/drivers/usb/usbio.c View File

@@ -1005,17 +1005,14 @@ static int usbio_endpoint_message ( struct usb_endpoint *ep,
1005 1005
  *
1006 1006
  * @v ep		USB endpoint
1007 1007
  * @v iobuf		I/O buffer
1008
- * @v terminate		Terminate using a short packet
1008
+ * @v zlp		Append a zero-length packet
1009 1009
  * @ret rc		Return status code
1010 1010
  */
1011 1011
 static int usbio_endpoint_stream ( struct usb_endpoint *ep,
1012
-				   struct io_buffer *iobuf, int terminate ) {
1013
-	size_t len = iob_len ( iobuf );
1014
-	int zlen;
1012
+				   struct io_buffer *iobuf, int zlp ) {
1015 1013
 
1016 1014
 	/* Enqueue transfer */
1017
-	zlen = ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) );
1018
-	return usbio_endpoint_enqueue ( ep, iobuf, ( zlen ? USBIO_ZLEN : 0 ) );
1015
+	return usbio_endpoint_enqueue ( ep, iobuf, ( zlp ? USBIO_ZLEN : 0 ) );
1019 1016
 }
1020 1017
 
1021 1018
 /**

+ 3
- 3
src/drivers/usb/xhci.c View File

@@ -2546,11 +2546,11 @@ static int xhci_endpoint_message ( struct usb_endpoint *ep,
2546 2546
  *
2547 2547
  * @v ep		USB endpoint
2548 2548
  * @v iobuf		I/O buffer
2549
- * @v terminate		Terminate using a short packet
2549
+ * @v zlp		Append a zero-length packet
2550 2550
  * @ret rc		Return status code
2551 2551
  */
2552 2552
 static int xhci_endpoint_stream ( struct usb_endpoint *ep,
2553
-				  struct io_buffer *iobuf, int terminate ) {
2553
+				  struct io_buffer *iobuf, int zlp ) {
2554 2554
 	struct xhci_endpoint *endpoint = usb_endpoint_get_hostdata ( ep );
2555 2555
 	union xhci_trb trbs[ 1 /* Normal */ + 1 /* Possible zero-length */ ];
2556 2556
 	union xhci_trb *trb = trbs;
@@ -2567,7 +2567,7 @@ static int xhci_endpoint_stream ( struct usb_endpoint *ep,
2567 2567
 	normal->data = cpu_to_le64 ( virt_to_phys ( iobuf->data ) );
2568 2568
 	normal->len = cpu_to_le32 ( len );
2569 2569
 	normal->type = XHCI_TRB_NORMAL;
2570
-	if ( terminate && ( ( len & ( ep->mtu - 1 ) ) == 0 ) ) {
2570
+	if ( zlp ) {
2571 2571
 		normal->flags = XHCI_TRB_CH;
2572 2572
 		normal = &(trb++)->normal;
2573 2573
 		normal->type = XHCI_TRB_NORMAL;

+ 2
- 2
src/include/ipxe/usb.h View File

@@ -458,11 +458,11 @@ struct usb_endpoint_host_operations {
458 458
 	 *
459 459
 	 * @v ep		USB endpoint
460 460
 	 * @v iobuf		I/O buffer
461
-	 * @v terminate		Terminate using a short packet
461
+	 * @v zlp		Append a zero-length packet
462 462
 	 * @ret rc		Return status code
463 463
 	 */
464 464
 	int ( * stream ) ( struct usb_endpoint *ep, struct io_buffer *iobuf,
465
-			   int terminate );
465
+			   int zlp );
466 466
 };
467 467
 
468 468
 /** USB endpoint driver operations */

Loading…
Cancel
Save