Sfoglia il codice sorgente

[usb] Clear transaction translator buffers when applicable

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 anni fa
parent
commit
5486c947e2
2 ha cambiato i file con 72 aggiunte e 4 eliminazioni
  1. 68
    4
      src/drivers/bus/usb.c
  2. 4
    0
      src/include/ipxe/usb.h

+ 68
- 4
src/drivers/bus/usb.c Vedi File

321
 	return rc;
321
 	return rc;
322
 }
322
 }
323
 
323
 
324
+/**
325
+ * Clear transaction translator (if applicable)
326
+ *
327
+ * @v ep		USB endpoint
328
+ * @ret rc		Return status code
329
+ */
330
+static int usb_endpoint_clear_tt ( struct usb_endpoint *ep ) {
331
+	struct usb_device *usb = ep->usb;
332
+	struct usb_port *tt;
333
+	int rc;
334
+
335
+	/* Do nothing if this is a periodic endpoint */
336
+	if ( ep->attributes & USB_ENDPOINT_ATTR_PERIODIC )
337
+		return 0;
338
+
339
+	/* Do nothing if this endpoint is not behind a transaction translator */
340
+	tt = usb_transaction_translator ( usb );
341
+	if ( ! tt )
342
+		return 0;
343
+
344
+	/* Clear transaction translator buffer */
345
+	if ( ( rc = tt->hub->driver->clear_tt ( tt->hub, tt, ep ) ) != 0 ) {
346
+		DBGC ( usb, "USB %s %s could not clear transaction translator: "
347
+		       "%s\n", usb->name, usb_endpoint_name ( ep->address ),
348
+		       strerror ( rc ) );
349
+		return rc;
350
+	}
351
+
352
+	return 0;
353
+}
354
+
324
 /**
355
 /**
325
  * Close USB endpoint
356
  * Close USB endpoint
326
  *
357
  *
345
 	/* Discard any recycled buffers, if applicable */
376
 	/* Discard any recycled buffers, if applicable */
346
 	if ( ep->max )
377
 	if ( ep->max )
347
 		usb_flush ( ep );
378
 		usb_flush ( ep );
379
+
380
+	/* Clear transaction translator, if applicable */
381
+	usb_endpoint_clear_tt ( ep );
348
 }
382
 }
349
 
383
 
350
 /**
384
 /**
369
 		return rc;
403
 		return rc;
370
 	}
404
 	}
371
 
405
 
406
+	/* Clear transaction translator, if applicable */
407
+	if ( ( rc = usb_endpoint_clear_tt ( ep ) ) != 0 )
408
+		return rc;
409
+
372
 	/* Clear endpoint halt, if applicable */
410
 	/* Clear endpoint halt, if applicable */
373
 	type = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
411
 	type = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
374
 	if ( ( type != USB_ENDPOINT_ATTR_CONTROL ) &&
412
 	if ( ( type != USB_ENDPOINT_ATTR_CONTROL ) &&
1949
  * @ret route		USB route string
1987
  * @ret route		USB route string
1950
  */
1988
  */
1951
 unsigned int usb_route_string ( struct usb_device *usb ) {
1989
 unsigned int usb_route_string ( struct usb_device *usb ) {
1990
+	struct usb_device *parent;
1952
 	unsigned int route;
1991
 	unsigned int route;
1953
 
1992
 
1954
 	/* Navigate up to root hub, constructing route string as we go */
1993
 	/* Navigate up to root hub, constructing route string as we go */
1955
-	for ( route = 0 ; usb->port->hub->usb ; usb = usb->port->hub->usb ) {
1994
+	for ( route = 0 ; ( parent = usb->port->hub->usb ) ; usb = parent ) {
1956
 		route <<= 4;
1995
 		route <<= 4;
1957
 		route |= ( ( usb->port->address > 0xf ) ?
1996
 		route |= ( ( usb->port->address > 0xf ) ?
1958
 			   0xf : usb->port->address );
1997
 			   0xf : usb->port->address );
1959
 	}
1998
 	}
1999
+
1960
 	return route;
2000
 	return route;
1961
 }
2001
 }
1962
 
2002
 
1967
  * @ret depth		Hub depth
2007
  * @ret depth		Hub depth
1968
  */
2008
  */
1969
 unsigned int usb_depth ( struct usb_device *usb ) {
2009
 unsigned int usb_depth ( struct usb_device *usb ) {
2010
+	struct usb_device *parent;
1970
 	unsigned int depth;
2011
 	unsigned int depth;
1971
 
2012
 
1972
 	/* Navigate up to root hub, constructing depth as we go */
2013
 	/* Navigate up to root hub, constructing depth as we go */
1973
-	for ( depth = 0 ; usb->port->hub->usb ; usb = usb->port->hub->usb )
2014
+	for ( depth = 0 ; ( parent = usb->port->hub->usb ) ; usb = parent )
1974
 		depth++;
2015
 		depth++;
1975
 
2016
 
1976
 	return depth;
2017
 	return depth;
1983
  * @ret port		Root hub port
2024
  * @ret port		Root hub port
1984
  */
2025
  */
1985
 struct usb_port * usb_root_hub_port ( struct usb_device *usb ) {
2026
 struct usb_port * usb_root_hub_port ( struct usb_device *usb ) {
2027
+	struct usb_device *parent;
1986
 
2028
 
1987
 	/* Navigate up to root hub */
2029
 	/* Navigate up to root hub */
1988
-	while ( usb->port->hub->usb )
1989
-		usb = usb->port->hub->usb;
2030
+	while ( ( parent = usb->port->hub->usb ) )
2031
+		usb = parent;
1990
 
2032
 
1991
 	return usb->port;
2033
 	return usb->port;
1992
 }
2034
 }
1993
 
2035
 
2036
+/**
2037
+ * Get USB transaction translator
2038
+ *
2039
+ * @v usb		USB device
2040
+ * @ret port		Transaction translator port, or NULL
2041
+ */
2042
+struct usb_port * usb_transaction_translator ( struct usb_device *usb ) {
2043
+	struct usb_device *parent;
2044
+
2045
+	/* Navigate up to root hub.  If we find a low-speed or
2046
+	 * full-speed port with a higher-speed parent device, then
2047
+	 * that port is the transaction translator.
2048
+	 */
2049
+	for ( ; ( parent = usb->port->hub->usb ) ; usb = parent ) {
2050
+		if ( ( usb->port->speed <= USB_SPEED_FULL ) &&
2051
+		     ( parent->port->speed > USB_SPEED_FULL ) )
2052
+			return usb->port;
2053
+	}
2054
+
2055
+	return NULL;
2056
+}
2057
+
1994
 /* Drag in objects via register_usb_bus() */
2058
 /* Drag in objects via register_usb_bus() */
1995
 REQUIRING_SYMBOL ( register_usb_bus );
2059
 REQUIRING_SYMBOL ( register_usb_bus );
1996
 
2060
 

+ 4
- 0
src/include/ipxe/usb.h Vedi File

249
 /** Endpoint attribute transfer type mask */
249
 /** Endpoint attribute transfer type mask */
250
 #define USB_ENDPOINT_ATTR_TYPE_MASK 0x03
250
 #define USB_ENDPOINT_ATTR_TYPE_MASK 0x03
251
 
251
 
252
+/** Endpoint periodic type */
253
+#define USB_ENDPOINT_ATTR_PERIODIC 0x01
254
+
252
 /** Control endpoint transfer type */
255
 /** Control endpoint transfer type */
253
 #define USB_ENDPOINT_ATTR_CONTROL 0x00
256
 #define USB_ENDPOINT_ATTR_CONTROL 0x00
254
 
257
 
1189
 extern unsigned int usb_route_string ( struct usb_device *usb );
1192
 extern unsigned int usb_route_string ( struct usb_device *usb );
1190
 extern unsigned int usb_depth ( struct usb_device *usb );
1193
 extern unsigned int usb_depth ( struct usb_device *usb );
1191
 extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
1194
 extern struct usb_port * usb_root_hub_port ( struct usb_device *usb );
1195
+extern struct usb_port * usb_transaction_translator ( struct usb_device *usb );
1192
 
1196
 
1193
 /** Minimum reset time
1197
 /** Minimum reset time
1194
  *
1198
  *

Loading…
Annulla
Salva