183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2affae2bfSwdenk /* 3affae2bfSwdenk * Most of this source has been derived from the Linux USB 4460c322fSWolfgang Denk * project: 5460c322fSWolfgang Denk * (C) Copyright Linus Torvalds 1999 6460c322fSWolfgang Denk * (C) Copyright Johannes Erdfelt 1999-2001 7460c322fSWolfgang Denk * (C) Copyright Andreas Gal 1999 8460c322fSWolfgang Denk * (C) Copyright Gregory P. Smith 1999 9460c322fSWolfgang Denk * (C) Copyright Deti Fliegl 1999 (new USB architecture) 10460c322fSWolfgang Denk * (C) Copyright Randy Dunlap 2000 11460c322fSWolfgang Denk * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id) 12460c322fSWolfgang Denk * (C) Copyright Yggdrasil Computing, Inc. 2000 13460c322fSWolfgang Denk * (usb_device_id matching changes by Adam J. Richter) 14460c322fSWolfgang Denk * 15460c322fSWolfgang Denk * Adapted for U-Boot: 16460c322fSWolfgang Denk * (C) Copyright 2001 Denis Peter, MPL AG Switzerland 17affae2bfSwdenk */ 18affae2bfSwdenk 19affae2bfSwdenk /* 20affae2bfSwdenk * How it works: 21affae2bfSwdenk * 22affae2bfSwdenk * Since this is a bootloader, the devices will not be automatic 23affae2bfSwdenk * (re)configured on hotplug, but after a restart of the USB the 24affae2bfSwdenk * device should work. 25affae2bfSwdenk * 26affae2bfSwdenk * For each transfer (except "Interrupt") we wait for completion. 27affae2bfSwdenk */ 28affae2bfSwdenk #include <common.h> 29affae2bfSwdenk #include <command.h> 3095fbfe42SSimon Glass #include <dm.h> 31cf92e05cSSimon Glass #include <memalign.h> 32affae2bfSwdenk #include <asm/processor.h> 3366cf6410SMike Frysinger #include <linux/compiler.h> 349c998aa8SWolfgang Denk #include <linux/ctype.h> 35c918261cSChristian Eggers #include <asm/byteorder.h> 36b2fb47f1STom Rini #include <asm/unaligned.h> 3797b9eb9eSMarek Vasut #include <errno.h> 38affae2bfSwdenk #include <usb.h> 39affae2bfSwdenk 40cd0a9de6Swdenk #define USB_BUFSIZ 512 41cd0a9de6Swdenk 4295fbfe42SSimon Glass static int asynch_allowed; 4395fbfe42SSimon Glass char usb_started; /* flag for the started/stopped USB status */ 4495fbfe42SSimon Glass 45*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB) 46affae2bfSwdenk static struct usb_device usb_dev[USB_MAX_DEVICE]; 47affae2bfSwdenk static int dev_index; 48e51aae38SBartlomiej Sieka 4993c2582fSLucas Stach #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT 5093c2582fSLucas Stach #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 5193c2582fSLucas Stach #endif 52affae2bfSwdenk 53affae2bfSwdenk /*************************************************************************** 54affae2bfSwdenk * Init USB Device 55affae2bfSwdenk */ 56affae2bfSwdenk int usb_init(void) 57affae2bfSwdenk { 5893c2582fSLucas Stach void *ctrl; 5993c2582fSLucas Stach struct usb_device *dev; 6093c2582fSLucas Stach int i, start_index = 0; 61d906bbc2SHans de Goede int controllers_initialized = 0; 6297b9eb9eSMarek Vasut int ret; 63affae2bfSwdenk 64affae2bfSwdenk dev_index = 0; 65affae2bfSwdenk asynch_allowed = 1; 66affae2bfSwdenk usb_hub_reset(); 6793c2582fSLucas Stach 6893c2582fSLucas Stach /* first make all devices unknown */ 6993c2582fSLucas Stach for (i = 0; i < USB_MAX_DEVICE; i++) { 7093c2582fSLucas Stach memset(&usb_dev[i], 0, sizeof(struct usb_device)); 7193c2582fSLucas Stach usb_dev[i].devnum = -1; 7293c2582fSLucas Stach } 7393c2582fSLucas Stach 74affae2bfSwdenk /* init low_level USB */ 7593c2582fSLucas Stach for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { 7693c2582fSLucas Stach /* init low_level USB */ 7793c2582fSLucas Stach printf("USB%d: ", i); 7897b9eb9eSMarek Vasut ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl); 7997b9eb9eSMarek Vasut if (ret == -ENODEV) { /* No such device. */ 8097b9eb9eSMarek Vasut puts("Port not available.\n"); 81d906bbc2SHans de Goede controllers_initialized++; 8297b9eb9eSMarek Vasut continue; 8397b9eb9eSMarek Vasut } 8497b9eb9eSMarek Vasut 8597b9eb9eSMarek Vasut if (ret) { /* Other error. */ 8693c2582fSLucas Stach puts("lowlevel init failed\n"); 8793c2582fSLucas Stach continue; 8893c2582fSLucas Stach } 8993c2582fSLucas Stach /* 9093c2582fSLucas Stach * lowlevel init is OK, now scan the bus for devices 9193c2582fSLucas Stach * i.e. search HUBs and configure them 9293c2582fSLucas Stach */ 93d906bbc2SHans de Goede controllers_initialized++; 9493c2582fSLucas Stach start_index = dev_index; 9593c2582fSLucas Stach printf("scanning bus %d for devices... ", i); 9679b58887SSimon Glass ret = usb_alloc_new_device(ctrl, &dev); 9779b58887SSimon Glass if (ret) 988879be88SPaul Kocialkowski break; 998879be88SPaul Kocialkowski 10093c2582fSLucas Stach /* 10193c2582fSLucas Stach * device 0 is always present 10293c2582fSLucas Stach * (root hub, so let it analyze) 10393c2582fSLucas Stach */ 1048879be88SPaul Kocialkowski ret = usb_new_device(dev); 1058879be88SPaul Kocialkowski if (ret) 10679b58887SSimon Glass usb_free_device(dev->controller); 10793c2582fSLucas Stach 1088879be88SPaul Kocialkowski if (start_index == dev_index) { 10993c2582fSLucas Stach puts("No USB Device found\n"); 1108879be88SPaul Kocialkowski continue; 1118879be88SPaul Kocialkowski } else { 11293c2582fSLucas Stach printf("%d USB Device(s) found\n", 11393c2582fSLucas Stach dev_index - start_index); 1148879be88SPaul Kocialkowski } 11593c2582fSLucas Stach 116e51aae38SBartlomiej Sieka usb_started = 1; 11793c2582fSLucas Stach } 11893c2582fSLucas Stach 119ceb4972aSVivek Gautam debug("scan end\n"); 12093c2582fSLucas Stach /* if we were not able to find at least one working bus, bail out */ 121d906bbc2SHans de Goede if (controllers_initialized == 0) 12293c2582fSLucas Stach puts("USB error: all controllers failed lowlevel init\n"); 12393c2582fSLucas Stach 1245a80b344SPaul Kocialkowski return usb_started ? 0 : -ENODEV; 125affae2bfSwdenk } 126affae2bfSwdenk 127affae2bfSwdenk /****************************************************************************** 128affae2bfSwdenk * Stop USB this stops the LowLevel Part and deregisters USB devices. 129affae2bfSwdenk */ 130affae2bfSwdenk int usb_stop(void) 131affae2bfSwdenk { 13293c2582fSLucas Stach int i; 133eba1f2fcSRemy Bohmer 134eba1f2fcSRemy Bohmer if (usb_started) { 135affae2bfSwdenk asynch_allowed = 1; 136e51aae38SBartlomiej Sieka usb_started = 0; 137affae2bfSwdenk usb_hub_reset(); 13893c2582fSLucas Stach 13993c2582fSLucas Stach for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { 14093c2582fSLucas Stach if (usb_lowlevel_stop(i)) 14193c2582fSLucas Stach printf("failed to stop USB controller %d\n", i); 142eba1f2fcSRemy Bohmer } 14393c2582fSLucas Stach } 14493c2582fSLucas Stach 14593c2582fSLucas Stach return 0; 146affae2bfSwdenk } 147affae2bfSwdenk 14808f3bb0bSVincent Palatin /****************************************************************************** 14908f3bb0bSVincent Palatin * Detect if a USB device has been plugged or unplugged. 15008f3bb0bSVincent Palatin */ 15108f3bb0bSVincent Palatin int usb_detect_change(void) 15208f3bb0bSVincent Palatin { 15308f3bb0bSVincent Palatin int i, j; 15408f3bb0bSVincent Palatin int change = 0; 15508f3bb0bSVincent Palatin 15608f3bb0bSVincent Palatin for (j = 0; j < USB_MAX_DEVICE; j++) { 15708f3bb0bSVincent Palatin for (i = 0; i < usb_dev[j].maxchild; i++) { 15808f3bb0bSVincent Palatin struct usb_port_status status; 15908f3bb0bSVincent Palatin 16008f3bb0bSVincent Palatin if (usb_get_port_status(&usb_dev[j], i + 1, 16108f3bb0bSVincent Palatin &status) < 0) 16208f3bb0bSVincent Palatin /* USB request failed */ 16308f3bb0bSVincent Palatin continue; 16408f3bb0bSVincent Palatin 16508f3bb0bSVincent Palatin if (le16_to_cpu(status.wPortChange) & 16608f3bb0bSVincent Palatin USB_PORT_STAT_C_CONNECTION) 16708f3bb0bSVincent Palatin change++; 16808f3bb0bSVincent Palatin } 16908f3bb0bSVincent Palatin } 17008f3bb0bSVincent Palatin 17108f3bb0bSVincent Palatin return change; 17208f3bb0bSVincent Palatin } 17308f3bb0bSVincent Palatin 174affae2bfSwdenk /* 175affae2bfSwdenk * disables the asynch behaviour of the control message. This is used for data 176affae2bfSwdenk * transfers that uses the exclusiv access to the control and bulk messages. 17789d48367SSimon Glass * Returns the old value so it can be restored later. 178affae2bfSwdenk */ 17989d48367SSimon Glass int usb_disable_asynch(int disable) 180affae2bfSwdenk { 18189d48367SSimon Glass int old_value = asynch_allowed; 18289d48367SSimon Glass 183affae2bfSwdenk asynch_allowed = !disable; 18489d48367SSimon Glass return old_value; 185affae2bfSwdenk } 186*fd09c205SSven Schwermer #endif /* !CONFIG_IS_ENABLED(DM_USB) */ 187affae2bfSwdenk 188affae2bfSwdenk 189affae2bfSwdenk /*------------------------------------------------------------------- 190affae2bfSwdenk * Message wrappers. 191affae2bfSwdenk * 192affae2bfSwdenk */ 193affae2bfSwdenk 194affae2bfSwdenk /* 195affae2bfSwdenk * submits an Interrupt Message 196affae2bfSwdenk */ 197affae2bfSwdenk int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, 198affae2bfSwdenk void *buffer, int transfer_len, int interval) 199affae2bfSwdenk { 200affae2bfSwdenk return submit_int_msg(dev, pipe, buffer, transfer_len, interval); 201affae2bfSwdenk } 202affae2bfSwdenk 203affae2bfSwdenk /* 204affae2bfSwdenk * submits a control message and waits for comletion (at least timeout * 1ms) 205affae2bfSwdenk * If timeout is 0, we don't wait for completion (used as example to set and 206affae2bfSwdenk * clear keyboards LEDs). For data transfers, (storage transfers) we don't 207affae2bfSwdenk * allow control messages with 0 timeout, by previousely resetting the flag 208affae2bfSwdenk * asynch_allowed (usb_disable_asynch(1)). 209a6f70a3dSVagrant Cascadian * returns the transferred length if OK or -1 if error. The transferred length 210affae2bfSwdenk * and the current status are stored in the dev->act_len and dev->status. 211affae2bfSwdenk */ 212affae2bfSwdenk int usb_control_msg(struct usb_device *dev, unsigned int pipe, 213affae2bfSwdenk unsigned char request, unsigned char requesttype, 214affae2bfSwdenk unsigned short value, unsigned short index, 215affae2bfSwdenk void *data, unsigned short size, int timeout) 216affae2bfSwdenk { 217f5766139SPuneet Saxena ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1); 218651d95c8SHans de Goede int err; 219e159e486SMarek Vasut 2206f5794a6SRemy Bohmer if ((timeout == 0) && (!asynch_allowed)) { 2216f5794a6SRemy Bohmer /* request for a asynch control pipe is not allowed */ 2225a80b344SPaul Kocialkowski return -EINVAL; 2236f5794a6SRemy Bohmer } 2249c998aa8SWolfgang Denk 225affae2bfSwdenk /* set setup command */ 226f5766139SPuneet Saxena setup_packet->requesttype = requesttype; 227f5766139SPuneet Saxena setup_packet->request = request; 228f5766139SPuneet Saxena setup_packet->value = cpu_to_le16(value); 229f5766139SPuneet Saxena setup_packet->index = cpu_to_le16(index); 230f5766139SPuneet Saxena setup_packet->length = cpu_to_le16(size); 231ceb4972aSVivek Gautam debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ 2326f5794a6SRemy Bohmer "value 0x%X index 0x%X length 0x%X\n", 233affae2bfSwdenk request, requesttype, value, index, size); 234affae2bfSwdenk dev->status = USB_ST_NOT_PROC; /*not yet processed */ 235affae2bfSwdenk 236651d95c8SHans de Goede err = submit_control_msg(dev, pipe, data, size, setup_packet); 237651d95c8SHans de Goede if (err < 0) 238651d95c8SHans de Goede return err; 2396f5794a6SRemy Bohmer if (timeout == 0) 240affae2bfSwdenk return (int)size; 2416f5794a6SRemy Bohmer 24248867208SRemy Bohmer /* 24384d36b30SRemy Bohmer * Wait for status to update until timeout expires, USB driver 24484d36b30SRemy Bohmer * interrupt handler may set the status when the USB operation has 24584d36b30SRemy Bohmer * been completed. 24648867208SRemy Bohmer */ 24784d36b30SRemy Bohmer while (timeout--) { 24884d36b30SRemy Bohmer if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) 24984d36b30SRemy Bohmer break; 2505b84dd67SMike Frysinger mdelay(1); 251affae2bfSwdenk } 25284d36b30SRemy Bohmer if (dev->status) 25384d36b30SRemy Bohmer return -1; 254affae2bfSwdenk 25548867208SRemy Bohmer return dev->act_len; 25684d36b30SRemy Bohmer 25748867208SRemy Bohmer } 25848867208SRemy Bohmer 259affae2bfSwdenk /*------------------------------------------------------------------- 260affae2bfSwdenk * submits bulk message, and waits for completion. returns 0 if Ok or 2615a80b344SPaul Kocialkowski * negative if Error. 262affae2bfSwdenk * synchronous behavior 263affae2bfSwdenk */ 264affae2bfSwdenk int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, 265affae2bfSwdenk void *data, int len, int *actual_length, int timeout) 266affae2bfSwdenk { 267affae2bfSwdenk if (len < 0) 2685a80b344SPaul Kocialkowski return -EINVAL; 269affae2bfSwdenk dev->status = USB_ST_NOT_PROC; /*not yet processed */ 270fd06028dSIlya Yanok if (submit_bulk_msg(dev, pipe, data, len) < 0) 2715a80b344SPaul Kocialkowski return -EIO; 272affae2bfSwdenk while (timeout--) { 273affae2bfSwdenk if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) 274affae2bfSwdenk break; 2755b84dd67SMike Frysinger mdelay(1); 276affae2bfSwdenk } 277affae2bfSwdenk *actual_length = dev->act_len; 278affae2bfSwdenk if (dev->status == 0) 279affae2bfSwdenk return 0; 280affae2bfSwdenk else 2815a80b344SPaul Kocialkowski return -EIO; 282affae2bfSwdenk } 283affae2bfSwdenk 284affae2bfSwdenk 285affae2bfSwdenk /*------------------------------------------------------------------- 286affae2bfSwdenk * Max Packet stuff 287affae2bfSwdenk */ 288affae2bfSwdenk 289affae2bfSwdenk /* 290affae2bfSwdenk * returns the max packet size, depending on the pipe direction and 291affae2bfSwdenk * the configurations values 292affae2bfSwdenk */ 293affae2bfSwdenk int usb_maxpacket(struct usb_device *dev, unsigned long pipe) 294affae2bfSwdenk { 2956f5794a6SRemy Bohmer /* direction is out -> use emaxpacket out */ 2966f5794a6SRemy Bohmer if ((pipe & USB_DIR_IN) == 0) 297de39f8c1SMichael Trimarchi return dev->epmaxpacketout[((pipe>>15) & 0xf)]; 298affae2bfSwdenk else 299de39f8c1SMichael Trimarchi return dev->epmaxpacketin[((pipe>>15) & 0xf)]; 300affae2bfSwdenk } 301affae2bfSwdenk 3025e8baf87SMarek Vasut /* 3035e8baf87SMarek Vasut * The routine usb_set_maxpacket_ep() is extracted from the loop of routine 304be19d324SRemy Bohmer * usb_set_maxpacket(), because the optimizer of GCC 4.x chokes on this routine 305be19d324SRemy Bohmer * when it is inlined in 1 single routine. What happens is that the register r3 306be19d324SRemy Bohmer * is used as loop-count 'i', but gets overwritten later on. 307be19d324SRemy Bohmer * This is clearly a compiler bug, but it is easier to workaround it here than 308be19d324SRemy Bohmer * to update the compiler (Occurs with at least several GCC 4.{1,2},x 309be19d324SRemy Bohmer * CodeSourcery compilers like e.g. 2007q3, 2008q1, 2008q3 lite editions on ARM) 3105e8baf87SMarek Vasut * 3115e8baf87SMarek Vasut * NOTE: Similar behaviour was observed with GCC4.6 on ARMv5. 312be19d324SRemy Bohmer */ 31366cf6410SMike Frysinger static void noinline 3145e8baf87SMarek Vasut usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx) 315be19d324SRemy Bohmer { 316be19d324SRemy Bohmer int b; 3175e8baf87SMarek Vasut struct usb_endpoint_descriptor *ep; 318b2fb47f1STom Rini u16 ep_wMaxPacketSize; 3195e8baf87SMarek Vasut 3205e8baf87SMarek Vasut ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx]; 321be19d324SRemy Bohmer 322be19d324SRemy Bohmer b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 323b2fb47f1STom Rini ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize); 324be19d324SRemy Bohmer 325be19d324SRemy Bohmer if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 326be19d324SRemy Bohmer USB_ENDPOINT_XFER_CONTROL) { 327be19d324SRemy Bohmer /* Control => bidirectional */ 328b2fb47f1STom Rini dev->epmaxpacketout[b] = ep_wMaxPacketSize; 329b2fb47f1STom Rini dev->epmaxpacketin[b] = ep_wMaxPacketSize; 330ceb4972aSVivek Gautam debug("##Control EP epmaxpacketout/in[%d] = %d\n", 331be19d324SRemy Bohmer b, dev->epmaxpacketin[b]); 332be19d324SRemy Bohmer } else { 333be19d324SRemy Bohmer if ((ep->bEndpointAddress & 0x80) == 0) { 334be19d324SRemy Bohmer /* OUT Endpoint */ 335b2fb47f1STom Rini if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) { 336b2fb47f1STom Rini dev->epmaxpacketout[b] = ep_wMaxPacketSize; 337ceb4972aSVivek Gautam debug("##EP epmaxpacketout[%d] = %d\n", 338be19d324SRemy Bohmer b, dev->epmaxpacketout[b]); 339be19d324SRemy Bohmer } 340be19d324SRemy Bohmer } else { 341be19d324SRemy Bohmer /* IN Endpoint */ 342b2fb47f1STom Rini if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) { 343b2fb47f1STom Rini dev->epmaxpacketin[b] = ep_wMaxPacketSize; 344ceb4972aSVivek Gautam debug("##EP epmaxpacketin[%d] = %d\n", 345be19d324SRemy Bohmer b, dev->epmaxpacketin[b]); 346be19d324SRemy Bohmer } 347be19d324SRemy Bohmer } /* if out */ 348be19d324SRemy Bohmer } /* if control */ 349be19d324SRemy Bohmer } 350be19d324SRemy Bohmer 351affae2bfSwdenk /* 352affae2bfSwdenk * set the max packed value of all endpoints in the given configuration 353affae2bfSwdenk */ 354c08b1b26SMarek Vasut static int usb_set_maxpacket(struct usb_device *dev) 355affae2bfSwdenk { 356be19d324SRemy Bohmer int i, ii; 357affae2bfSwdenk 3588f8bd565STom Rix for (i = 0; i < dev->config.desc.bNumInterfaces; i++) 3598f8bd565STom Rix for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++) 3605e8baf87SMarek Vasut usb_set_maxpacket_ep(dev, i, ii); 361affae2bfSwdenk 362affae2bfSwdenk return 0; 363affae2bfSwdenk } 364affae2bfSwdenk 365affae2bfSwdenk /******************************************************************************* 366affae2bfSwdenk * Parse the config, located in buffer, and fills the dev->config structure. 367affae2bfSwdenk * Note that all little/big endian swapping are done automatically. 368eaf3e613SJulius Werner * (wTotalLength has already been swapped and sanitized when it was read.) 369affae2bfSwdenk */ 370c08b1b26SMarek Vasut static int usb_parse_config(struct usb_device *dev, 371c08b1b26SMarek Vasut unsigned char *buffer, int cfgno) 372affae2bfSwdenk { 373affae2bfSwdenk struct usb_descriptor_header *head; 3747455af41SBartlomiej Sieka int index, ifno, epno, curr_if_num; 375b2fb47f1STom Rini u16 ep_wMaxPacketSize; 376605bd75aSVivek Gautam struct usb_interface *if_desc = NULL; 3777455af41SBartlomiej Sieka 378affae2bfSwdenk ifno = -1; 379affae2bfSwdenk epno = -1; 3807455af41SBartlomiej Sieka curr_if_num = -1; 381affae2bfSwdenk 382affae2bfSwdenk dev->configno = cfgno; 383affae2bfSwdenk head = (struct usb_descriptor_header *) &buffer[0]; 384affae2bfSwdenk if (head->bDescriptorType != USB_DT_CONFIG) { 3856f5794a6SRemy Bohmer printf(" ERROR: NOT USB_CONFIG_DESC %x\n", 3866f5794a6SRemy Bohmer head->bDescriptorType); 3875a80b344SPaul Kocialkowski return -EINVAL; 388affae2bfSwdenk } 389eaf3e613SJulius Werner if (head->bLength != USB_DT_CONFIG_SIZE) { 390eaf3e613SJulius Werner printf("ERROR: Invalid USB CFG length (%d)\n", head->bLength); 3915a80b344SPaul Kocialkowski return -EINVAL; 392eaf3e613SJulius Werner } 393eaf3e613SJulius Werner memcpy(&dev->config, head, USB_DT_CONFIG_SIZE); 394affae2bfSwdenk dev->config.no_of_if = 0; 395affae2bfSwdenk 3968f8bd565STom Rix index = dev->config.desc.bLength; 3976f5794a6SRemy Bohmer /* Ok the first entry must be a configuration entry, 3986f5794a6SRemy Bohmer * now process the others */ 399affae2bfSwdenk head = (struct usb_descriptor_header *) &buffer[index]; 400eaf3e613SJulius Werner while (index + 1 < dev->config.desc.wTotalLength && head->bLength) { 401affae2bfSwdenk switch (head->bDescriptorType) { 402affae2bfSwdenk case USB_DT_INTERFACE: 403eaf3e613SJulius Werner if (head->bLength != USB_DT_INTERFACE_SIZE) { 404eaf3e613SJulius Werner printf("ERROR: Invalid USB IF length (%d)\n", 405eaf3e613SJulius Werner head->bLength); 406eaf3e613SJulius Werner break; 407eaf3e613SJulius Werner } 408eaf3e613SJulius Werner if (index + USB_DT_INTERFACE_SIZE > 409eaf3e613SJulius Werner dev->config.desc.wTotalLength) { 410eaf3e613SJulius Werner puts("USB IF descriptor overflowed buffer!\n"); 411eaf3e613SJulius Werner break; 412eaf3e613SJulius Werner } 4136f5794a6SRemy Bohmer if (((struct usb_interface_descriptor *) \ 414eaf3e613SJulius Werner head)->bInterfaceNumber != curr_if_num) { 4157455af41SBartlomiej Sieka /* this is a new interface, copy new desc */ 416affae2bfSwdenk ifno = dev->config.no_of_if; 417eaf3e613SJulius Werner if (ifno >= USB_MAXINTERFACES) { 418eaf3e613SJulius Werner puts("Too many USB interfaces!\n"); 419eaf3e613SJulius Werner /* try to go on with what we have */ 4205a80b344SPaul Kocialkowski return -EINVAL; 421eaf3e613SJulius Werner } 422605bd75aSVivek Gautam if_desc = &dev->config.if_desc[ifno]; 4237455af41SBartlomiej Sieka dev->config.no_of_if++; 424eaf3e613SJulius Werner memcpy(if_desc, head, 425eaf3e613SJulius Werner USB_DT_INTERFACE_SIZE); 426605bd75aSVivek Gautam if_desc->no_of_ep = 0; 427605bd75aSVivek Gautam if_desc->num_altsetting = 1; 4286f5794a6SRemy Bohmer curr_if_num = 429605bd75aSVivek Gautam if_desc->desc.bInterfaceNumber; 4307455af41SBartlomiej Sieka } else { 4317455af41SBartlomiej Sieka /* found alternate setting for the interface */ 432605bd75aSVivek Gautam if (ifno >= 0) { 433605bd75aSVivek Gautam if_desc = &dev->config.if_desc[ifno]; 434605bd75aSVivek Gautam if_desc->num_altsetting++; 435605bd75aSVivek Gautam } 4367455af41SBartlomiej Sieka } 437affae2bfSwdenk break; 438affae2bfSwdenk case USB_DT_ENDPOINT: 4392f0eb2acSBin Meng if (head->bLength != USB_DT_ENDPOINT_SIZE && 4402f0eb2acSBin Meng head->bLength != USB_DT_ENDPOINT_AUDIO_SIZE) { 441eaf3e613SJulius Werner printf("ERROR: Invalid USB EP length (%d)\n", 442eaf3e613SJulius Werner head->bLength); 443eaf3e613SJulius Werner break; 444eaf3e613SJulius Werner } 4452f0eb2acSBin Meng if (index + head->bLength > 446eaf3e613SJulius Werner dev->config.desc.wTotalLength) { 447eaf3e613SJulius Werner puts("USB EP descriptor overflowed buffer!\n"); 448eaf3e613SJulius Werner break; 449eaf3e613SJulius Werner } 450eaf3e613SJulius Werner if (ifno < 0) { 451eaf3e613SJulius Werner puts("Endpoint descriptor out of order!\n"); 452eaf3e613SJulius Werner break; 453eaf3e613SJulius Werner } 454affae2bfSwdenk epno = dev->config.if_desc[ifno].no_of_ep; 455605bd75aSVivek Gautam if_desc = &dev->config.if_desc[ifno]; 456447b9cdfSPeng Fan if (epno >= USB_MAXENDPOINTS) { 457eaf3e613SJulius Werner printf("Interface %d has too many endpoints!\n", 458eaf3e613SJulius Werner if_desc->desc.bInterfaceNumber); 4595a80b344SPaul Kocialkowski return -EINVAL; 460eaf3e613SJulius Werner } 4616f5794a6SRemy Bohmer /* found an endpoint */ 462605bd75aSVivek Gautam if_desc->no_of_ep++; 463eaf3e613SJulius Werner memcpy(&if_desc->ep_desc[epno], head, 464eaf3e613SJulius Werner USB_DT_ENDPOINT_SIZE); 465b2fb47f1STom Rini ep_wMaxPacketSize = get_unaligned(&dev->config.\ 466b2fb47f1STom Rini if_desc[ifno].\ 467b2fb47f1STom Rini ep_desc[epno].\ 468b2fb47f1STom Rini wMaxPacketSize); 469b2fb47f1STom Rini put_unaligned(le16_to_cpu(ep_wMaxPacketSize), 470b2fb47f1STom Rini &dev->config.\ 471b2fb47f1STom Rini if_desc[ifno].\ 472b2fb47f1STom Rini ep_desc[epno].\ 473b2fb47f1STom Rini wMaxPacketSize); 474ceb4972aSVivek Gautam debug("if %d, ep %d\n", ifno, epno); 475affae2bfSwdenk break; 4766497c667SVivek Gautam case USB_DT_SS_ENDPOINT_COMP: 477eaf3e613SJulius Werner if (head->bLength != USB_DT_SS_EP_COMP_SIZE) { 478eaf3e613SJulius Werner printf("ERROR: Invalid USB EPC length (%d)\n", 479eaf3e613SJulius Werner head->bLength); 480eaf3e613SJulius Werner break; 481eaf3e613SJulius Werner } 482eaf3e613SJulius Werner if (index + USB_DT_SS_EP_COMP_SIZE > 483eaf3e613SJulius Werner dev->config.desc.wTotalLength) { 484eaf3e613SJulius Werner puts("USB EPC descriptor overflowed buffer!\n"); 485eaf3e613SJulius Werner break; 486eaf3e613SJulius Werner } 487eaf3e613SJulius Werner if (ifno < 0 || epno < 0) { 488eaf3e613SJulius Werner puts("EPC descriptor out of order!\n"); 489eaf3e613SJulius Werner break; 490eaf3e613SJulius Werner } 4916497c667SVivek Gautam if_desc = &dev->config.if_desc[ifno]; 492eaf3e613SJulius Werner memcpy(&if_desc->ss_ep_comp_desc[epno], head, 493eaf3e613SJulius Werner USB_DT_SS_EP_COMP_SIZE); 4946497c667SVivek Gautam break; 495affae2bfSwdenk default: 496affae2bfSwdenk if (head->bLength == 0) 4975a80b344SPaul Kocialkowski return -EINVAL; 4986f5794a6SRemy Bohmer 499ceb4972aSVivek Gautam debug("unknown Description Type : %x\n", 5006f5794a6SRemy Bohmer head->bDescriptorType); 5016f5794a6SRemy Bohmer 502ceb4972aSVivek Gautam #ifdef DEBUG 503affae2bfSwdenk { 504fad2e1b0SWolfgang Denk unsigned char *ch = (unsigned char *)head; 505ceb4972aSVivek Gautam int i; 506ceb4972aSVivek Gautam 507affae2bfSwdenk for (i = 0; i < head->bLength; i++) 508ceb4972aSVivek Gautam debug("%02X ", *ch++); 509ceb4972aSVivek Gautam debug("\n\n\n"); 510affae2bfSwdenk } 511ceb4972aSVivek Gautam #endif 512affae2bfSwdenk break; 513affae2bfSwdenk } 514affae2bfSwdenk index += head->bLength; 515affae2bfSwdenk head = (struct usb_descriptor_header *)&buffer[index]; 516affae2bfSwdenk } 5175a80b344SPaul Kocialkowski return 0; 518affae2bfSwdenk } 519affae2bfSwdenk 520affae2bfSwdenk /*********************************************************************** 521affae2bfSwdenk * Clears an endpoint 522affae2bfSwdenk * endp: endpoint number in bits 0-3; 523affae2bfSwdenk * direction flag in bit 7 (1 = IN, 0 = OUT) 524affae2bfSwdenk */ 525affae2bfSwdenk int usb_clear_halt(struct usb_device *dev, int pipe) 526affae2bfSwdenk { 527affae2bfSwdenk int result; 528affae2bfSwdenk int endp = usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7); 529affae2bfSwdenk 530affae2bfSwdenk result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 5316f5794a6SRemy Bohmer USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, 5326f5794a6SRemy Bohmer endp, NULL, 0, USB_CNTL_TIMEOUT * 3); 533affae2bfSwdenk 534affae2bfSwdenk /* don't clear if failed */ 535affae2bfSwdenk if (result < 0) 536affae2bfSwdenk return result; 5379c998aa8SWolfgang Denk 5389c998aa8SWolfgang Denk /* 5399c998aa8SWolfgang Denk * NOTE: we do not get status and verify reset was successful 5409c998aa8SWolfgang Denk * as some devices are reported to lock up upon this check.. 5419c998aa8SWolfgang Denk */ 5429c998aa8SWolfgang Denk 543affae2bfSwdenk usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)); 5449c998aa8SWolfgang Denk 545affae2bfSwdenk /* toggle is reset on clear */ 546affae2bfSwdenk usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); 547affae2bfSwdenk return 0; 548affae2bfSwdenk } 549affae2bfSwdenk 550affae2bfSwdenk 551affae2bfSwdenk /********************************************************************** 552affae2bfSwdenk * get_descriptor type 553affae2bfSwdenk */ 554c08b1b26SMarek Vasut static int usb_get_descriptor(struct usb_device *dev, unsigned char type, 5556f5794a6SRemy Bohmer unsigned char index, void *buf, int size) 556affae2bfSwdenk { 5578319aeb1SMasahiro Yamada return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 558affae2bfSwdenk USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 5598319aeb1SMasahiro Yamada (type << 8) + index, 0, buf, size, 5608319aeb1SMasahiro Yamada USB_CNTL_TIMEOUT); 561affae2bfSwdenk } 562affae2bfSwdenk 563affae2bfSwdenk /********************************************************************** 564c75f57fbSStefan Brüns * gets len of configuration cfgno 565affae2bfSwdenk */ 566c75f57fbSStefan Brüns int usb_get_configuration_len(struct usb_device *dev, int cfgno) 567affae2bfSwdenk { 568affae2bfSwdenk int result; 569c75f57fbSStefan Brüns ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9); 570c60795f4SIlya Yanok struct usb_config_descriptor *config; 571affae2bfSwdenk 572c60795f4SIlya Yanok config = (struct usb_config_descriptor *)&buffer[0]; 57348867208SRemy Bohmer result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9); 57448867208SRemy Bohmer if (result < 9) { 575affae2bfSwdenk if (result < 0) 5766f5794a6SRemy Bohmer printf("unable to get descriptor, error %lX\n", 5776f5794a6SRemy Bohmer dev->status); 578affae2bfSwdenk else 5796f5794a6SRemy Bohmer printf("config descriptor too short " \ 58048867208SRemy Bohmer "(expected %i, got %i)\n", 9, result); 5815a80b344SPaul Kocialkowski return -EIO; 582affae2bfSwdenk } 583c75f57fbSStefan Brüns return le16_to_cpu(config->wTotalLength); 584cd0a9de6Swdenk } 585cd0a9de6Swdenk 586c75f57fbSStefan Brüns /********************************************************************** 587c75f57fbSStefan Brüns * gets configuration cfgno and store it in the buffer 588c75f57fbSStefan Brüns */ 589c75f57fbSStefan Brüns int usb_get_configuration_no(struct usb_device *dev, int cfgno, 590c75f57fbSStefan Brüns unsigned char *buffer, int length) 591c75f57fbSStefan Brüns { 592c75f57fbSStefan Brüns int result; 593c75f57fbSStefan Brüns struct usb_config_descriptor *config; 594c75f57fbSStefan Brüns 595c75f57fbSStefan Brüns config = (struct usb_config_descriptor *)&buffer[0]; 596eaf3e613SJulius Werner result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length); 597c75f57fbSStefan Brüns debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, 598c75f57fbSStefan Brüns le16_to_cpu(config->wTotalLength)); 599c75f57fbSStefan Brüns config->wTotalLength = result; /* validated, with CPU byte order */ 600eaf3e613SJulius Werner 601affae2bfSwdenk return result; 602affae2bfSwdenk } 603affae2bfSwdenk 604affae2bfSwdenk /******************************************************************** 605affae2bfSwdenk * set address of a device to the value in dev->devnum. 606affae2bfSwdenk * This can only be done by addressing the device via the default address (0) 607affae2bfSwdenk */ 608c08b1b26SMarek Vasut static int usb_set_address(struct usb_device *dev) 609affae2bfSwdenk { 610ceb4972aSVivek Gautam debug("set address %d\n", dev->devnum); 6118319aeb1SMasahiro Yamada 6128319aeb1SMasahiro Yamada return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, 6138319aeb1SMasahiro Yamada 0, (dev->devnum), 0, NULL, 0, USB_CNTL_TIMEOUT); 614affae2bfSwdenk } 615affae2bfSwdenk 616affae2bfSwdenk /******************************************************************** 617affae2bfSwdenk * set interface number to interface 618affae2bfSwdenk */ 619affae2bfSwdenk int usb_set_interface(struct usb_device *dev, int interface, int alternate) 620affae2bfSwdenk { 6218f8bd565STom Rix struct usb_interface *if_face = NULL; 622affae2bfSwdenk int ret, i; 623affae2bfSwdenk 6248f8bd565STom Rix for (i = 0; i < dev->config.desc.bNumInterfaces; i++) { 6258f8bd565STom Rix if (dev->config.if_desc[i].desc.bInterfaceNumber == interface) { 626affae2bfSwdenk if_face = &dev->config.if_desc[i]; 627affae2bfSwdenk break; 628affae2bfSwdenk } 629affae2bfSwdenk } 630affae2bfSwdenk if (!if_face) { 631affae2bfSwdenk printf("selecting invalid interface %d", interface); 6325a80b344SPaul Kocialkowski return -EINVAL; 633affae2bfSwdenk } 6347455af41SBartlomiej Sieka /* 6357455af41SBartlomiej Sieka * We should return now for devices with only one alternate setting. 6366f5794a6SRemy Bohmer * According to 9.4.10 of the Universal Serial Bus Specification 6376f5794a6SRemy Bohmer * Revision 2.0 such devices can return with a STALL. This results in 6386f5794a6SRemy Bohmer * some USB sticks timeouting during initialization and then being 6396f5794a6SRemy Bohmer * unusable in U-Boot. 6407455af41SBartlomiej Sieka */ 6417455af41SBartlomiej Sieka if (if_face->num_altsetting == 1) 6427455af41SBartlomiej Sieka return 0; 643affae2bfSwdenk 6446f5794a6SRemy Bohmer ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 6456f5794a6SRemy Bohmer USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, 6466f5794a6SRemy Bohmer alternate, interface, NULL, 0, 6476f5794a6SRemy Bohmer USB_CNTL_TIMEOUT * 5); 6486f5794a6SRemy Bohmer if (ret < 0) 649affae2bfSwdenk return ret; 650affae2bfSwdenk 651affae2bfSwdenk return 0; 652affae2bfSwdenk } 653affae2bfSwdenk 654affae2bfSwdenk /******************************************************************** 655affae2bfSwdenk * set configuration number to configuration 656affae2bfSwdenk */ 657c08b1b26SMarek Vasut static int usb_set_configuration(struct usb_device *dev, int configuration) 658affae2bfSwdenk { 659affae2bfSwdenk int res; 660ceb4972aSVivek Gautam debug("set configuration %d\n", configuration); 661affae2bfSwdenk /* set setup command */ 662affae2bfSwdenk res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 663affae2bfSwdenk USB_REQ_SET_CONFIGURATION, 0, 664affae2bfSwdenk configuration, 0, 665affae2bfSwdenk NULL, 0, USB_CNTL_TIMEOUT); 666affae2bfSwdenk if (res == 0) { 667affae2bfSwdenk dev->toggle[0] = 0; 668affae2bfSwdenk dev->toggle[1] = 0; 669affae2bfSwdenk return 0; 6706f5794a6SRemy Bohmer } else 6715a80b344SPaul Kocialkowski return -EIO; 672affae2bfSwdenk } 673affae2bfSwdenk 674affae2bfSwdenk /******************************************************************** 675affae2bfSwdenk * set protocol to protocol 676affae2bfSwdenk */ 677affae2bfSwdenk int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol) 678affae2bfSwdenk { 679affae2bfSwdenk return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 680affae2bfSwdenk USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 681affae2bfSwdenk protocol, ifnum, NULL, 0, USB_CNTL_TIMEOUT); 682affae2bfSwdenk } 683affae2bfSwdenk 684affae2bfSwdenk /******************************************************************** 685affae2bfSwdenk * set idle 686affae2bfSwdenk */ 687affae2bfSwdenk int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id) 688affae2bfSwdenk { 689affae2bfSwdenk return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 690affae2bfSwdenk USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 691affae2bfSwdenk (duration << 8) | report_id, ifnum, NULL, 0, USB_CNTL_TIMEOUT); 692affae2bfSwdenk } 693affae2bfSwdenk 694affae2bfSwdenk /******************************************************************** 695affae2bfSwdenk * get report 696affae2bfSwdenk */ 6976f5794a6SRemy Bohmer int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, 6986f5794a6SRemy Bohmer unsigned char id, void *buf, int size) 699affae2bfSwdenk { 700affae2bfSwdenk return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 7016f5794a6SRemy Bohmer USB_REQ_GET_REPORT, 7026f5794a6SRemy Bohmer USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 703affae2bfSwdenk (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT); 704affae2bfSwdenk } 705affae2bfSwdenk 706affae2bfSwdenk /******************************************************************** 707affae2bfSwdenk * get class descriptor 708affae2bfSwdenk */ 709affae2bfSwdenk int usb_get_class_descriptor(struct usb_device *dev, int ifnum, 710affae2bfSwdenk unsigned char type, unsigned char id, void *buf, int size) 711affae2bfSwdenk { 712affae2bfSwdenk return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 713affae2bfSwdenk USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, 714affae2bfSwdenk (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT); 715affae2bfSwdenk } 716affae2bfSwdenk 717affae2bfSwdenk /******************************************************************** 718affae2bfSwdenk * get string index in buffer 719affae2bfSwdenk */ 720c08b1b26SMarek Vasut static int usb_get_string(struct usb_device *dev, unsigned short langid, 7216f5794a6SRemy Bohmer unsigned char index, void *buf, int size) 722affae2bfSwdenk { 7239c998aa8SWolfgang Denk int i; 7249c998aa8SWolfgang Denk int result; 7259c998aa8SWolfgang Denk 7269c998aa8SWolfgang Denk for (i = 0; i < 3; ++i) { 7279c998aa8SWolfgang Denk /* some devices are flaky */ 7289c998aa8SWolfgang Denk result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 729affae2bfSwdenk USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 7309c998aa8SWolfgang Denk (USB_DT_STRING << 8) + index, langid, buf, size, 7319c998aa8SWolfgang Denk USB_CNTL_TIMEOUT); 7329c998aa8SWolfgang Denk 7339c998aa8SWolfgang Denk if (result > 0) 7349c998aa8SWolfgang Denk break; 735affae2bfSwdenk } 736affae2bfSwdenk 7379c998aa8SWolfgang Denk return result; 7389c998aa8SWolfgang Denk } 7399c998aa8SWolfgang Denk 7409c998aa8SWolfgang Denk 7419c998aa8SWolfgang Denk static void usb_try_string_workarounds(unsigned char *buf, int *length) 7429c998aa8SWolfgang Denk { 7439c998aa8SWolfgang Denk int newlength, oldlength = *length; 7449c998aa8SWolfgang Denk 7459c998aa8SWolfgang Denk for (newlength = 2; newlength + 1 < oldlength; newlength += 2) 7469c998aa8SWolfgang Denk if (!isprint(buf[newlength]) || buf[newlength + 1]) 7479c998aa8SWolfgang Denk break; 7489c998aa8SWolfgang Denk 7499c998aa8SWolfgang Denk if (newlength > 2) { 7509c998aa8SWolfgang Denk buf[0] = newlength; 7519c998aa8SWolfgang Denk *length = newlength; 7529c998aa8SWolfgang Denk } 7539c998aa8SWolfgang Denk } 7549c998aa8SWolfgang Denk 7559c998aa8SWolfgang Denk 7569c998aa8SWolfgang Denk static int usb_string_sub(struct usb_device *dev, unsigned int langid, 7579c998aa8SWolfgang Denk unsigned int index, unsigned char *buf) 7589c998aa8SWolfgang Denk { 7599c998aa8SWolfgang Denk int rc; 7609c998aa8SWolfgang Denk 7619c998aa8SWolfgang Denk /* Try to read the string descriptor by asking for the maximum 7629c998aa8SWolfgang Denk * possible number of bytes */ 7639c998aa8SWolfgang Denk rc = usb_get_string(dev, langid, index, buf, 255); 7649c998aa8SWolfgang Denk 7659c998aa8SWolfgang Denk /* If that failed try to read the descriptor length, then 7669c998aa8SWolfgang Denk * ask for just that many bytes */ 7679c998aa8SWolfgang Denk if (rc < 2) { 7689c998aa8SWolfgang Denk rc = usb_get_string(dev, langid, index, buf, 2); 7699c998aa8SWolfgang Denk if (rc == 2) 7709c998aa8SWolfgang Denk rc = usb_get_string(dev, langid, index, buf, buf[0]); 7719c998aa8SWolfgang Denk } 7729c998aa8SWolfgang Denk 7739c998aa8SWolfgang Denk if (rc >= 2) { 7749c998aa8SWolfgang Denk if (!buf[0] && !buf[1]) 7759c998aa8SWolfgang Denk usb_try_string_workarounds(buf, &rc); 7769c998aa8SWolfgang Denk 7779c998aa8SWolfgang Denk /* There might be extra junk at the end of the descriptor */ 7789c998aa8SWolfgang Denk if (buf[0] < rc) 7799c998aa8SWolfgang Denk rc = buf[0]; 7809c998aa8SWolfgang Denk 7819c998aa8SWolfgang Denk rc = rc - (rc & 1); /* force a multiple of two */ 7829c998aa8SWolfgang Denk } 7839c998aa8SWolfgang Denk 7849c998aa8SWolfgang Denk if (rc < 2) 7855a80b344SPaul Kocialkowski rc = -EINVAL; 7869c998aa8SWolfgang Denk 7879c998aa8SWolfgang Denk return rc; 7889c998aa8SWolfgang Denk } 7899c998aa8SWolfgang Denk 7909c998aa8SWolfgang Denk 791affae2bfSwdenk /******************************************************************** 792affae2bfSwdenk * usb_string: 793affae2bfSwdenk * Get string index and translate it to ascii. 794affae2bfSwdenk * returns string length (> 0) or error (< 0) 795affae2bfSwdenk */ 796affae2bfSwdenk int usb_string(struct usb_device *dev, int index, char *buf, size_t size) 797affae2bfSwdenk { 798f5766139SPuneet Saxena ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ); 799affae2bfSwdenk unsigned char *tbuf; 800affae2bfSwdenk int err; 801affae2bfSwdenk unsigned int u, idx; 802affae2bfSwdenk 803affae2bfSwdenk if (size <= 0 || !buf || !index) 8045a80b344SPaul Kocialkowski return -EINVAL; 805affae2bfSwdenk buf[0] = 0; 806affae2bfSwdenk tbuf = &mybuf[0]; 807affae2bfSwdenk 808affae2bfSwdenk /* get langid for strings if it's not yet known */ 809affae2bfSwdenk if (!dev->have_langid) { 8109c998aa8SWolfgang Denk err = usb_string_sub(dev, 0, 0, tbuf); 811affae2bfSwdenk if (err < 0) { 812ceb4972aSVivek Gautam debug("error getting string descriptor 0 " \ 813f1c1f540SStefan Roese "(error=%lx)\n", dev->status); 8145a80b344SPaul Kocialkowski return -EIO; 815affae2bfSwdenk } else if (tbuf[0] < 4) { 816ceb4972aSVivek Gautam debug("string descriptor 0 too short\n"); 8175a80b344SPaul Kocialkowski return -EIO; 818affae2bfSwdenk } else { 819affae2bfSwdenk dev->have_langid = -1; 820affae2bfSwdenk dev->string_langid = tbuf[2] | (tbuf[3] << 8); 821affae2bfSwdenk /* always use the first langid listed */ 822ceb4972aSVivek Gautam debug("USB device number %d default " \ 8236f5794a6SRemy Bohmer "language ID 0x%x\n", 824affae2bfSwdenk dev->devnum, dev->string_langid); 825affae2bfSwdenk } 826affae2bfSwdenk } 8279c998aa8SWolfgang Denk 8289c998aa8SWolfgang Denk err = usb_string_sub(dev, dev->string_langid, index, tbuf); 829affae2bfSwdenk if (err < 0) 830affae2bfSwdenk return err; 831cd0a9de6Swdenk 832affae2bfSwdenk size--; /* leave room for trailing NULL char in output buffer */ 833affae2bfSwdenk for (idx = 0, u = 2; u < err; u += 2) { 834affae2bfSwdenk if (idx >= size) 835affae2bfSwdenk break; 836affae2bfSwdenk if (tbuf[u+1]) /* high byte */ 837affae2bfSwdenk buf[idx++] = '?'; /* non-ASCII character */ 838affae2bfSwdenk else 839affae2bfSwdenk buf[idx++] = tbuf[u]; 840affae2bfSwdenk } 841affae2bfSwdenk buf[idx] = 0; 842affae2bfSwdenk err = idx; 843affae2bfSwdenk return err; 844affae2bfSwdenk } 845affae2bfSwdenk 846affae2bfSwdenk 847affae2bfSwdenk /******************************************************************** 848affae2bfSwdenk * USB device handling: 849affae2bfSwdenk * the USB device are static allocated [USB_MAX_DEVICE]. 850affae2bfSwdenk */ 851affae2bfSwdenk 852*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB) 853affae2bfSwdenk 854affae2bfSwdenk /* returns a pointer to the device with the index [index]. 855affae2bfSwdenk * if the device is not assigned (dev->devnum==-1) returns NULL 856affae2bfSwdenk */ 857affae2bfSwdenk struct usb_device *usb_get_dev_index(int index) 858affae2bfSwdenk { 859affae2bfSwdenk if (usb_dev[index].devnum == -1) 860affae2bfSwdenk return NULL; 861affae2bfSwdenk else 862affae2bfSwdenk return &usb_dev[index]; 863affae2bfSwdenk } 864affae2bfSwdenk 86579b58887SSimon Glass int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp) 866affae2bfSwdenk { 867affae2bfSwdenk int i; 868ceb4972aSVivek Gautam debug("New Device %d\n", dev_index); 869affae2bfSwdenk if (dev_index == USB_MAX_DEVICE) { 8705f535fe1Swdenk printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE); 87179b58887SSimon Glass return -ENOSPC; 872affae2bfSwdenk } 8736f5794a6SRemy Bohmer /* default Address is 0, real addresses start with 1 */ 8746f5794a6SRemy Bohmer usb_dev[dev_index].devnum = dev_index + 1; 875affae2bfSwdenk usb_dev[dev_index].maxchild = 0; 876affae2bfSwdenk for (i = 0; i < USB_MAXCHILDREN; i++) 877affae2bfSwdenk usb_dev[dev_index].children[i] = NULL; 878affae2bfSwdenk usb_dev[dev_index].parent = NULL; 879c7e3b2b5SLucas Stach usb_dev[dev_index].controller = controller; 880affae2bfSwdenk dev_index++; 88179b58887SSimon Glass *devp = &usb_dev[dev_index - 1]; 88279b58887SSimon Glass 88379b58887SSimon Glass return 0; 884affae2bfSwdenk } 885affae2bfSwdenk 886359439d2SMilind Choudhary /* 887359439d2SMilind Choudhary * Free the newly created device node. 888359439d2SMilind Choudhary * Called in error cases where configuring a newly attached 889359439d2SMilind Choudhary * device fails for some reason. 890359439d2SMilind Choudhary */ 89179b58887SSimon Glass void usb_free_device(struct udevice *controller) 892359439d2SMilind Choudhary { 893359439d2SMilind Choudhary dev_index--; 894ceb4972aSVivek Gautam debug("Freeing device node: %d\n", dev_index); 895359439d2SMilind Choudhary memset(&usb_dev[dev_index], 0, sizeof(struct usb_device)); 896359439d2SMilind Choudhary usb_dev[dev_index].devnum = -1; 897359439d2SMilind Choudhary } 898affae2bfSwdenk 899affae2bfSwdenk /* 9005853e133SVivek Gautam * XHCI issues Enable Slot command and thereafter 9015853e133SVivek Gautam * allocates device contexts. Provide a weak alias 9025853e133SVivek Gautam * function for the purpose, so that XHCI overrides it 9035853e133SVivek Gautam * and EHCI/OHCI just work out of the box. 9045853e133SVivek Gautam */ 9055853e133SVivek Gautam __weak int usb_alloc_device(struct usb_device *udev) 9065853e133SVivek Gautam { 9075853e133SVivek Gautam return 0; 9085853e133SVivek Gautam } 909*fd09c205SSven Schwermer #endif /* !CONFIG_IS_ENABLED(DM_USB) */ 910862e75c0SSimon Glass 911682c9f8dSHans de Goede static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub) 912862e75c0SSimon Glass { 9133ed9eb93SStefan Roese if (!hub) 9148802f563SHans de Goede usb_reset_root_port(dev); 915862e75c0SSimon Glass 916862e75c0SSimon Glass return 0; 917862e75c0SSimon Glass } 918862e75c0SSimon Glass 9190ed27905SSimon Glass static int get_descriptor_len(struct usb_device *dev, int len, int expect_len) 920affae2bfSwdenk { 921128fcac0SSimon Glass __maybe_unused struct usb_device_descriptor *desc; 922f5766139SPuneet Saxena ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); 9230ed27905SSimon Glass int err; 9240ed27905SSimon Glass 9250ed27905SSimon Glass desc = (struct usb_device_descriptor *)tmpbuf; 9260ed27905SSimon Glass 9270ed27905SSimon Glass err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len); 9280ed27905SSimon Glass if (err < expect_len) { 9290ed27905SSimon Glass if (err < 0) { 9300ed27905SSimon Glass printf("unable to get device descriptor (error=%d)\n", 9310ed27905SSimon Glass err); 9320ed27905SSimon Glass return err; 9330ed27905SSimon Glass } else { 9340ed27905SSimon Glass printf("USB device descriptor short read (expected %i, got %i)\n", 9350ed27905SSimon Glass expect_len, err); 9360ed27905SSimon Glass return -EIO; 9370ed27905SSimon Glass } 9380ed27905SSimon Glass } 9390ed27905SSimon Glass memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor)); 9400ed27905SSimon Glass 9410ed27905SSimon Glass return 0; 9420ed27905SSimon Glass } 9430ed27905SSimon Glass 9440ed27905SSimon Glass static int usb_setup_descriptor(struct usb_device *dev, bool do_read) 9450ed27905SSimon Glass { 9465853e133SVivek Gautam /* 94753d8aa0fSSimon Glass * This is a Windows scheme of initialization sequence, with double 94848867208SRemy Bohmer * reset of the device (Linux uses the same sequence) 949c9e8436bSRemy Bohmer * Some equipment is said to work only with such init sequence; this 950c9e8436bSRemy Bohmer * patch is based on the work by Alan Stern: 951de39f8c1SMichael Trimarchi * http://sourceforge.net/mailarchive/forum.php? 952de39f8c1SMichael Trimarchi * thread_id=5729457&forum_id=5398 9539c998aa8SWolfgang Denk */ 9549c998aa8SWolfgang Denk 95553d8aa0fSSimon Glass /* 95653d8aa0fSSimon Glass * send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is 9579c998aa8SWolfgang Denk * only 18 bytes long, this will terminate with a short packet. But if 9589c998aa8SWolfgang Denk * the maxpacket size is 8 or 16 the device may be waiting to transmit 9592b338ef4SHans de Goede * some more, or keeps on retransmitting the 8 byte header. 9602b338ef4SHans de Goede */ 9619c998aa8SWolfgang Denk 9622b338ef4SHans de Goede if (dev->speed == USB_SPEED_LOW) { 9632b338ef4SHans de Goede dev->descriptor.bMaxPacketSize0 = 8; 9642b338ef4SHans de Goede dev->maxpacketsize = PACKET_SIZE_8; 9652b338ef4SHans de Goede } else { 9662b338ef4SHans de Goede dev->descriptor.bMaxPacketSize0 = 64; 96748867208SRemy Bohmer dev->maxpacketsize = PACKET_SIZE_64; 9682b338ef4SHans de Goede } 9692b338ef4SHans de Goede dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; 9702b338ef4SHans de Goede dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; 97148867208SRemy Bohmer 972c008faa7SBin Meng if (do_read && dev->speed == USB_SPEED_FULL) { 973128fcac0SSimon Glass int err; 974862e75c0SSimon Glass 97525c06736SStephen Warren /* 976c008faa7SBin Meng * Validate we've received only at least 8 bytes, not that 977c008faa7SBin Meng * we've received the entire descriptor. The reasoning is: 978c008faa7SBin Meng * - The code only uses fields in the first 8 bytes, so 979c008faa7SBin Meng * that's all we need to have fetched at this stage. 980c008faa7SBin Meng * - The smallest maxpacket size is 8 bytes. Before we know 981c008faa7SBin Meng * the actual maxpacket the device uses, the USB controller 982c008faa7SBin Meng * may only accept a single packet. Consequently we are only 983c008faa7SBin Meng * guaranteed to receive 1 packet (at least 8 bytes) even in 984c008faa7SBin Meng * a non-error case. 98525c06736SStephen Warren * 986c008faa7SBin Meng * At least the DWC2 controller needs to be programmed with 987c008faa7SBin Meng * the number of packets in addition to the number of bytes. 988c008faa7SBin Meng * A request for 64 bytes of data with the maxpacket guessed 989c008faa7SBin Meng * as 64 (above) yields a request for 1 packet. 99025c06736SStephen Warren */ 9910ed27905SSimon Glass err = get_descriptor_len(dev, 64, 8); 9920ed27905SSimon Glass if (err) 993128fcac0SSimon Glass return err; 994128fcac0SSimon Glass } 9959c998aa8SWolfgang Denk 996affae2bfSwdenk dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; 997affae2bfSwdenk dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; 998affae2bfSwdenk switch (dev->descriptor.bMaxPacketSize0) { 999de39f8c1SMichael Trimarchi case 8: 1000de39f8c1SMichael Trimarchi dev->maxpacketsize = PACKET_SIZE_8; 1001de39f8c1SMichael Trimarchi break; 1002de39f8c1SMichael Trimarchi case 16: 1003de39f8c1SMichael Trimarchi dev->maxpacketsize = PACKET_SIZE_16; 1004de39f8c1SMichael Trimarchi break; 1005de39f8c1SMichael Trimarchi case 32: 1006de39f8c1SMichael Trimarchi dev->maxpacketsize = PACKET_SIZE_32; 1007de39f8c1SMichael Trimarchi break; 1008de39f8c1SMichael Trimarchi case 64: 1009de39f8c1SMichael Trimarchi dev->maxpacketsize = PACKET_SIZE_64; 1010de39f8c1SMichael Trimarchi break; 101104ee6ee2SPaul Kocialkowski default: 1012c008faa7SBin Meng printf("%s: invalid max packet size\n", __func__); 101304ee6ee2SPaul Kocialkowski return -EIO; 1014affae2bfSwdenk } 1015128fcac0SSimon Glass 1016128fcac0SSimon Glass return 0; 1017128fcac0SSimon Glass } 1018128fcac0SSimon Glass 101991398f98SSimon Glass static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, 10209eb72dd1SHans de Goede struct usb_device *parent) 102191398f98SSimon Glass { 102291398f98SSimon Glass int err; 102391398f98SSimon Glass 102491398f98SSimon Glass /* 102591398f98SSimon Glass * Allocate usb 3.0 device context. 102691398f98SSimon Glass * USB 3.0 (xHCI) protocol tries to allocate device slot 102791398f98SSimon Glass * and related data structures first. This call does that. 102891398f98SSimon Glass * Refer to sec 4.3.2 in xHCI spec rev1.0 102991398f98SSimon Glass */ 103091398f98SSimon Glass err = usb_alloc_device(dev); 103191398f98SSimon Glass if (err) { 103291398f98SSimon Glass printf("Cannot allocate device context to get SLOT_ID\n"); 103391398f98SSimon Glass return err; 103491398f98SSimon Glass } 103591398f98SSimon Glass err = usb_setup_descriptor(dev, do_read); 103691398f98SSimon Glass if (err) 103791398f98SSimon Glass return err; 1038682c9f8dSHans de Goede err = usb_hub_port_reset(dev, parent); 103991398f98SSimon Glass if (err) 104091398f98SSimon Glass return err; 104191398f98SSimon Glass 104291398f98SSimon Glass dev->devnum = addr; 104391398f98SSimon Glass 104491398f98SSimon Glass err = usb_set_address(dev); /* set address */ 104591398f98SSimon Glass 104691398f98SSimon Glass if (err < 0) { 104791398f98SSimon Glass printf("\n USB device not accepting new address " \ 104891398f98SSimon Glass "(error=%lX)\n", dev->status); 104991398f98SSimon Glass return err; 105091398f98SSimon Glass } 105191398f98SSimon Glass 105291398f98SSimon Glass mdelay(10); /* Let the SET_ADDRESS settle */ 105391398f98SSimon Glass 1054932bb668SBin Meng /* 1055932bb668SBin Meng * If we haven't read device descriptor before, read it here 1056932bb668SBin Meng * after device is assigned an address. This is only applicable 1057932bb668SBin Meng * to xHCI so far. 1058932bb668SBin Meng */ 1059932bb668SBin Meng if (!do_read) { 1060932bb668SBin Meng err = usb_setup_descriptor(dev, true); 1061932bb668SBin Meng if (err) 1062932bb668SBin Meng return err; 1063932bb668SBin Meng } 1064932bb668SBin Meng 106591398f98SSimon Glass return 0; 106691398f98SSimon Glass } 106791398f98SSimon Glass 106895fbfe42SSimon Glass int usb_select_config(struct usb_device *dev) 1069128fcac0SSimon Glass { 10702f1b4302SMarek Vasut unsigned char *tmpbuf = NULL; 10710ed27905SSimon Glass int err; 1072128fcac0SSimon Glass 10730ed27905SSimon Glass err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE); 10740ed27905SSimon Glass if (err) 10750ed27905SSimon Glass return err; 1076128fcac0SSimon Glass 1077affae2bfSwdenk /* correct le values */ 1078c918261cSChristian Eggers le16_to_cpus(&dev->descriptor.bcdUSB); 1079c918261cSChristian Eggers le16_to_cpus(&dev->descriptor.idVendor); 1080c918261cSChristian Eggers le16_to_cpus(&dev->descriptor.idProduct); 1081c918261cSChristian Eggers le16_to_cpus(&dev->descriptor.bcdDevice); 10820ed27905SSimon Glass 1083ef71290bSMarek Vasut /* 1084ef71290bSMarek Vasut * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive 1085ef71290bSMarek Vasut * about this first Get Descriptor request. If there are any other 1086ef71290bSMarek Vasut * requests in the first microframe, the stick crashes. Wait about 1087ef71290bSMarek Vasut * one microframe duration here (1mS for USB 1.x , 125uS for USB 2.0). 1088ef71290bSMarek Vasut */ 1089ef71290bSMarek Vasut mdelay(1); 1090ef71290bSMarek Vasut 1091affae2bfSwdenk /* only support for one config for now */ 1092c75f57fbSStefan Brüns err = usb_get_configuration_len(dev, 0); 1093c75f57fbSStefan Brüns if (err >= 0) { 1094c75f57fbSStefan Brüns tmpbuf = (unsigned char *)malloc_cache_aligned(err); 1095c75f57fbSStefan Brüns if (!tmpbuf) 1096c75f57fbSStefan Brüns err = -ENOMEM; 1097c75f57fbSStefan Brüns else 1098c75f57fbSStefan Brüns err = usb_get_configuration_no(dev, 0, tmpbuf, err); 1099c75f57fbSStefan Brüns } 11008b8d779dSVincent Palatin if (err < 0) { 11018b8d779dSVincent Palatin printf("usb_new_device: Cannot read configuration, " \ 11028b8d779dSVincent Palatin "skipping device %04x:%04x\n", 11038b8d779dSVincent Palatin dev->descriptor.idVendor, dev->descriptor.idProduct); 1104c75f57fbSStefan Brüns free(tmpbuf); 11050ed27905SSimon Glass return err; 11068b8d779dSVincent Palatin } 1107f5766139SPuneet Saxena usb_parse_config(dev, tmpbuf, 0); 1108c75f57fbSStefan Brüns free(tmpbuf); 1109affae2bfSwdenk usb_set_maxpacket(dev); 11100ed27905SSimon Glass /* 11110ed27905SSimon Glass * we set the default configuration here 11120ed27905SSimon Glass * This seems premature. If the driver wants a different configuration 11130ed27905SSimon Glass * it will need to select itself. 11140ed27905SSimon Glass */ 11150ed27905SSimon Glass err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue); 11160ed27905SSimon Glass if (err < 0) { 11176f5794a6SRemy Bohmer printf("failed to set default configuration " \ 11186f5794a6SRemy Bohmer "len %d, status %lX\n", dev->act_len, dev->status); 11190ed27905SSimon Glass return err; 1120affae2bfSwdenk } 1121f647bf0bSMarek Vasut 1122f647bf0bSMarek Vasut /* 1123f647bf0bSMarek Vasut * Wait until the Set Configuration request gets processed by the 1124f647bf0bSMarek Vasut * device. This is required by at least SanDisk Cruzer Pop USB 2.0 1125f647bf0bSMarek Vasut * and Kingston DT Ultimate 32GB USB 3.0 on DWC2 OTG controller. 1126f647bf0bSMarek Vasut */ 1127f647bf0bSMarek Vasut mdelay(10); 1128f647bf0bSMarek Vasut 1129ceb4972aSVivek Gautam debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", 11306f5794a6SRemy Bohmer dev->descriptor.iManufacturer, dev->descriptor.iProduct, 11316f5794a6SRemy Bohmer dev->descriptor.iSerialNumber); 1132affae2bfSwdenk memset(dev->mf, 0, sizeof(dev->mf)); 1133affae2bfSwdenk memset(dev->prod, 0, sizeof(dev->prod)); 1134affae2bfSwdenk memset(dev->serial, 0, sizeof(dev->serial)); 1135affae2bfSwdenk if (dev->descriptor.iManufacturer) 11366f5794a6SRemy Bohmer usb_string(dev, dev->descriptor.iManufacturer, 11376f5794a6SRemy Bohmer dev->mf, sizeof(dev->mf)); 1138affae2bfSwdenk if (dev->descriptor.iProduct) 11396f5794a6SRemy Bohmer usb_string(dev, dev->descriptor.iProduct, 11406f5794a6SRemy Bohmer dev->prod, sizeof(dev->prod)); 1141affae2bfSwdenk if (dev->descriptor.iSerialNumber) 11426f5794a6SRemy Bohmer usb_string(dev, dev->descriptor.iSerialNumber, 11436f5794a6SRemy Bohmer dev->serial, sizeof(dev->serial)); 1144ceb4972aSVivek Gautam debug("Manufacturer %s\n", dev->mf); 1145ceb4972aSVivek Gautam debug("Product %s\n", dev->prod); 1146ceb4972aSVivek Gautam debug("SerialNumber %s\n", dev->serial); 11470ed27905SSimon Glass 11480ed27905SSimon Glass return 0; 11490ed27905SSimon Glass } 11500ed27905SSimon Glass 115195fbfe42SSimon Glass int usb_setup_device(struct usb_device *dev, bool do_read, 11529eb72dd1SHans de Goede struct usb_device *parent) 11530ed27905SSimon Glass { 11540ed27905SSimon Glass int addr; 11550ed27905SSimon Glass int ret; 11560ed27905SSimon Glass 11570ed27905SSimon Glass /* We still haven't set the Address yet */ 11580ed27905SSimon Glass addr = dev->devnum; 11590ed27905SSimon Glass dev->devnum = 0; 11600ed27905SSimon Glass 11619eb72dd1SHans de Goede ret = usb_prepare_device(dev, addr, do_read, parent); 11620ed27905SSimon Glass if (ret) 11630ed27905SSimon Glass return ret; 11640ed27905SSimon Glass ret = usb_select_config(dev); 11650ed27905SSimon Glass 11660ed27905SSimon Glass return ret; 11670ed27905SSimon Glass } 11680ed27905SSimon Glass 1169*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB) 11700ed27905SSimon Glass /* 11710ed27905SSimon Glass * By the time we get here, the device has gotten a new device ID 11720ed27905SSimon Glass * and is in the default state. We need to identify the thing and 11730ed27905SSimon Glass * get the ball rolling.. 11740ed27905SSimon Glass * 11750ed27905SSimon Glass * Returns 0 for success, != 0 for error. 11760ed27905SSimon Glass */ 11770ed27905SSimon Glass int usb_new_device(struct usb_device *dev) 11780ed27905SSimon Glass { 11790ed27905SSimon Glass bool do_read = true; 11800ed27905SSimon Glass int err; 11810ed27905SSimon Glass 11820ed27905SSimon Glass /* 11830ed27905SSimon Glass * XHCI needs to issue a Address device command to setup 11840ed27905SSimon Glass * proper device context structures, before it can interact 11850ed27905SSimon Glass * with the device. So a get_descriptor will fail before any 11860ed27905SSimon Glass * of that is done for XHCI unlike EHCI. 11870ed27905SSimon Glass */ 11880a8cc1a3SMasahiro Yamada #ifdef CONFIG_USB_XHCI_HCD 11890ed27905SSimon Glass do_read = false; 11900ed27905SSimon Glass #endif 11919eb72dd1SHans de Goede err = usb_setup_device(dev, do_read, dev->parent); 11920ed27905SSimon Glass if (err) 11930ed27905SSimon Glass return err; 11940ed27905SSimon Glass 11950ed27905SSimon Glass /* Now probe if the device is a hub */ 11960ed27905SSimon Glass err = usb_hub_probe(dev, 0); 11970ed27905SSimon Glass if (err < 0) 11980ed27905SSimon Glass return err; 11990ed27905SSimon Glass 1200affae2bfSwdenk return 0; 1201affae2bfSwdenk } 120295fbfe42SSimon Glass #endif 1203affae2bfSwdenk 120416297cfbSMateusz Zalega __weak 1205bba67914STroy Kisky int board_usb_init(int index, enum usb_init_type init) 120616297cfbSMateusz Zalega { 120716297cfbSMateusz Zalega return 0; 120816297cfbSMateusz Zalega } 1209db378d78SKishon Vijay Abraham I 1210db378d78SKishon Vijay Abraham I __weak 1211db378d78SKishon Vijay Abraham I int board_usb_cleanup(int index, enum usb_init_type init) 1212db378d78SKishon Vijay Abraham I { 1213db378d78SKishon Vijay Abraham I return 0; 1214db378d78SKishon Vijay Abraham I } 121595fbfe42SSimon Glass 121695fbfe42SSimon Glass bool usb_device_has_child_on_port(struct usb_device *parent, int port) 121795fbfe42SSimon Glass { 1218*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB) 121995fbfe42SSimon Glass return false; 122095fbfe42SSimon Glass #else 122195fbfe42SSimon Glass return parent->children[port] != NULL; 122295fbfe42SSimon Glass #endif 122395fbfe42SSimon Glass } 122495fbfe42SSimon Glass 1225*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB) 1226faa7db24SStefan Brüns void usb_find_usb2_hub_address_port(struct usb_device *udev, 1227faa7db24SStefan Brüns uint8_t *hub_address, uint8_t *hub_port) 1228faa7db24SStefan Brüns { 1229faa7db24SStefan Brüns struct udevice *parent; 1230faa7db24SStefan Brüns struct usb_device *uparent, *ttdev; 1231faa7db24SStefan Brüns 1232faa7db24SStefan Brüns /* 1233faa7db24SStefan Brüns * When called from usb-uclass.c: usb_scan_device() udev->dev points 1234faa7db24SStefan Brüns * to the parent udevice, not the actual udevice belonging to the 1235faa7db24SStefan Brüns * udev as the device is not instantiated yet. So when searching 1236faa7db24SStefan Brüns * for the first usb-2 parent start with udev->dev not 1237faa7db24SStefan Brüns * udev->dev->parent . 1238faa7db24SStefan Brüns */ 1239faa7db24SStefan Brüns ttdev = udev; 1240faa7db24SStefan Brüns parent = udev->dev; 1241faa7db24SStefan Brüns uparent = dev_get_parent_priv(parent); 1242faa7db24SStefan Brüns 1243faa7db24SStefan Brüns while (uparent->speed != USB_SPEED_HIGH) { 1244faa7db24SStefan Brüns struct udevice *dev = parent; 1245faa7db24SStefan Brüns 1246faa7db24SStefan Brüns if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) { 1247faa7db24SStefan Brüns printf("Error: Cannot find high speed parent of usb-1 device\n"); 1248faa7db24SStefan Brüns *hub_address = 0; 1249faa7db24SStefan Brüns *hub_port = 0; 1250faa7db24SStefan Brüns return; 1251faa7db24SStefan Brüns } 1252faa7db24SStefan Brüns 1253faa7db24SStefan Brüns ttdev = dev_get_parent_priv(dev); 1254faa7db24SStefan Brüns parent = dev->parent; 1255faa7db24SStefan Brüns uparent = dev_get_parent_priv(parent); 1256faa7db24SStefan Brüns } 1257faa7db24SStefan Brüns *hub_address = uparent->devnum; 1258faa7db24SStefan Brüns *hub_port = ttdev->portnr; 1259faa7db24SStefan Brüns } 1260faa7db24SStefan Brüns #else 1261faa7db24SStefan Brüns void usb_find_usb2_hub_address_port(struct usb_device *udev, 1262faa7db24SStefan Brüns uint8_t *hub_address, uint8_t *hub_port) 1263faa7db24SStefan Brüns { 1264faa7db24SStefan Brüns /* Find out the nearest parent which is high speed */ 1265faa7db24SStefan Brüns while (udev->parent->parent != NULL) 1266faa7db24SStefan Brüns if (udev->parent->speed != USB_SPEED_HIGH) { 1267faa7db24SStefan Brüns udev = udev->parent; 1268faa7db24SStefan Brüns } else { 1269faa7db24SStefan Brüns *hub_address = udev->parent->devnum; 1270faa7db24SStefan Brüns *hub_port = udev->portnr; 1271faa7db24SStefan Brüns return; 1272faa7db24SStefan Brüns } 1273faa7db24SStefan Brüns 1274faa7db24SStefan Brüns printf("Error: Cannot find high speed parent of usb-1 device\n"); 1275faa7db24SStefan Brüns *hub_address = 0; 1276faa7db24SStefan Brüns *hub_port = 0; 1277faa7db24SStefan Brüns } 1278faa7db24SStefan Brüns #endif 1279faa7db24SStefan Brüns 1280faa7db24SStefan Brüns 1281affae2bfSwdenk /* EOF */ 1282