|  | @@ -321,6 +321,37 @@ int usb_endpoint_open ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 321 | 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 | 356 |   * Close USB endpoint
 | 
		
	
		
			
			| 326 | 357 |   *
 | 
		
	
	
		
			
			|  | @@ -345,6 +376,9 @@ void usb_endpoint_close ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 345 | 376 |  	/* Discard any recycled buffers, if applicable */
 | 
		
	
		
			
			| 346 | 377 |  	if ( ep->max )
 | 
		
	
		
			
			| 347 | 378 |  		usb_flush ( ep );
 | 
		
	
		
			
			|  | 379 | +
 | 
		
	
		
			
			|  | 380 | +	/* Clear transaction translator, if applicable */
 | 
		
	
		
			
			|  | 381 | +	usb_endpoint_clear_tt ( ep );
 | 
		
	
		
			
			| 348 | 382 |  }
 | 
		
	
		
			
			| 349 | 383 |  
 | 
		
	
		
			
			| 350 | 384 |  /**
 | 
		
	
	
		
			
			|  | @@ -369,6 +403,10 @@ static int usb_endpoint_reset ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 369 | 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 | 410 |  	/* Clear endpoint halt, if applicable */
 | 
		
	
		
			
			| 373 | 411 |  	type = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
 | 
		
	
		
			
			| 374 | 412 |  	if ( ( type != USB_ENDPOINT_ATTR_CONTROL ) &&
 | 
		
	
	
		
			
			|  | @@ -1949,14 +1987,16 @@ void usb_free_address ( struct usb_bus *bus, unsigned int address ) {
 | 
		
	
		
			
			| 1949 | 1987 |   * @ret route		USB route string
 | 
		
	
		
			
			| 1950 | 1988 |   */
 | 
		
	
		
			
			| 1951 | 1989 |  unsigned int usb_route_string ( struct usb_device *usb ) {
 | 
		
	
		
			
			|  | 1990 | +	struct usb_device *parent;
 | 
		
	
		
			
			| 1952 | 1991 |  	unsigned int route;
 | 
		
	
		
			
			| 1953 | 1992 |  
 | 
		
	
		
			
			| 1954 | 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 | 1995 |  		route <<= 4;
 | 
		
	
		
			
			| 1957 | 1996 |  		route |= ( ( usb->port->address > 0xf ) ?
 | 
		
	
		
			
			| 1958 | 1997 |  			   0xf : usb->port->address );
 | 
		
	
		
			
			| 1959 | 1998 |  	}
 | 
		
	
		
			
			|  | 1999 | +
 | 
		
	
		
			
			| 1960 | 2000 |  	return route;
 | 
		
	
		
			
			| 1961 | 2001 |  }
 | 
		
	
		
			
			| 1962 | 2002 |  
 | 
		
	
	
		
			
			|  | @@ -1967,10 +2007,11 @@ unsigned int usb_route_string ( struct usb_device *usb ) {
 | 
		
	
		
			
			| 1967 | 2007 |   * @ret depth		Hub depth
 | 
		
	
		
			
			| 1968 | 2008 |   */
 | 
		
	
		
			
			| 1969 | 2009 |  unsigned int usb_depth ( struct usb_device *usb ) {
 | 
		
	
		
			
			|  | 2010 | +	struct usb_device *parent;
 | 
		
	
		
			
			| 1970 | 2011 |  	unsigned int depth;
 | 
		
	
		
			
			| 1971 | 2012 |  
 | 
		
	
		
			
			| 1972 | 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 | 2015 |  		depth++;
 | 
		
	
		
			
			| 1975 | 2016 |  
 | 
		
	
		
			
			| 1976 | 2017 |  	return depth;
 | 
		
	
	
		
			
			|  | @@ -1983,14 +2024,37 @@ unsigned int usb_depth ( struct usb_device *usb ) {
 | 
		
	
		
			
			| 1983 | 2024 |   * @ret port		Root hub port
 | 
		
	
		
			
			| 1984 | 2025 |   */
 | 
		
	
		
			
			| 1985 | 2026 |  struct usb_port * usb_root_hub_port ( struct usb_device *usb ) {
 | 
		
	
		
			
			|  | 2027 | +	struct usb_device *parent;
 | 
		
	
		
			
			| 1986 | 2028 |  
 | 
		
	
		
			
			| 1987 | 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 | 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 | 2058 |  /* Drag in objects via register_usb_bus() */
 | 
		
	
		
			
			| 1995 | 2059 |  REQUIRING_SYMBOL ( register_usb_bus );
 | 
		
	
		
			
			| 1996 | 2060 |  
 |