Browse Source

[usb] Add clear_tt() hub method to clear transaction translator buffer

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
9e88194655
5 changed files with 114 additions and 2 deletions
  1. 22
    2
      src/drivers/usb/ehci.c
  2. 30
    0
      src/drivers/usb/usbhub.c
  3. 33
    0
      src/drivers/usb/usbhub.h
  4. 20
    0
      src/drivers/usb/xhci.c
  5. 9
    0
      src/include/ipxe/usb.h

+ 22
- 2
src/drivers/usb/ehci.c View File

1022
 		/* No way to prevent hardware from continuing to
1022
 		/* No way to prevent hardware from continuing to
1023
 		 * access the memory, so leak it.
1023
 		 * access the memory, so leak it.
1024
 		 */
1024
 		 */
1025
-		DBGC ( ehci, "EHCI %p %s endpoint %d could not unschedule: "
1025
+		DBGC ( ehci, "EHCI %p %s endpoint %02x could not unschedule: "
1026
 		       "%s\n", ehci, usb->name, ep->address, strerror ( rc ) );
1026
 		       "%s\n", ehci, usb->name, ep->address, strerror ( rc ) );
1027
 		return;
1027
 		return;
1028
 	}
1028
 	}
1217
 		 */
1217
 		 */
1218
 		if ( status & EHCI_STATUS_HALTED ) {
1218
 		if ( status & EHCI_STATUS_HALTED ) {
1219
 			rc = -EIO_STATUS ( status );
1219
 			rc = -EIO_STATUS ( status );
1220
-			DBGC ( ehci, "EHCI %p %s endpoint %d completion %d "
1220
+			DBGC ( ehci, "EHCI %p %s endpoint %02x completion %d "
1221
 			       "failed (status %02x): %s\n", ehci, usb->name,
1221
 			       "failed (status %02x): %s\n", ehci, usb->name,
1222
 			       ep->address, index, status, strerror ( rc ) );
1222
 			       ep->address, index, status, strerror ( rc ) );
1223
 			while ( ! iobuf )
1223
 			while ( ! iobuf )
1496
 	return 0;
1496
 	return 0;
1497
 }
1497
 }
1498
 
1498
 
1499
+/**
1500
+ * Clear transaction translator buffer
1501
+ *
1502
+ * @v hub		USB hub
1503
+ * @v port		USB port
1504
+ * @v ep		USB endpoint
1505
+ * @ret rc		Return status code
1506
+ */
1507
+static int ehci_hub_clear_tt ( struct usb_hub *hub, struct usb_port *port,
1508
+			       struct usb_endpoint *ep ) {
1509
+	struct ehci_device *ehci = usb_hub_get_drvdata ( hub );
1510
+
1511
+	/* Should never be called; this is a root hub */
1512
+	DBGC ( ehci, "EHCI %p port %d nonsensical CLEAR_TT for %s endpoint "
1513
+	       "%02x\n", ehci, port->address, ep->usb->name, ep->address );
1514
+
1515
+	return -ENOTSUP;
1516
+}
1517
+
1499
 /**
1518
 /**
1500
  * Poll for port status changes
1519
  * Poll for port status changes
1501
  *
1520
  *
1706
 		.enable = ehci_hub_enable,
1725
 		.enable = ehci_hub_enable,
1707
 		.disable = ehci_hub_disable,
1726
 		.disable = ehci_hub_disable,
1708
 		.speed = ehci_hub_speed,
1727
 		.speed = ehci_hub_speed,
1728
+		.clear_tt = ehci_hub_clear_tt,
1709
 	},
1729
 	},
1710
 };
1730
 };
1711
 
1731
 

+ 30
- 0
src/drivers/usb/usbhub.c View File

338
 	return 0;
338
 	return 0;
339
 }
339
 }
340
 
340
 
341
+/**
342
+ * Clear transaction translator buffer
343
+ *
344
+ * @v hub		USB hub
345
+ * @v port		USB port
346
+ * @v ep		USB endpoint
347
+ * @ret rc		Return status code
348
+ */
349
+static int hub_clear_tt ( struct usb_hub *hub, struct usb_port *port,
350
+			  struct usb_endpoint *ep ) {
351
+	struct usb_hub_device *hubdev = usb_hub_get_drvdata ( hub );
352
+	struct usb_device *usb = hubdev->usb;
353
+	int rc;
354
+
355
+	/* Clear transaction translator buffer.  All hubs must support
356
+	 * single-TT operation; we simplify our code by supporting
357
+	 * only this configuration.
358
+	 */
359
+	if ( ( rc = usb_hub_clear_tt_buffer ( usb, ep->usb->address,
360
+					      ep->address, ep->attributes,
361
+					      USB_HUB_TT_SINGLE ) ) != 0 ) {
362
+		DBGC ( hubdev, "HUB %s port %d could not clear TT buffer: %s\n",
363
+		       hubdev->name, port->address, strerror ( rc ) );
364
+		return rc;
365
+	}
366
+
367
+	return 0;
368
+}
369
+
341
 /** USB hub operations */
370
 /** USB hub operations */
342
 static struct usb_hub_driver_operations hub_operations = {
371
 static struct usb_hub_driver_operations hub_operations = {
343
 	.open = hub_open,
372
 	.open = hub_open,
345
 	.enable = hub_enable,
374
 	.enable = hub_enable,
346
 	.disable = hub_disable,
375
 	.disable = hub_disable,
347
 	.speed = hub_speed,
376
 	.speed = hub_speed,
377
+	.clear_tt = hub_clear_tt,
348
 };
378
 };
349
 
379
 
350
 /**
380
 /**

+ 33
- 0
src/drivers/usb/usbhub.h View File

129
 	( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE |		\
129
 	( USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE |		\
130
 	  USB_REQUEST_TYPE ( 12 ) )
130
 	  USB_REQUEST_TYPE ( 12 ) )
131
 
131
 
132
+/** Clear transaction translator buffer */
133
+#define USB_HUB_CLEAR_TT_BUFFER						\
134
+	( USB_DIR_OUT | USB_TYPE_CLASS | USB_HUB_RECIP_PORT |		\
135
+	  USB_REQUEST_TYPE ( 8 ) )
136
+
132
 /**
137
 /**
133
  * Get hub descriptor
138
  * Get hub descriptor
134
  *
139
  *
214
 	return usb_control ( usb, USB_HUB_SET_HUB_DEPTH, depth, 0, NULL, 0 );
219
 	return usb_control ( usb, USB_HUB_SET_HUB_DEPTH, depth, 0, NULL, 0 );
215
 }
220
 }
216
 
221
 
222
+/**
223
+ * Clear transaction translator buffer
224
+ *
225
+ * @v usb		USB device
226
+ * @v device		Device address
227
+ * @v endpoint		Endpoint address
228
+ * @v attributes	Endpoint attributes
229
+ * @v tt_port		Transaction translator port (or 1 for single-TT hubs)
230
+ * @ret rc		Return status code
231
+ */
232
+static inline __attribute__ (( always_inline )) int
233
+usb_hub_clear_tt_buffer ( struct usb_device *usb, unsigned int device,
234
+			  unsigned int endpoint, unsigned int attributes,
235
+			  unsigned int tt_port ) {
236
+	unsigned int value;
237
+
238
+	/* Calculate value */
239
+	value = ( ( ( endpoint & USB_ENDPOINT_MAX ) << 0 ) | ( device << 4 ) |
240
+		  ( ( attributes & USB_ENDPOINT_ATTR_TYPE_MASK ) << 11 ) |
241
+		  ( ( endpoint & USB_ENDPOINT_IN ) << 8 ) );
242
+
243
+	return usb_control ( usb, USB_HUB_CLEAR_TT_BUFFER, value,
244
+			     tt_port, NULL, 0 );
245
+}
246
+
247
+/** Transaction translator port value for single-TT hubs */
248
+#define USB_HUB_TT_SINGLE 1
249
+
217
 /** A USB hub device */
250
 /** A USB hub device */
218
 struct usb_hub_device {
251
 struct usb_hub_device {
219
 	/** Name */
252
 	/** Name */

+ 20
- 0
src/drivers/usb/xhci.c View File

2992
 	return 0;
2992
 	return 0;
2993
 }
2993
 }
2994
 
2994
 
2995
+/**
2996
+ * Clear transaction translator buffer
2997
+ *
2998
+ * @v hub		USB hub
2999
+ * @v port		USB port
3000
+ * @v ep		USB endpoint
3001
+ * @ret rc		Return status code
3002
+ */
3003
+static int xhci_hub_clear_tt ( struct usb_hub *hub, struct usb_port *port,
3004
+			       struct usb_endpoint *ep ) {
3005
+	struct ehci_device *ehci = usb_hub_get_drvdata ( hub );
3006
+
3007
+	/* Should never be called; this is a root hub */
3008
+	DBGC ( ehci, "XHCI %p port %d nonsensical CLEAR_TT for %s endpoint "
3009
+	       "%02x\n", ehci, port->address, ep->usb->name, ep->address );
3010
+
3011
+	return -ENOTSUP;
3012
+}
3013
+
2995
 /******************************************************************************
3014
 /******************************************************************************
2996
  *
3015
  *
2997
  * PCI interface
3016
  * PCI interface
3025
 		.enable = xhci_hub_enable,
3044
 		.enable = xhci_hub_enable,
3026
 		.disable = xhci_hub_disable,
3045
 		.disable = xhci_hub_disable,
3027
 		.speed = xhci_hub_speed,
3046
 		.speed = xhci_hub_speed,
3047
+		.clear_tt = xhci_hub_clear_tt,
3028
 	},
3048
 	},
3029
 };
3049
 };
3030
 
3050
 

+ 9
- 0
src/include/ipxe/usb.h View File

820
 	 * @ret rc		Return status code
820
 	 * @ret rc		Return status code
821
 	 */
821
 	 */
822
 	int ( * speed ) ( struct usb_hub *hub, struct usb_port *port );
822
 	int ( * speed ) ( struct usb_hub *hub, struct usb_port *port );
823
+	/** Clear transaction translator buffer
824
+	 *
825
+	 * @v hub		USB hub
826
+	 * @v port		USB port
827
+	 * @v ep		USB endpoint
828
+	 * @ret rc		Return status code
829
+	 */
830
+	int ( * clear_tt ) ( struct usb_hub *hub, struct usb_port *port,
831
+			     struct usb_endpoint *ep );
823
 };
832
 };
824
 
833
 
825
 /**
834
 /**

Loading…
Cancel
Save