Merge with /home/tur/proj/usb_sticks/u-boot

This commit is contained in:
Wolfgang Denk 2006-08-07 20:28:05 +02:00
commit 6587f7e1e9
4 changed files with 70 additions and 33 deletions

View File

@ -2,6 +2,12 @@
Changes since U-Boot 1.1.4: Changes since U-Boot 1.1.4:
====================================================================== ======================================================================
* Prevent USB commands from working when USB is stopped.
* Add rudimentary handling of alternate settings of USB interfaces.
This is in order to fix issues with some USB sticks timing out
during initialization. Some code readability improvements.
* PPC440 DDR setup: Set SDRAM0_CFG0[PMU]=0 for best performance * PPC440 DDR setup: Set SDRAM0_CFG0[PMU]=0 for best performance
AMCC suggested to set the PMU bit to 0 for best performace on AMCC suggested to set the PMU bit to 0 for best performace on
the PPC440 DDR controller. the PPC440 DDR controller.

View File

@ -186,7 +186,7 @@ void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_devic
void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev) void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev)
{ {
printf(" Interface: %d\n",ifdesc->bInterfaceNumber); printf(" Interface: %d\n",ifdesc->bInterfaceNumber);
printf(" - Alternate Settings %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints); printf(" - Alternate Setting %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints);
printf(" - Class "); printf(" - Class ");
usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol); usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol);
printf("\n"); printf("\n");
@ -444,6 +444,7 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
int i; int i;
struct usb_device *dev = NULL; struct usb_device *dev = NULL;
extern char usb_started;
#ifdef CONFIG_USB_STORAGE #ifdef CONFIG_USB_STORAGE
block_dev_desc_t *stor_dev; block_dev_desc_t *stor_dev;
#endif #endif
@ -477,6 +478,10 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
usb_stop(); usb_stop();
return 0; return 0;
} }
if (!usb_started) {
printf("USB is stopped. Please issue 'usb start' first.\n");
return 1;
}
if (strncmp(argv[1],"tree",4) == 0) { if (strncmp(argv[1],"tree",4) == 0) {
printf("\nDevice Tree:\n"); printf("\nDevice Tree:\n");
usb_show_tree(usb_get_dev_index(0)); usb_show_tree(usb_get_dev_index(0));

View File

@ -72,6 +72,8 @@ static int running;
static int asynch_allowed; static int asynch_allowed;
static struct devrequest setup_packet; static struct devrequest setup_packet;
char usb_started; /* flag for the started/stopped USB status */
/********************************************************************** /**********************************************************************
* some forward declerations... * some forward declerations...
*/ */
@ -110,10 +112,12 @@ int usb_init(void)
printf("scanning bus for devices... "); printf("scanning bus for devices... ");
running=1; running=1;
usb_scan_devices(); usb_scan_devices();
usb_started = 1;
return 0; return 0;
} }
else { else {
printf("Error, couldn't init Lowlevel part\n"); printf("Error, couldn't init Lowlevel part\n");
usb_started = 0;
return -1; return -1;
} }
} }
@ -124,6 +128,7 @@ int usb_init(void)
int usb_stop(void) int usb_stop(void)
{ {
asynch_allowed=1; asynch_allowed=1;
usb_started = 0;
usb_hub_reset(); usb_hub_reset();
return usb_lowlevel_stop(); return usb_lowlevel_stop();
} }
@ -280,9 +285,13 @@ int usb_set_maxpacket(struct usb_device *dev)
int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
{ {
struct usb_descriptor_header *head; struct usb_descriptor_header *head;
int index,ifno,epno; int index, ifno, epno, curr_if_num;
int i;
unsigned char *ch;
ifno = -1; ifno = -1;
epno = -1; epno = -1;
curr_if_num = -1;
dev->configno = cfgno; dev->configno = cfgno;
head = (struct usb_descriptor_header *) &buffer[0]; head = (struct usb_descriptor_header *) &buffer[0];
@ -300,18 +309,28 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
while(index + 1 < dev->config.wTotalLength) { while(index + 1 < dev->config.wTotalLength) {
switch(head->bDescriptorType) { switch(head->bDescriptorType) {
case USB_DT_INTERFACE: 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; ifno = dev->config.no_of_if;
dev->config.no_of_if++; /* found an interface desc, increase numbers */ dev->config.no_of_if++;
memcpy(&dev->config.if_desc[ifno],&buffer[index],buffer[index]); /* copy new desc */ memcpy(&dev->config.if_desc[ifno],
&buffer[index], buffer[index]);
dev->config.if_desc[ifno].no_of_ep = 0; 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; break;
case USB_DT_ENDPOINT: case USB_DT_ENDPOINT:
epno = dev->config.if_desc[ifno].no_of_ep; epno = dev->config.if_desc[ifno].no_of_ep;
dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */ dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */
memcpy(&dev->config.if_desc[ifno].ep_desc[epno],&buffer[index],buffer[index]); memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize &buffer[index], buffer[index]);
=swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize); dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize =
swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize);
USB_PRINTF("if %d, ep %d\n", ifno, epno); USB_PRINTF("if %d, ep %d\n", ifno, epno);
break; break;
default: default:
@ -319,8 +338,6 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
return 1; return 1;
USB_PRINTF("unknown Description Type : %x\n", head->bDescriptorType); USB_PRINTF("unknown Description Type : %x\n", head->bDescriptorType);
{ {
int i;
unsigned char *ch;
ch = (unsigned char *)head; ch = (unsigned char *)head;
for(i = 0; i < head->bLength; i++) for(i = 0; i < head->bLength; i++)
USB_PRINTF("%02X ", *ch++); USB_PRINTF("%02X ", *ch++);
@ -443,6 +460,14 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
printf("selecting invalid interface %d", interface); printf("selecting invalid interface %d", interface);
return -1; return -1;
} }
/*
* 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.
*/
if (if_face->num_altsetting == 1)
return 0;
if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate, USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,

View File

@ -108,6 +108,7 @@ struct usb_interface_descriptor {
unsigned char iInterface; unsigned char iInterface;
unsigned char no_of_ep; unsigned char no_of_ep;
unsigned char num_altsetting;
unsigned char act_altsetting; unsigned char act_altsetting;
struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS]; struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
} __attribute__ ((packed)); } __attribute__ ((packed));