@ -58,9 +58,9 @@
# undef USB_DEBUG
# ifdef USB_DEBUG
# define USB_PRINTF(fmt,args...) printf (fmt ,##args)
# define USB_PRINTF(fmt, args...) printf (fmt , ##args)
# else
# define USB_PRINTF(fmt,args...)
# define USB_PRINTF(fmt, args...)
# endif
# define USB_BUFSIZ 512
@ -88,7 +88,7 @@ void usb_hub_reset(void);
void __inline__ wait_ms ( unsigned long ms )
{
while ( ms - - > 0 )
while ( ms - - > 0 )
udelay ( 1000 ) ;
}
/***************************************************************************
@ -99,22 +99,22 @@ int usb_init(void)
{
int result ;
running = 0 ;
dev_index = 0 ;
asynch_allowed = 1 ;
running = 0 ;
dev_index = 0 ;
asynch_allowed = 1 ;
usb_hub_reset ( ) ;
/* init low_level USB */
printf ( " USB: " ) ;
result = usb_lowlevel_init ( ) ;
/* if lowlevel init is OK, scan the bus for devices i.e. search HUBs and configure them */
if ( result = = 0 ) {
/* if lowlevel init is OK, scan the bus for devices
* i . e . search HUBs and configure them */
if ( result = = 0 ) {
printf ( " scanning bus for devices... " ) ;
running = 1 ;
running = 1 ;
usb_scan_devices ( ) ;
usb_started = 1 ;
return 0 ;
}
else {
} else {
printf ( " Error, couldn't init Lowlevel part \n " ) ;
usb_started = 0 ;
return - 1 ;
@ -143,7 +143,7 @@ int usb_stop(void)
*/
void usb_disable_asynch ( int disable )
{
asynch_allowed = ! disable ;
asynch_allowed = ! disable ;
}
@ -156,9 +156,9 @@ void usb_disable_asynch(int disable)
* submits an Interrupt Message
*/
int usb_submit_int_msg ( struct usb_device * dev , unsigned long pipe ,
void * buffer , int transfer_len , int interval )
void * buffer , int transfer_len , int interval )
{
return submit_int_msg ( dev , pipe , buffer , transfer_len , interval ) ;
return submit_int_msg ( dev , pipe , buffer , transfer_len , interval ) ;
}
/*
@ -175,8 +175,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
unsigned short value , unsigned short index ,
void * data , unsigned short size , int timeout )
{
if ( ( timeout = = 0 ) & & ( ! asynch_allowed ) ) /* request for a asynch control pipe is not allowed */
if ( ( timeout = = 0 ) & & ( ! asynch_allowed ) ) {
/* request for a asynch control pipe is not allowed */
return - 1 ;
}
/* set setup command */
setup_packet . requesttype = requesttype ;
@ -184,24 +186,24 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
setup_packet . value = cpu_to_le16 ( value ) ;
setup_packet . index = cpu_to_le16 ( index ) ;
setup_packet . length = cpu_to_le16 ( size ) ;
USB_PRINTF ( " usb_control_msg: request: 0x%X, requesttype: 0x%X, value 0x%X index 0x%X length 0x%X \n " ,
request , requesttype , value , index , size ) ;
dev - > status = USB_ST_NOT_PROC ; /*not yet processed */
USB_PRINTF ( " usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
" value 0x%X index 0x%X length 0x%X \n " ,
request , requesttype , value , index , size ) ;
dev - > status = USB_ST_NOT_PROC ; /*not yet processed */
submit_control_msg ( dev , pipe , data , size , & setup_packet ) ;
if ( timeout = = 0 ) {
submit_control_msg ( dev , pipe , data , size , & setup_packet ) ;
if ( timeout = = 0 )
return ( int ) size ;
}
while ( timeout - - ) {
if ( ! ( ( volatile unsigned long ) dev - > status & USB_ST_NOT_PROC ) )
while ( timeout - - ) {
if ( ! ( ( volatile unsigned long ) dev - > status & USB_ST_NOT_PROC ) )
break ;
wait_ms ( 1 ) ;
}
if ( dev - > status = = 0 )
if ( dev - > status = = 0 )
return dev - > act_len ;
else {
else
return - 1 ;
}
}
/*-------------------------------------------------------------------
@ -214,15 +216,15 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
{
if ( len < 0 )
return - 1 ;
dev - > status = USB_ST_NOT_PROC ; /*not yet processed */
submit_bulk_msg ( dev , pipe , data , len ) ;
while ( timeout - - ) {
if ( ! ( ( volatile unsigned long ) dev - > status & USB_ST_NOT_PROC ) )
dev - > status = USB_ST_NOT_PROC ; /*not yet processed */
submit_bulk_msg ( dev , pipe , data , len ) ;
while ( timeout - - ) {
if ( ! ( ( volatile unsigned long ) dev - > status & USB_ST_NOT_PROC ) )
break ;
wait_ms ( 1 ) ;
}
* actual_length = dev - > act_len ;
if ( dev - > status = = 0 )
* actual_length = dev - > act_len ;
if ( dev - > status = = 0 )
return 0 ;
else
return - 1 ;
@ -237,9 +239,10 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
* returns the max packet size , depending on the pipe direction and
* the configurations values
*/
int usb_maxpacket ( struct usb_device * dev , unsigned long pipe )
int usb_maxpacket ( struct usb_device * dev , unsigned long pipe )
{
if ( ( pipe & USB_DIR_IN ) = = 0 ) /* direction is out -> use emaxpacket out */
/* direction is out -> use emaxpacket out */
if ( ( pipe & USB_DIR_IN ) = = 0 )
return ( dev - > epmaxpacketout [ ( ( pipe > > 15 ) & 0xf ) ] ) ;
else
return ( dev - > epmaxpacketin [ ( ( pipe > > 15 ) & 0xf ) ] ) ;
@ -318,8 +321,9 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
dev - > configno = cfgno ;
head = ( struct usb_descriptor_header * ) & buffer [ 0 ] ;
if ( head - > bDescriptorType ! = USB_DT_CONFIG ) {
printf ( " ERROR: NOT USB_CONFIG_DESC %x \n " , head - > bDescriptorType ) ;
if ( head - > bDescriptorType ! = USB_DT_CONFIG ) {
printf ( " ERROR: NOT USB_CONFIG_DESC %x \n " ,
head - > bDescriptorType ) ;
return - 1 ;
}
memcpy ( & dev - > config , buffer , buffer [ 0 ] ) ;
@ -327,45 +331,52 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
dev - > config . no_of_if = 0 ;
index = dev - > config . bLength ;
/* Ok the first entry must be a configuration entry, now process the others */
/* Ok the first entry must be a configuration entry,
* now process the others */
head = ( struct usb_descriptor_header * ) & buffer [ index ] ;
while ( index + 1 < dev - > config . wTotalLength ) {
switch ( head - > bDescriptorType ) {
case USB_DT_INTERFACE :
if ( ( ( struct usb_interface_descriptor * ) & buffer [ index ] ) - >
bInterfaceNumber ! = curr_if_num ) {
/* this is a new interface, copy new desc */
ifno = dev - > config . no_of_if ;
dev - > config . no_of_if + + ;
memcpy ( & dev - > config . if_desc [ ifno ] ,
& buffer [ index ] , buffer [ index ] ) ;
dev - > config . if_desc [ ifno ] . no_of_ep = 0 ;
dev - > config . if_desc [ ifno ] . num_altsetting = 1 ;
curr_if_num = dev - > config . if_desc [ ifno ] . bInterfaceNumber ;
} else {
/* found alternate setting for the interface */
dev - > config . if_desc [ ifno ] . num_altsetting + + ;
}
break ;
case USB_DT_ENDPOINT :
epno = dev - > config . if_desc [ ifno ] . no_of_ep ;
dev - > config . if_desc [ ifno ] . no_of_ep + + ; /* found an endpoint */
memcpy ( & dev - > config . if_desc [ ifno ] . ep_desc [ epno ] ,
while ( index + 1 < dev - > config . wTotalLength ) {
switch ( head - > bDescriptorType ) {
case USB_DT_INTERFACE :
if ( ( ( struct usb_interface_descriptor * ) \
& buffer [ index ] ) - > bInterfaceNumber ! = curr_if_num ) {
/* this is a new interface, copy new desc */
ifno = dev - > config . no_of_if ;
dev - > config . no_of_if + + ;
memcpy ( & dev - > config . if_desc [ ifno ] ,
& buffer [ index ] , buffer [ index ] ) ;
le16_to_cpus ( & ( dev - > config . if_desc [ ifno ] . ep_desc [ epno ] . wMaxPacketSize ) ) ;
USB_PRINTF ( " if %d, ep %d \n " , ifno , epno ) ;
break ;
default :
if ( head - > bLength = = 0 )
return 1 ;
USB_PRINTF ( " unknown Description Type : %x \n " , head - > bDescriptorType ) ;
{
ch = ( unsigned char * ) head ;
for ( i = 0 ; i < head - > bLength ; i + + )
USB_PRINTF ( " %02X " , * ch + + ) ;
USB_PRINTF ( " \n \n \n " ) ;
}
break ;
dev - > config . if_desc [ ifno ] . no_of_ep = 0 ;
dev - > config . if_desc [ ifno ] . num_altsetting = 1 ;
curr_if_num =
dev - > config . if_desc [ ifno ] . bInterfaceNumber ;
} else {
/* found alternate setting for the interface */
dev - > config . if_desc [ ifno ] . num_altsetting + + ;
}
break ;
case USB_DT_ENDPOINT :
epno = dev - > config . if_desc [ ifno ] . no_of_ep ;
/* found an endpoint */
dev - > config . if_desc [ ifno ] . no_of_ep + + ;
memcpy ( & dev - > config . if_desc [ ifno ] . ep_desc [ epno ] ,
& buffer [ index ] , buffer [ index ] ) ;
le16_to_cpus ( & ( dev - > config . if_desc [ ifno ] . ep_desc [ epno ] . \
wMaxPacketSize ) ) ;
USB_PRINTF ( " if %d, ep %d \n " , ifno , epno ) ;
break ;
default :
if ( head - > bLength = = 0 )
return 1 ;
USB_PRINTF ( " unknown Description Type : %x \n " ,
head - > bDescriptorType ) ;
{
ch = ( unsigned char * ) head ;
for ( i = 0 ; i < head - > bLength ; i + + )
USB_PRINTF ( " %02X " , * ch + + ) ;
USB_PRINTF ( " \n \n \n " ) ;
}
break ;
}
index + = head - > bLength ;
head = ( struct usb_descriptor_header * ) & buffer [ index ] ;
@ -384,7 +395,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
int endp = usb_pipeendpoint ( pipe ) | ( usb_pipein ( pipe ) < < 7 ) ;
result = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_CLEAR_FEATURE , USB_RECIP_ENDPOINT , 0 , endp , NULL , 0 , USB_CNTL_TIMEOUT * 3 ) ;
USB_REQ_CLEAR_FEATURE , USB_RECIP_ENDPOINT , 0 ,
endp , NULL , 0 , USB_CNTL_TIMEOUT * 3 ) ;
/* don't clear if failed */
if ( result < 0 )
@ -406,7 +418,8 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
/**********************************************************************
* get_descriptor type
*/
int usb_get_descriptor ( struct usb_device * dev , unsigned char type , unsigned char index , void * buf , int size )
int usb_get_descriptor ( struct usb_device * dev , unsigned char type ,
unsigned char index , void * buf , int size )
{
int res ;
res = usb_control_msg ( dev , usb_rcvctrlpipe ( dev , 0 ) ,
@ -419,32 +432,36 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
/**********************************************************************
* gets configuration cfgno and store it in the buffer
*/
int usb_get_configuration_no ( struct usb_device * dev , unsigned char * buffer , int cfgno )
int usb_get_configuration_no ( struct usb_device * dev ,
unsigned char * buffer , int cfgno )
{
int result ;
unsigned int tmp ;
struct usb_config_descriptor * config ;
config = ( struct usb_config_descriptor * ) & buffer [ 0 ] ;
config = ( struct usb_config_descriptor * ) & buffer [ 0 ] ;
result = usb_get_descriptor ( dev , USB_DT_CONFIG , cfgno , buffer , 8 ) ;
if ( result < 8 ) {
if ( result < 0 )
printf ( " unable to get descriptor, error %lX \n " , dev - > status ) ;
printf ( " unable to get descriptor, error %lX \n " ,
dev - > status ) ;
else
printf ( " config descriptor too short (expected %i, got %i) \n " , 8 , result ) ;
printf ( " config descriptor too short " \
" (expected %i, got %i) \n " , 8 , result ) ;
return - 1 ;
}
tmp = le16_to_cpu ( config - > wTotalLength ) ;
if ( tmp > USB_BUFSIZ ) {
USB_PRINTF ( " usb_get_configuration_no: failed to get descriptor - too long: %d \n " ,
tmp ) ;
USB_PRINTF ( " usb_get_configuration_no: failed to get " \
" descriptor - too long: %d \n " , tmp ) ;
return - 1 ;
}
result = usb_get_descriptor ( dev , USB_DT_CONFIG , cfgno , buffer , tmp ) ;
USB_PRINTF ( " get_conf_no %d Result %d, wLength %d \n " , cfgno , result , tmp ) ;
USB_PRINTF ( " get_conf_no %d Result %d, wLength %d \n " ,
cfgno , result , tmp ) ;
return result ;
}
@ -456,11 +473,11 @@ int usb_set_address(struct usb_device *dev)
{
int res ;
USB_PRINTF ( " set address %d \n " , dev - > devnum ) ;
res = usb_control_msg ( dev , usb_snddefctrl ( dev ) ,
USB_REQ_SET_ADDRESS , 0 ,
( dev - > devnum ) , 0 ,
NULL , 0 , USB_CNTL_TIMEOUT ) ;
USB_PRINTF ( " set address %d \n " , dev - > devnum ) ;
res = usb_control_msg ( dev , usb_snddefctrl ( dev ) ,
USB_REQ_SET_ADDRESS , 0 ,
( dev - > devnum ) , 0 ,
NULL , 0 , USB_CNTL_TIMEOUT ) ;
return res ;
}
@ -484,16 +501,19 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
}
/*
* We should return now for devices with only one alternate setting .
* According to 9.4 .10 of the Universal Serial Bus Specification Revision 2.0
* such devices can return with a STALL . This results in some USB sticks
* timeouting during initialization and then being unusable in U - Boot .
* According to 9.4 .10 of the Universal Serial Bus Specification
* Revision 2.0 such devices can return with a STALL . This results in
* some USB sticks timeouting during initialization and then being
* unusable in U - Boot .
*/
if ( if_face - > num_altsetting = = 1 )
return 0 ;
if ( ( ret = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_INTERFACE , USB_RECIP_INTERFACE , alternate ,
interface , NULL , 0 , USB_CNTL_TIMEOUT * 5 ) ) < 0 )
ret = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_INTERFACE , USB_RECIP_INTERFACE ,
alternate , interface , NULL , 0 ,
USB_CNTL_TIMEOUT * 5 ) ;
if ( ret < 0 )
return ret ;
return 0 ;
@ -505,18 +525,17 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
int usb_set_configuration ( struct usb_device * dev , int configuration )
{
int res ;
USB_PRINTF ( " set configuration %d \n " , configuration ) ;
USB_PRINTF ( " set configuration %d \n " , configuration ) ;
/* set setup command */
res = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_CONFIGURATION , 0 ,
configuration , 0 ,
NULL , 0 , USB_CNTL_TIMEOUT ) ;
if ( res = = 0 ) {
res = usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_CONFIGURATION , 0 ,
configuration , 0 ,
NULL , 0 , USB_CNTL_TIMEOUT ) ;
if ( res = = 0 ) {
dev - > toggle [ 0 ] = 0 ;
dev - > toggle [ 1 ] = 0 ;
return 0 ;
}
else
} else
return - 1 ;
}
@ -543,11 +562,13 @@ int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
/********************************************************************
* get report
*/
int usb_get_report ( struct usb_device * dev , int ifnum , unsigned char type , unsigned char id , void * buf , int size )
int usb_get_report ( struct usb_device * dev , int ifnum , unsigned char type ,
unsigned char id , void * buf , int size )
{
return usb_control_msg ( dev , usb_rcvctrlpipe ( dev , 0 ) ,
USB_REQ_GET_REPORT , USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE ,
( type < < 8 ) + id , ifnum , buf , size , USB_CNTL_TIMEOUT ) ;
USB_REQ_GET_REPORT ,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE ,
( type < < 8 ) + id , ifnum , buf , size , USB_CNTL_TIMEOUT ) ;
}
/********************************************************************
@ -564,7 +585,8 @@ int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
/********************************************************************
* get string index in buffer
*/
int usb_get_string ( struct usb_device * dev , unsigned short langid , unsigned char index , void * buf , int size )
int usb_get_string ( struct usb_device * dev , unsigned short langid ,
unsigned char index , void * buf , int size )
{
int i ;
int result ;
@ -655,17 +677,19 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
if ( ! dev - > have_langid ) {
err = usb_string_sub ( dev , 0 , 0 , tbuf ) ;
if ( err < 0 ) {
USB_PRINTF ( " error getting string descriptor 0 (error=%x) \n " , dev - > status ) ;
USB_PRINTF ( " error getting string descriptor 0 " \
" (error=%x) \n " , dev - > status ) ;
return - 1 ;
} else if ( tbuf [ 0 ] < 4 ) {
USB_PRINTF ( " string descriptor 0 too short \n " ) ;
return - 1 ;
} else {
dev - > have_langid = - 1 ;
dev - > string_langid = tbuf [ 2 ] | ( tbuf [ 3 ] < < 8 ) ;
dev - > string_langid = tbuf [ 2 ] | ( tbuf [ 3 ] < < 8 ) ;
/* always use the first langid listed */
USB_PRINTF ( " USB device number %d default language ID 0x%x \n " ,
dev - > devnum , dev - > string_langid ) ;
USB_PRINTF ( " USB device number %d default " \
" language ID 0x%x \n " ,
dev - > devnum , dev - > string_langid ) ;
}
}
@ -697,9 +721,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
/* returns a pointer to the device with the index [index].
* if the device is not assigned ( dev - > devnum = = - 1 ) returns NULL
*/
struct usb_device * usb_get_dev_index ( int index )
struct usb_device * usb_get_dev_index ( int index )
{
if ( usb_dev [ index ] . devnum = = - 1 )
if ( usb_dev [ index ] . devnum = = - 1 )
return NULL ;
else
return & usb_dev [ index ] ;
@ -709,21 +733,22 @@ struct usb_device * usb_get_dev_index(int index)
/* returns a pointer of a new device structure or NULL, if
* no device struct is available
*/
struct usb_device * usb_alloc_new_device ( void )
struct usb_device * usb_alloc_new_device ( void )
{
int i ;
USB_PRINTF ( " New Device %d \n " , dev_index ) ;
if ( dev_index = = USB_MAX_DEVICE ) {
printf ( " ERROR, too many USB Devices, max=%d \n " , USB_MAX_DEVICE ) ;
USB_PRINTF ( " New Device %d \n " , dev_index ) ;
if ( dev_index = = USB_MAX_DEVICE ) {
printf ( " ERROR, too many USB Devices, max=%d \n " , USB_MAX_DEVICE ) ;
return NULL ;
}
usb_dev [ dev_index ] . devnum = dev_index + 1 ; /* default Address is 0, real addresses start with 1 */
usb_dev [ dev_index ] . maxchild = 0 ;
for ( i = 0 ; i < USB_MAXCHILDREN ; i + + )
usb_dev [ dev_index ] . children [ i ] = NULL ;
usb_dev [ dev_index ] . parent = NULL ;
/* default Address is 0, real addresses start with 1 */
usb_dev [ dev_index ] . devnum = dev_index + 1 ;
usb_dev [ dev_index ] . maxchild = 0 ;
for ( i = 0 ; i < USB_MAXCHILDREN ; i + + )
usb_dev [ dev_index ] . children [ i ] = NULL ;
usb_dev [ dev_index ] . parent = NULL ;
dev_index + + ;
return & usb_dev [ dev_index - 1 ] ;
return & usb_dev [ dev_index - 1 ] ;
}
@ -788,7 +813,7 @@ int usb_new_device(struct usb_device *dev)
}
}
if ( port < 0 ) {
printf ( " usb_new_device: cannot locate device's port. . \n " ) ;
printf ( " usb_new_device:cannot locate device's port. \n " ) ;
return 1 ;
}
@ -803,7 +828,8 @@ int usb_new_device(struct usb_device *dev)
/* and this is the old and known way of initializing devices */
err = usb_get_descriptor ( dev , USB_DT_DEVICE , 0 , & dev - > descriptor , 8 ) ;
if ( err < 8 ) {
printf ( " \n USB device not responding, giving up (status=%lX) \n " , dev - > status ) ;
printf ( " \n USB device not responding, " \
" giving up (status=%lX) \n " , dev - > status ) ;
return 1 ;
}
# endif
@ -811,17 +837,18 @@ int usb_new_device(struct usb_device *dev)
dev - > epmaxpacketin [ 0 ] = dev - > descriptor . bMaxPacketSize0 ;
dev - > epmaxpacketout [ 0 ] = dev - > descriptor . bMaxPacketSize0 ;
switch ( dev - > descriptor . bMaxPacketSize0 ) {
case 8 : dev - > maxpacketsize = 0 ; break ;
case 16 : dev - > maxpacketsize = 1 ; break ;
case 32 : dev - > maxpacketsize = 2 ; break ;
case 64 : dev - > maxpacketsize = 3 ; break ;
case 8 : dev - > maxpacketsize = 0 ; break ;
case 16 : dev - > maxpacketsize = 1 ; break ;
case 32 : dev - > maxpacketsize = 2 ; break ;
case 64 : dev - > maxpacketsize = 3 ; break ;
}
dev - > devnum = addr ;
err = usb_set_address ( dev ) ; /* set address */
if ( err < 0 ) {
printf ( " \n USB device not accepting new address (error=%lX) \n " , dev - > status ) ;
printf ( " \n USB device not accepting new address " \
" (error=%lX) \n " , dev - > status ) ;
return 1 ;
}
@ -829,12 +856,15 @@ int usb_new_device(struct usb_device *dev)
tmp = sizeof ( dev - > descriptor ) ;
err = usb_get_descriptor ( dev , USB_DT_DEVICE , 0 , & dev - > descriptor , sizeof ( dev - > descriptor ) ) ;
err = usb_get_descriptor ( dev , USB_DT_DEVICE , 0 ,
& dev - > descriptor , sizeof ( dev - > descriptor ) ) ;
if ( err < tmp ) {
if ( err < 0 )
printf ( " unable to get device descriptor (error=%d) \n " , err ) ;
printf ( " unable to get device descriptor (error=%d) \n " ,
err ) ;
else
printf ( " USB device descriptor short read (expected %i, got %i) \n " , tmp , err ) ;
printf ( " USB device descriptor short read " \
" (expected %i, got %i) \n " , tmp , err ) ;
return 1 ;
}
/* correct le values */
@ -843,30 +873,35 @@ int usb_new_device(struct usb_device *dev)
le16_to_cpus ( & dev - > descriptor . idProduct ) ;
le16_to_cpus ( & dev - > descriptor . bcdDevice ) ;
/* only support for one config for now */
usb_get_configuration_no ( dev , & tmpbuf [ 0 ] , 0 ) ;
usb_parse_config ( dev , & tmpbuf [ 0 ] , 0 ) ;
usb_get_configuration_no ( dev , & tmpbuf [ 0 ] , 0 ) ;
usb_parse_config ( dev , & tmpbuf [ 0 ] , 0 ) ;
usb_set_maxpacket ( dev ) ;
/* we set the default configuration here */
if ( usb_set_configuration ( dev , dev - > config . bConfigurationValue ) ) {
printf ( " failed to set default configuration len %d, status %lX \n " , dev - > act_len , dev - > status ) ;
printf ( " failed to set default configuration " \
" len %d, status %lX \n " , dev - > act_len , dev - > status ) ;
return - 1 ;
}
USB_PRINTF ( " new device strings: Mfr=%d, Product=%d, SerialNumber=%d \n " ,
dev - > descriptor . iManufacturer , dev - > descriptor . iProduct , dev - > descriptor . iSerialNumber ) ;
dev - > descriptor . iManufacturer , dev - > descriptor . iProduct ,
dev - > descriptor . iSerialNumber ) ;
memset ( dev - > mf , 0 , sizeof ( dev - > mf ) ) ;
memset ( dev - > prod , 0 , sizeof ( dev - > prod ) ) ;
memset ( dev - > serial , 0 , sizeof ( dev - > serial ) ) ;
if ( dev - > descriptor . iManufacturer )
usb_string ( dev , dev - > descriptor . iManufacturer , dev - > mf , sizeof ( dev - > mf ) ) ;
usb_string ( dev , dev - > descriptor . iManufacturer ,
dev - > mf , sizeof ( dev - > mf ) ) ;
if ( dev - > descriptor . iProduct )
usb_string ( dev , dev - > descriptor . iProduct , dev - > prod , sizeof ( dev - > prod ) ) ;
usb_string ( dev , dev - > descriptor . iProduct ,
dev - > prod , sizeof ( dev - > prod ) ) ;
if ( dev - > descriptor . iSerialNumber )
usb_string ( dev , dev - > descriptor . iSerialNumber , dev - > serial , sizeof ( dev - > serial ) ) ;
usb_string ( dev , dev - > descriptor . iSerialNumber ,
dev - > serial , sizeof ( dev - > serial ) ) ;
USB_PRINTF ( " Manufacturer %s \n " , dev - > mf ) ;
USB_PRINTF ( " Product %s \n " , dev - > prod ) ;
USB_PRINTF ( " SerialNumber %s \n " , dev - > serial ) ;
/* now prode if the device is a hub */
usb_hub_probe ( dev , 0 ) ;
usb_hub_probe ( dev , 0 ) ;
return 0 ;
}
@ -877,15 +912,15 @@ void usb_scan_devices(void)
struct usb_device * dev ;
/* first make all devices unknown */
for ( i = 0 ; i < USB_MAX_DEVICE ; i + + ) {
memset ( & usb_dev [ i ] , 0 , sizeof ( struct usb_device ) ) ;
for ( i = 0 ; i < USB_MAX_DEVICE ; i + + ) {
memset ( & usb_dev [ i ] , 0 , sizeof ( struct usb_device ) ) ;
usb_dev [ i ] . devnum = - 1 ;
}
dev_index = 0 ;
dev_index = 0 ;
/* device 0 is always present (root hub, so let it analyze) */
dev = usb_alloc_new_device ( ) ;
dev = usb_alloc_new_device ( ) ;
usb_new_device ( dev ) ;
printf ( " %d USB Device(s) found \n " , dev_index ) ;
printf ( " %d USB Device(s) found \n " , dev_index ) ;
/* insert "driver" if possible */
# ifdef CONFIG_USB_KEYBOARD
drv_usb_kbd_init ( ) ;
@ -902,9 +937,9 @@ void usb_scan_devices(void)
# undef USB_HUB_DEBUG
# ifdef USB_HUB_DEBUG
# define USB_HUB_PRINTF(fmt,args...) printf (fmt ,##args)
# define USB_HUB_PRINTF(fmt, args...) printf (fmt , ##args)
# else
# define USB_HUB_PRINTF(fmt,args...)
# define USB_HUB_PRINTF(fmt, args...)
# endif
@ -922,19 +957,22 @@ int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
int usb_clear_hub_feature ( struct usb_device * dev , int feature )
{
return usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_CLEAR_FEATURE , USB_RT_HUB , feature , 0 , NULL , 0 , USB_CNTL_TIMEOUT ) ;
USB_REQ_CLEAR_FEATURE , USB_RT_HUB , feature ,
0 , NULL , 0 , USB_CNTL_TIMEOUT ) ;
}
int usb_clear_port_feature ( struct usb_device * dev , int port , int feature )
{
return usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_CLEAR_FEATURE , USB_RT_PORT , feature , port , NULL , 0 , USB_CNTL_TIMEOUT ) ;
USB_REQ_CLEAR_FEATURE , USB_RT_PORT , feature ,
port , NULL , 0 , USB_CNTL_TIMEOUT ) ;
}
int usb_set_port_feature ( struct usb_device * dev , int port , int feature )
{
return usb_control_msg ( dev , usb_sndctrlpipe ( dev , 0 ) ,
USB_REQ_SET_FEATURE , USB_RT_PORT , feature , port , NULL , 0 , USB_CNTL_TIMEOUT ) ;
USB_REQ_SET_FEATURE , USB_RT_PORT , feature ,
port , NULL , 0 , USB_CNTL_TIMEOUT ) ;
}
int usb_get_hub_status ( struct usb_device * dev , void * data )
@ -957,27 +995,27 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
int i ;
struct usb_device * dev ;
dev = hub - > pusb_dev ;
dev = hub - > pusb_dev ;
/* Enable power to the ports */
USB_HUB_PRINTF ( " enabling power on all ports \n " ) ;
for ( i = 0 ; i < dev - > maxchild ; i + + ) {
usb_set_port_feature ( dev , i + 1 , USB_PORT_FEAT_POWER ) ;
USB_HUB_PRINTF ( " port %d returns %lX \n " , i + 1 , dev - > status ) ;
USB_HUB_PRINTF ( " port %d returns %lX \n " , i + 1 , dev - > status ) ;
wait_ms ( hub - > desc . bPwrOn2PwrGood * 2 ) ;
}
}
void usb_hub_reset ( void )
{
usb_hub_index = 0 ;
usb_hub_index = 0 ;
}
struct usb_hub_device * usb_hub_allocate ( void )
{
if ( usb_hub_index < USB_MAX_HUB ) {
if ( usb_hub_index < USB_MAX_HUB )
return & hub_dev [ usb_hub_index + + ] ;
}
printf ( " ERROR: USB_MAX_HUB (%d) reached \n " , USB_MAX_HUB ) ;
printf ( " ERROR: USB_MAX_HUB (%d) reached \n " , USB_MAX_HUB ) ;
return NULL ;
}
@ -990,39 +1028,42 @@ static int hub_port_reset(struct usb_device *dev, int port,
struct usb_port_status portsts ;
unsigned short portstatus , portchange ;
USB_HUB_PRINTF ( " hub_port_reset: resetting port %d... \n " , port ) ;
for ( tries = 0 ; tries < MAX_TRIES ; tries + + ) {
for ( tries = 0 ; tries < MAX_TRIES ; tries + + ) {
usb_set_port_feature ( dev , port + 1 , USB_PORT_FEAT_RESET ) ;
wait_ms ( 200 ) ;
if ( usb_get_port_status ( dev , port + 1 , & portsts ) < 0 ) {
USB_HUB_PRINTF ( " get_port_status failed status %lX \n " , dev - > status ) ;
if ( usb_get_port_status ( dev , port + 1 , & portsts ) < 0 ) {
USB_HUB_PRINTF ( " get_port_status failed status %lX \n " ,
dev - > status ) ;
return - 1 ;
}
portstatus = le16_to_cpu ( portsts . wPortStatus ) ;
portchange = le16_to_cpu ( portsts . wPortChange ) ;
USB_HUB_PRINTF ( " portstatus %x, change %x, %s \n " , portstatus , portchange ,
portstatus & ( 1 < < USB_PORT_FEAT_LOWSPEED ) ? " Low Speed " : " High Speed " ) ;
USB_HUB_PRINTF ( " STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d \n " ,
USB_HUB_PRINTF ( " portstatus %x, change %x, %s \n " ,
portstatus , portchange ,
portstatus & ( 1 < < USB_PORT_FEAT_LOWSPEED ) ? \
" Low Speed " : " High Speed " ) ;
USB_HUB_PRINTF ( " STAT_C_CONNECTION = %d STAT_CONNECTION = %d " \
" USB_PORT_STAT_ENABLE %d \n " ,
( portchange & USB_PORT_STAT_C_CONNECTION ) ? 1 : 0 ,
( portstatus & USB_PORT_STAT_CONNECTION ) ? 1 : 0 ,
( portstatus & USB_PORT_STAT_ENABLE ) ? 1 : 0 ) ;
if ( ( portchange & USB_PORT_STAT_C_CONNECTION ) | |
! ( portstatus & USB_PORT_STAT_CONNECTION ) )
return - 1 ;
if ( portstatus & USB_PORT_STAT_ENABLE ) {
if ( portstatus & USB_PORT_STAT_ENABLE )
break ;
}
wait_ms ( 200 ) ;
}
if ( tries = = MAX_TRIES ) {
USB_HUB_PRINTF ( " Cannot enable port %i after %i retries, disabling port. \n " , port + 1 , MAX_TRIES ) ;
if ( tries = = MAX_TRIES ) {
USB_HUB_PRINTF ( " Cannot enable port %i after %i retries, " \
" disabling port. \n " , port + 1 , MAX_TRIES ) ;
USB_HUB_PRINTF ( " Maybe the USB cable is bad? \n " ) ;
return - 1 ;
}
@ -1030,7 +1071,6 @@ static int hub_port_reset(struct usb_device *dev, int port,
usb_clear_port_feature ( dev , port + 1 , USB_PORT_FEAT_C_RESET ) ;
* portstat = portstatus ;
return 0 ;
}
@ -1041,22 +1081,24 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
unsigned short portstatus , portchange ;
/* Check status */
if ( usb_get_port_status ( dev , port + 1 , & portsts ) < 0 ) {
if ( usb_get_port_status ( dev , port + 1 , & portsts ) < 0 ) {
USB_HUB_PRINTF ( " get_port_status failed \n " ) ;
return ;
}
portstatus = le16_to_cpu ( portsts . wPortStatus ) ;
portchange = le16_to_cpu ( portsts . wPortChange ) ;
USB_HUB_PRINTF ( " portstatus %x, change %x, %s \n " , portstatus , portchange ,
portstatus & ( 1 < < USB_PORT_FEAT_LOWSPEED ) ? " Low Speed " : " High Speed " ) ;
USB_HUB_PRINTF ( " portstatus %x, change %x, %s \n " ,
portstatus , portchange ,
portstatus & ( 1 < < USB_PORT_FEAT_LOWSPEED ) ? \
" Low Speed " : " High Speed " ) ;
/* Clear the connection change status */
usb_clear_port_feature ( dev , port + 1 , USB_PORT_FEAT_C_CONNECTION ) ;
/* Disconnect any existing devices under this port */
if ( ( ( ! ( portstatus & USB_PORT_STAT_CONNECTION ) ) & &
( ! ( portstatus & USB_PORT_STAT_ENABLE ) ) ) | | ( dev - > children [ port ] ) ) {
( ! ( portstatus & USB_PORT_STAT_ENABLE ) ) ) | | ( dev - > children [ port ] ) ) {
USB_HUB_PRINTF ( " usb_disconnect(&hub->children[port]); \n " ) ;
/* Return now if nothing is connected */
if ( ! ( portstatus & USB_PORT_STAT_CONNECTION ) )
@ -1073,11 +1115,11 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
wait_ms ( 200 ) ;
/* Allocate a new device struct for it */
usb = usb_alloc_new_device ( ) ;
usb = usb_alloc_new_device ( ) ;
usb - > slow = ( portstatus & USB_PORT_STAT_LOW_SPEED ) ? 1 : 0 ;
dev - > children [ port ] = usb ;
usb - > parent = dev ;
usb - > parent = dev ;
/* Run it through the hoops (find a driver, etc) */
if ( usb_new_device ( usb ) ) {
/* Woops, disable the port */
@ -1096,13 +1138,14 @@ int usb_hub_configure(struct usb_device *dev)
struct usb_hub_device * hub ;
/* "allocate" Hub device */
hub = usb_hub_allocate ( ) ;
if ( hub = = NULL )
hub = usb_hub_allocate ( ) ;
if ( hub = = NULL )
return - 1 ;
hub - > pusb_dev = dev ;
hub - > pusb_dev = dev ;
/* Get the the hub descriptor */
if ( usb_get_hub_descriptor ( dev , buffer , 4 ) < 0 ) {
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub descriptor, giving up %lX \n " , dev - > status ) ;
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub " \
" descriptor, giving up %lX \n " , dev - > status ) ;
return - 1 ;
}
descriptor = ( struct usb_hub_descriptor * ) buffer ;
@ -1110,43 +1153,48 @@ int usb_hub_configure(struct usb_device *dev)
/* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */
i = descriptor - > bLength ;
if ( i > USB_BUFSIZ ) {
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub descriptor - too long: %d \n " ,
descriptor - > bLength ) ;
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub " \
" descriptor - too long: %d \n " ,
descriptor - > bLength ) ;
return - 1 ;
}
if ( usb_get_hub_descriptor ( dev , buffer , descriptor - > bLength ) < 0 ) {
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub descriptor 2nd giving up %lX \n " , dev - > status ) ;
USB_HUB_PRINTF ( " usb_hub_configure: failed to get hub " \
" descriptor 2nd giving up %lX \n " , dev - > status ) ;
return - 1 ;
}
memcpy ( ( unsigned char * ) & hub - > desc , buffer , descriptor - > bLength ) ;
memcpy ( ( unsigned char * ) & hub - > desc , buffer , descriptor - > bLength ) ;
/* adjust 16bit values */
hub - > desc . wHubCharacteristics = le16_to_cpu ( descriptor - > wHubCharacteristics ) ;
hub - > desc . wHubCharacteristics =
le16_to_cpu ( descriptor - > wHubCharacteristics ) ;
/* set the bitmap */
bitmap = ( unsigned char * ) & hub - > desc . DeviceRemovable [ 0 ] ;
memset ( bitmap , 0xff , ( USB_MAXCHILDREN + 1 + 7 ) / 8 ) ; /* devices not removable by default */
bitmap = ( unsigned char * ) & hub - > desc . PortPowerCtrlMask [ 0 ] ;
memset ( bitmap , 0xff , ( USB_MAXCHILDREN + 1 + 7 ) / 8 ) ; /* PowerMask = 1B */
for ( i = 0 ; i < ( ( hub - > desc . bNbrPorts + 1 + 7 ) / 8 ) ; i + + ) {
hub - > desc . DeviceRemovable [ i ] = descriptor - > DeviceRemovable [ i ] ;
}
for ( i = 0 ; i < ( ( hub - > desc . bNbrPorts + 1 + 7 ) / 8 ) ; i + + ) {
hub - > desc . DeviceRemovable [ i ] = descriptor - > PortPowerCtrlMask [ i ] ;
}
bitmap = ( unsigned char * ) & hub - > desc . DeviceRemovable [ 0 ] ;
/* devices not removable by default */
memset ( bitmap , 0xff , ( USB_MAXCHILDREN + 1 + 7 ) / 8 ) ;
bitmap = ( unsigned char * ) & hub - > desc . PortPowerCtrlMask [ 0 ] ;
memset ( bitmap , 0xff , ( USB_MAXCHILDREN + 1 + 7 ) / 8 ) ; /* PowerMask = 1B */
for ( i = 0 ; i < ( ( hub - > desc . bNbrPorts + 1 + 7 ) / 8 ) ; i + + )
hub - > desc . DeviceRemovable [ i ] = descriptor - > DeviceRemovable [ i ] ;
for ( i = 0 ; i < ( ( hub - > desc . bNbrPorts + 1 + 7 ) / 8 ) ; i + + )
hub - > desc . DeviceRemovable [ i ] = descriptor - > PortPowerCtrlMask [ i ] ;
dev - > maxchild = descriptor - > bNbrPorts ;
USB_HUB_PRINTF ( " %d ports detected \n " , dev - > maxchild ) ;
switch ( hub - > desc . wHubCharacteristics & HUB_CHAR_LPSM ) {
case 0x00 :
USB_HUB_PRINTF ( " ganged power switching \n " ) ;
break ;
case 0x01 :
USB_HUB_PRINTF ( " individual port power switching \n " ) ;
break ;
case 0x02 :
case 0x03 :
USB_HUB_PRINTF ( " unknown reserved power switching mode \n " ) ;
break ;
case 0x00 :
USB_HUB_PRINTF ( " ganged power switching \n " ) ;
break ;
case 0x01 :
USB_HUB_PRINTF ( " individual port power switching \n " ) ;
break ;
case 0x02 :
case 0x03 :
USB_HUB_PRINTF ( " unknown reserved power switching mode \n " ) ;
break ;
}
if ( hub - > desc . wHubCharacteristics & HUB_CHAR_COMPOUND )
@ -1155,40 +1203,52 @@ int usb_hub_configure(struct usb_device *dev)
USB_HUB_PRINTF ( " standalone hub \n " ) ;
switch ( hub - > desc . wHubCharacteristics & HUB_CHAR_OCPM ) {
case 0x00 :
USB_HUB_PRINTF ( " global over-current protection \n " ) ;
break ;
case 0x08 :
USB_HUB_PRINTF ( " individual port over-current protection \n " ) ;
break ;
case 0x10 :
case 0x18 :
USB_HUB_PRINTF ( " no over-current protection \n " ) ;
break ;
case 0x00 :
USB_HUB_PRINTF ( " global over-current protection \n " ) ;
break ;
case 0x08 :
USB_HUB_PRINTF ( " individual port over-current protection \n " ) ;
break ;
case 0x10 :
case 0x18 :
USB_HUB_PRINTF ( " no over-current protection \n " ) ;
break ;
}
USB_HUB_PRINTF ( " power on to power good time: %dms \n " , descriptor - > bPwrOn2PwrGood * 2 ) ;
USB_HUB_PRINTF ( " hub controller current requirement: %dmA \n " , descriptor - > bHubContrCurrent ) ;
USB_HUB_PRINTF ( " power on to power good time: %dms \n " ,
descriptor - > bPwrOn2PwrGood * 2 ) ;
USB_HUB_PRINTF ( " hub controller current requirement: %dmA \n " ,
descriptor - > bHubContrCurrent ) ;
for ( i = 0 ; i < dev - > maxchild ; i + + )
USB_HUB_PRINTF ( " port %d is%s removable \n " , i + 1 ,
hub - > desc . DeviceRemovable [ ( i + 1 ) / 8 ] & ( 1 < < ( ( i + 1 ) % 8 ) ) ? " not " : " " ) ;
hub - > desc . DeviceRemovable [ ( i + 1 ) / 8 ] & \
( 1 < < ( ( i + 1 ) % 8 ) ) ? " not " : " " ) ;
if ( sizeof ( struct usb_hub_status ) > USB_BUFSIZ ) {
USB_HUB_PRINTF ( " usb_hub_configure: failed to get Status - too long: %d \n " ,
descriptor - > bLength ) ;
USB_HUB_PRINTF ( " usb_hub_configure: failed to get Status - " \
" too long: %d \n " , descriptor - > bLength ) ;
return - 1 ;
}
if ( usb_get_hub_status ( dev , buffer ) < 0 ) {
USB_HUB_PRINTF ( " usb_hub_configure: failed to get Status %lX \n " , dev - > status ) ;
USB_HUB_PRINTF ( " usb_hub_configure: failed to get Status %lX \n " ,
dev - > status ) ;
return - 1 ;
}
hubsts = ( struct usb_hub_status * ) buffer ;
USB_HUB_PRINTF ( " get_hub_status returned status %X, change %X \n " ,
le16_to_cpu ( hubsts - > wHubStatus ) , le16_to_cpu ( hubsts - > wHubChange ) ) ;
le16_to_cpu ( hubsts - > wHubStatus ) ,
le16_to_cpu ( hubsts - > wHubChange ) ) ;
USB_HUB_PRINTF ( " local power source is %s \n " ,
( le16_to_cpu ( hubsts - > wHubStatus ) & HUB_STATUS_LOCAL_POWER ) ? " lost (inactive) " : " good " ) ;
( le16_to_cpu ( hubsts - > wHubStatus ) & HUB_STATUS_LOCAL_POWER ) ? \
" lost (inactive) " : " good " ) ;
USB_HUB_PRINTF ( " %sover-current condition exists \n " ,
( le16_to_cpu ( hubsts - > wHubStatus ) & HUB_STATUS_OVERCURRENT ) ? " " : " no " ) ;
( le16_to_cpu ( hubsts - > wHubStatus ) & HUB_STATUS_OVERCURRENT ) ? \
" " : " no " ) ;
usb_hub_power_on ( hub ) ;
for ( i = 0 ; i < dev - > maxchild ; i + + ) {
struct usb_port_status portsts ;
unsigned short portstatus , portchange ;
@ -1197,41 +1257,51 @@ int usb_hub_configure(struct usb_device *dev)
USB_HUB_PRINTF ( " get_port_status failed \n " ) ;
continue ;
}
portstatus = le16_to_cpu ( portsts . wPortStatus ) ;
portchange = le16_to_cpu ( portsts . wPortChange ) ;
USB_HUB_PRINTF ( " Port %d Status %X Change %X \n " , i + 1 , portstatus , portchange ) ;
USB_HUB_PRINTF ( " Port %d Status %X Change %X \n " ,
i + 1 , portstatus , portchange ) ;
if ( portchange & USB_PORT_STAT_C_CONNECTION ) {
USB_HUB_PRINTF ( " port %d connection change \n " , i + 1 ) ;
usb_hub_port_connect_change ( dev , i ) ;
}
if ( portchange & USB_PORT_STAT_C_ENABLE ) {
USB_HUB_PRINTF ( " port %d enable change, status %x \n " , i + 1 , portstatus ) ;
usb_clear_port_feature ( dev , i + 1 , USB_PORT_FEAT_C_ENABLE ) ;
/* EM interference sometimes causes bad shielded USB devices to
* be shutdown by the hub , this hack enables them again .
* Works at least with mouse driver */
USB_HUB_PRINTF ( " port %d enable change, status %x \n " ,
i + 1 , portstatus ) ;
usb_clear_port_feature ( dev , i + 1 ,
USB_PORT_FEAT_C_ENABLE ) ;
/* EM interference sometimes causes bad shielded USB
* devices to be shutdown by the hub , this hack enables
* them again . Works at least with mouse driver */
if ( ! ( portstatus & USB_PORT_STAT_ENABLE ) & &
( portstatus & USB_PORT_STAT_CONNECTION ) & & ( dev - > children [ i ] ) ) {
USB_HUB_PRINTF ( " already running port %i disabled by hub (EMI?), re-enabling... \n " ,
i + 1 ) ;
( portstatus & USB_PORT_STAT_CONNECTION ) & &
( ( dev - > children [ i ] ) ) ) {
USB_HUB_PRINTF ( " already running port %i " \
" disabled by hub (EMI?), " \
" re-enabling... \n " , i + 1 ) ;
usb_hub_port_connect_change ( dev , i ) ;
}
}
if ( portstatus & USB_PORT_STAT_SUSPEND ) {
USB_HUB_PRINTF ( " port %d suspend change \n " , i + 1 ) ;
usb_clear_port_feature ( dev , i + 1 , USB_PORT_FEAT_SUSPEND ) ;
usb_clear_port_feature ( dev , i + 1 ,
USB_PORT_FEAT_SUSPEND ) ;
}
if ( portchange & USB_PORT_STAT_C_OVERCURRENT ) {
USB_HUB_PRINTF ( " port %d over-current change \n " , i + 1 ) ;
usb_clear_port_feature ( dev , i + 1 , USB_PORT_FEAT_C_OVER_CURRENT ) ;
usb_clear_port_feature ( dev , i + 1 ,
USB_PORT_FEAT_C_OVER_CURRENT ) ;
usb_hub_power_on ( hub ) ;
}
if ( portchange & USB_PORT_STAT_C_RESET ) {
USB_HUB_PRINTF ( " port %d reset change \n " , i + 1 ) ;
usb_clear_port_feature ( dev , i + 1 , USB_PORT_FEAT_C_RESET ) ;
usb_clear_port_feature ( dev , i + 1 ,
USB_PORT_FEAT_C_RESET ) ;
}
} /* end for i all ports */
@ -1265,7 +1335,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
return 0 ;
/* We found a hub */
USB_HUB_PRINTF ( " USB hub found \n " ) ;
ret = usb_hub_configure ( dev ) ;
ret = usb_hub_configure ( dev ) ;
return ret ;
}