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
 		 int terminate ) {
530
 		 int terminate ) {
531
 	struct usb_device *usb = ep->usb;
531
 	struct usb_device *usb = ep->usb;
532
 	struct usb_port *port = usb->port;
532
 	struct usb_port *port = usb->port;
533
+	int zlp;
533
 	int rc;
534
 	int rc;
534
 
535
 
535
 	/* Fail immediately if device has been unplugged */
536
 	/* Fail immediately if device has been unplugged */
541
 	     ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
542
 	     ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
542
 		return rc;
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
 	/* Enqueue stream transfer */
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
 		DBGC ( usb, "USB %s %s could not enqueue stream transfer: %s\n",
552
 		DBGC ( usb, "USB %s %s could not enqueue stream transfer: %s\n",
547
 		       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
553
 		       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
548
 		return rc;
554
 		return rc;

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

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

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

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

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

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

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

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

Loading…
Cancel
Save