@ -21,6 +21,10 @@ DECLARE_GLOBAL_DATA_PTR;
extern bool usb_started ; /* flag for the started/stopped USB status */
static bool asynch_allowed ;
struct usb_uclass_priv {
int companion_device_count ;
} ;
int usb_disable_asynch ( int disable )
{
int old_value = asynch_allowed ;
@ -46,11 +50,22 @@ int submit_control_msg(struct usb_device *udev, unsigned long pipe,
{
struct udevice * bus = udev - > controller_dev ;
struct dm_usb_ops * ops = usb_get_ops ( bus ) ;
struct usb_uclass_priv * uc_priv = bus - > uclass - > priv ;
int err ;
if ( ! ops - > control )
return - ENOSYS ;
return ops - > control ( bus , udev , pipe , buffer , length , setup ) ;
err = ops - > control ( bus , udev , pipe , buffer , length , setup ) ;
if ( setup - > request = = USB_REQ_SET_FEATURE & &
setup - > requesttype = = USB_RT_PORT & &
setup - > value = = cpu_to_le16 ( USB_PORT_FEAT_RESET ) & &
err = = - ENXIO ) {
/* Device handed over to companion after port reset */
uc_priv - > companion_device_count + + ;
}
return err ;
}
int submit_bulk_msg ( struct usb_device * udev , unsigned long pipe , void * buffer ,
@ -117,12 +132,16 @@ int usb_stop(void)
{
struct udevice * bus ;
struct uclass * uc ;
struct usb_uclass_priv * uc_priv ;
int err = 0 , ret ;
/* De-activate any devices that have been activated */
ret = uclass_get ( UCLASS_USB , & uc ) ;
if ( ret )
return ret ;
uc_priv = uc - > priv ;
uclass_foreach_dev ( bus , uc ) {
ret = device_remove ( bus ) ;
if ( ret & & ! err )
@ -142,6 +161,7 @@ int usb_stop(void)
# endif
usb_stor_reset ( ) ;
usb_hub_reset ( ) ;
uc_priv - > companion_device_count = 0 ;
usb_started = 0 ;
return err ;
@ -171,6 +191,7 @@ static void usb_scan_bus(struct udevice *bus, bool recurse)
int usb_init ( void )
{
int controllers_initialized = 0 ;
struct usb_uclass_priv * uc_priv ;
struct usb_bus_priv * priv ;
struct udevice * bus ;
struct uclass * uc ;
@ -184,6 +205,8 @@ int usb_init(void)
if ( ret )
return ret ;
uc_priv = uc - > priv ;
uclass_foreach_dev ( bus , uc ) {
/* init low_level USB */
printf ( " USB%d: " , count ) ;
@ -219,15 +242,17 @@ int usb_init(void)
/*
* Now that the primary controllers have been scanned and have handed
* over any devices they do not understand to their companions , scan
* the companions .
* the companions if necessary .
*/
uclass_foreach_dev ( bus , uc ) {
if ( ! device_active ( bus ) )
continue ;
if ( uc_priv - > companion_device_count ) {
uclass_foreach_dev ( bus , uc ) {
if ( ! device_active ( bus ) )
continue ;
priv = dev_get_uclass_priv ( bus ) ;
if ( priv - > companion )
usb_scan_bus ( bus , true ) ;
priv = dev_get_uclass_priv ( bus ) ;
if ( priv - > companion )
usb_scan_bus ( bus , true ) ;
}
}
debug ( " scan end \n " ) ;
@ -685,6 +710,7 @@ UCLASS_DRIVER(usb) = {
. name = " usb " ,
. flags = DM_UC_FLAG_SEQ_ALIAS ,
. post_bind = usb_post_bind ,
. priv_auto_alloc_size = sizeof ( struct usb_uclass_priv ) ,
. per_child_auto_alloc_size = sizeof ( struct usb_device ) ,
. per_device_auto_alloc_size = sizeof ( struct usb_bus_priv ) ,
. child_post_bind = usb_child_post_bind ,