Refactoring parts of the common USB OHCI code
This patch refactors some large routines of the USB OHCI code by making some routines smaller and more readable which helps debugging and understanding the code. (Makes the code looks somewhat more like the Linux implementation.) Also made entire file compliant to Linux Coding Rules (checkpatch.pl compliant) Signed-off-by: Remy Bohmer <linux@bohmer.net> Signed-off-by: Markus Klotzbuecher <mk@denx.de>
This commit is contained in:
parent
be19d324ed
commit
6f5794a6f7
540
common/usb.c
540
common/usb.c
@ -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);
|
||||
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 */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,41 @@ static int cc_to_error[16] = {
|
||||
/* Not Access */ -1
|
||||
};
|
||||
|
||||
static const char *cc_to_string[16] = {
|
||||
"No Error",
|
||||
"CRC: Last data packet from endpoint contained a CRC error.",
|
||||
"BITSTUFFING: Last data packet from endpoint contained a bit " \
|
||||
"stuffing violation",
|
||||
"DATATOGGLEMISMATCH: Last packet from endpoint had data toggle PID\n" \
|
||||
"that did not match the expected value.",
|
||||
"STALL: TD was moved to the Done Queue because the endpoint returned" \
|
||||
" a STALL PID",
|
||||
"DEVICENOTRESPONDING: Device did not respond to token (IN) or did\n" \
|
||||
"not provide a handshake (OUT)",
|
||||
"PIDCHECKFAILURE: Check bits on PID from endpoint failed on data PID\n"\
|
||||
"(IN) or handshake (OUT)",
|
||||
"UNEXPECTEDPID: Receive PID was not valid when encountered or PID\n" \
|
||||
"value is not defined.",
|
||||
"DATAOVERRUN: The amount of data returned by the endpoint exceeded\n" \
|
||||
"either the size of the maximum data packet allowed\n" \
|
||||
"from the endpoint (found in MaximumPacketSize field\n" \
|
||||
"of ED) or the remaining buffer size.",
|
||||
"DATAUNDERRUN: The endpoint returned less than MaximumPacketSize\n" \
|
||||
"and that amount was not sufficient to fill the\n" \
|
||||
"specified buffer",
|
||||
"reserved1",
|
||||
"reserved2",
|
||||
"BUFFEROVERRUN: During an IN, HC received data from endpoint faster\n" \
|
||||
"than it could be written to system memory",
|
||||
"BUFFERUNDERRUN: During an OUT, HC could not retrieve data from\n" \
|
||||
"system memory fast enough to keep up with data USB " \
|
||||
"data rate.",
|
||||
"NOT ACCESSED: This code is set by software before the TD is placed" \
|
||||
"on a list to be processed by the HC.(1)",
|
||||
"NOT ACCESSED: This code is set by software before the TD is placed" \
|
||||
"on a list to be processed by the HC.(2)",
|
||||
};
|
||||
|
||||
/* ED States */
|
||||
|
||||
#define ED_NEW 0x00
|
||||
|
Loading…
Reference in New Issue
Block a user