X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fusb.c;h=4df01eabe513163eeb80475f9495b72ea504ac80;hb=5e3dca577b7c1bf58bd2b48449b18b7e7dcd8e04;hp=1738d950614154374b0a7a72fefe448a0d95920e;hpb=9c998aa83148c75cd734a18958218926313bd54c;p=oweals%2Fu-boot.git diff --git a/common/usb.c b/common/usb.c index 1738d95061..4df01eabe5 100644 --- a/common/usb.c +++ b/common/usb.c @@ -1,9 +1,19 @@ /* - * (C) Copyright 2001 - * Denis Peter, MPL AG Switzerland * * Most of this source has been derived from the Linux USB - * project. + * project: + * (C) Copyright Linus Torvalds 1999 + * (C) Copyright Johannes Erdfelt 1999-2001 + * (C) Copyright Andreas Gal 1999 + * (C) Copyright Gregory P. Smith 1999 + * (C) Copyright Deti Fliegl 1999 (new USB architecture) + * (C) Copyright Randy Dunlap 2000 + * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id) + * (C) Copyright Yggdrasil Computing, Inc. 2000 + * (usb_device_id matching changes by Adam J. Richter) + * + * Adapted for U-Boot: + * (C) Copyright 2001 Denis Peter, MPL AG Switzerland * * See file CREDITS for list of people who contributed to this * project. @@ -39,15 +49,14 @@ #include #include -#if (CONFIG_COMMANDS & CFG_CMD_USB) +#if defined(CONFIG_CMD_USB) #include #ifdef CONFIG_4xx -#include <405gp_pci.h> +#include #endif - -#undef USB_DEBUG +#undef USB_DEBUG #ifdef USB_DEBUG #define USB_PRINTF(fmt,args...) printf (fmt ,##args) @@ -63,6 +72,8 @@ static int running; static int asynch_allowed; static struct devrequest setup_packet; +char usb_started; /* flag for the started/stopped USB status */ + /********************************************************************** * some forward declerations... */ @@ -101,10 +112,12 @@ int usb_init(void) printf("scanning bus for devices... "); running=1; usb_scan_devices(); + usb_started = 1; return 0; } else { printf("Error, couldn't init Lowlevel part\n"); + usb_started = 0; return -1; } } @@ -115,6 +128,7 @@ int usb_init(void) int usb_stop(void) { asynch_allowed=1; + usb_started = 0; usb_hub_reset(); return usb_lowlevel_stop(); } @@ -271,56 +285,68 @@ int usb_set_maxpacket(struct usb_device *dev) int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) { struct usb_descriptor_header *head; - int index,ifno,epno; - ifno=-1; - epno=-1; - - 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); + int index, ifno, epno, curr_if_num; + int i; + unsigned char *ch; + + ifno = -1; + epno = -1; + curr_if_num = -1; + + 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); return -1; } - memcpy(&dev->config,buffer,buffer[0]); - dev->config.wTotalLength=swap_16(dev->config.wTotalLength); - dev->config.no_of_if=0; + memcpy(&dev->config, buffer, buffer[0]); + dev->config.wTotalLength = swap_16(dev->config.wTotalLength); + dev->config.no_of_if = 0; - index=dev->config.bLength; + index = dev->config.bLength; /* 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) { + head = (struct usb_descriptor_header *) &buffer[index]; + while(index + 1 < dev->config.wTotalLength) { switch(head->bDescriptorType) { case USB_DT_INTERFACE: - ifno=dev->config.no_of_if; - dev->config.no_of_if++; /* found an interface desc, increase numbers */ - memcpy(&dev->config.if_desc[ifno],&buffer[index],buffer[index]); /* copy new desc */ - dev->config.if_desc[ifno].no_of_ep=0; - + 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; + 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],&buffer[index],buffer[index]); - 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); + memcpy(&dev->config.if_desc[ifno].ep_desc[epno], + &buffer[index], buffer[index]); + 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); break; default: - if(head->bLength==0) + if(head->bLength == 0) 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; - for(i=0;ibLength; i++) - USB_PRINTF("%02X ",*ch++); + 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]; + index += head->bLength; + head = (struct usb_descriptor_header *)&buffer[index]; } return 1; } @@ -342,7 +368,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe) if (result < 0) return result; - /* + /* * NOTE: we do not get status and verify reset was successful * as some devices are reported to lock up upon this check.. */ @@ -434,6 +460,14 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) printf("selecting invalid interface %d", interface); 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), USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate, @@ -517,13 +551,13 @@ int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char /* some devices are flaky */ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (USB_DT_STRING << 8) + index, langid, buf, size, + (USB_DT_STRING << 8) + index, langid, buf, size, USB_CNTL_TIMEOUT); if (result > 0) break; - } - + } + return result; } @@ -572,7 +606,7 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, } if (rc < 2) - rc = -1; + rc = -1; return rc; } @@ -721,10 +755,10 @@ int usb_new_device(struct usb_device *dev) } } dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0; - + /* find the port number we're at */ if (parent) { - + for (j = 0; j < parent->maxchild; j++) { if (parent->children[j] == dev) { port = j; @@ -958,7 +992,7 @@ static int hub_port_reset(struct usb_device *dev, int port, return -1; if (portstatus & USB_PORT_STAT_ENABLE) { - + break; } @@ -1213,6 +1247,6 @@ int usb_hub_probe(struct usb_device *dev, int ifnum) return ret; } -#endif /* (CONFIG_COMMANDS & CFG_CMD_USB) */ +#endif /* EOF */