X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fusb.c;h=349e838f1d57785dff86eb5e8ee04d682d3841ec;hb=d40aa43f3f25e407cb12236b6171a186491d2f11;hp=45a5a0f9c73039def05eaf31362e8229ce6aeb77;hpb=83d95b67d3731e39292d858924ade3be68c167af;p=oweals%2Fu-boot.git diff --git a/common/usb.c b/common/usb.c index 45a5a0f9c7..349e838f1d 100644 --- a/common/usb.c +++ b/common/usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Most of this source has been derived from the Linux USB * project: @@ -13,8 +14,6 @@ * * Adapted for U-Boot: * (C) Copyright 2001 Denis Peter, MPL AG Switzerland - * - * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,16 +37,13 @@ #include #include #include -#ifdef CONFIG_4xx -#include -#endif #define USB_BUFSIZ 512 static int asynch_allowed; char usb_started; /* flag for the started/stopped USB status */ -#ifndef CONFIG_DM_USB +#if !CONFIG_IS_ENABLED(DM_USB) static struct usb_device usb_dev[USB_MAX_DEVICE]; static int dev_index; @@ -187,7 +184,7 @@ int usb_disable_asynch(int disable) asynch_allowed = !disable; return old_value; } -#endif /* !CONFIG_DM_USB */ +#endif /* !CONFIG_IS_ENABLED(DM_USB) */ /*------------------------------------------------------------------- @@ -196,12 +193,15 @@ int usb_disable_asynch(int disable) */ /* - * submits an Interrupt Message + * submits an Interrupt Message. Some drivers may implement non-blocking + * polling: when non-block is true and the device is not responding return + * -EAGAIN instead of waiting for device to respond. */ -int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, - void *buffer, int transfer_len, int interval) +int usb_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, int interval, bool nonblock) { - return submit_int_msg(dev, pipe, buffer, transfer_len, interval); + return submit_int_msg(dev, pipe, buffer, transfer_len, interval, + nonblock); } /* @@ -210,7 +210,7 @@ int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). - * returns the transfered length if OK or -1 if error. The transfered length + * returns the transferred length if OK or -1 if error. The transferred length * and the current status are stored in the dev->act_len and dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, @@ -440,12 +440,13 @@ static int usb_parse_config(struct usb_device *dev, } break; case USB_DT_ENDPOINT: - if (head->bLength != USB_DT_ENDPOINT_SIZE) { + if (head->bLength != USB_DT_ENDPOINT_SIZE && + head->bLength != USB_DT_ENDPOINT_AUDIO_SIZE) { printf("ERROR: Invalid USB EP length (%d)\n", head->bLength); break; } - if (index + USB_DT_ENDPOINT_SIZE > + if (index + head->bLength > dev->config.desc.wTotalLength) { puts("USB EP descriptor overflowed buffer!\n"); break; @@ -557,12 +558,10 @@ int usb_clear_halt(struct usb_device *dev, int pipe) static 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), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, - buf, size, USB_CNTL_TIMEOUT); - return res; + return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (type << 8) + index, 0, buf, size, + USB_CNTL_TIMEOUT); } /********************************************************************** @@ -612,14 +611,10 @@ int usb_get_configuration_no(struct usb_device *dev, int cfgno, */ static int usb_set_address(struct usb_device *dev) { - int res; - debug("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; + + return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS, + 0, (dev->devnum), 0, NULL, 0, USB_CNTL_TIMEOUT); } /******************************************************************** @@ -858,7 +853,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) * the USB device are static allocated [USB_MAX_DEVICE]. */ -#ifndef CONFIG_DM_USB +#if !CONFIG_IS_ENABLED(DM_USB) /* returns a pointer to the device with the index [index]. * if the device is not assigned (dev->devnum==-1) returns NULL @@ -915,7 +910,7 @@ __weak int usb_alloc_device(struct usb_device *udev) { return 0; } -#endif /* !CONFIG_DM_USB */ +#endif /* !CONFIG_IS_ENABLED(DM_USB) */ static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub) { @@ -978,23 +973,24 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read) dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; - if (do_read) { + if (do_read && dev->speed == USB_SPEED_FULL) { int err; /* - * Validate we've received only at least 8 bytes, not that we've - * received the entire descriptor. The reasoning is: - * - The code only uses fields in the first 8 bytes, so that's all we - * need to have fetched at this stage. - * - The smallest maxpacket size is 8 bytes. Before we know the actual - * maxpacket the device uses, the USB controller may only accept a - * single packet. Consequently we are only guaranteed to receive 1 - * packet (at least 8 bytes) even in a non-error case. + * Validate we've received only at least 8 bytes, not that + * we've received the entire descriptor. The reasoning is: + * - The code only uses fields in the first 8 bytes, so + * that's all we need to have fetched at this stage. + * - The smallest maxpacket size is 8 bytes. Before we know + * the actual maxpacket the device uses, the USB controller + * may only accept a single packet. Consequently we are only + * guaranteed to receive 1 packet (at least 8 bytes) even in + * a non-error case. * - * At least the DWC2 controller needs to be programmed with the number - * of packets in addition to the number of bytes. A request for 64 - * bytes of data with the maxpacket guessed as 64 (above) yields a - * request for 1 packet. + * At least the DWC2 controller needs to be programmed with + * the number of packets in addition to the number of bytes. + * A request for 64 bytes of data with the maxpacket guessed + * as 64 (above) yields a request for 1 packet. */ err = get_descriptor_len(dev, 64, 8); if (err) @@ -1017,7 +1013,7 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read) dev->maxpacketsize = PACKET_SIZE_64; break; default: - printf("usb_new_device: invalid max packet size\n"); + printf("%s: invalid max packet size\n", __func__); return -EIO; } @@ -1059,12 +1055,23 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, mdelay(10); /* Let the SET_ADDRESS settle */ + /* + * If we haven't read device descriptor before, read it here + * after device is assigned an address. This is only applicable + * to xHCI so far. + */ + if (!do_read) { + err = usb_setup_descriptor(dev, true); + if (err) + return err; + } + return 0; } int usb_select_config(struct usb_device *dev) { - unsigned char *tmpbuf = 0; + unsigned char *tmpbuf = NULL; int err; err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE); @@ -1077,6 +1084,14 @@ int usb_select_config(struct usb_device *dev) le16_to_cpus(&dev->descriptor.idProduct); le16_to_cpus(&dev->descriptor.bcdDevice); + /* + * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive + * about this first Get Descriptor request. If there are any other + * requests in the first microframe, the stick crashes. Wait about + * one microframe duration here (1mS for USB 1.x , 125uS for USB 2.0). + */ + mdelay(1); + /* only support for one config for now */ err = usb_get_configuration_len(dev, 0); if (err >= 0) { @@ -1107,6 +1122,14 @@ int usb_select_config(struct usb_device *dev) "len %d, status %lX\n", dev->act_len, dev->status); return err; } + + /* + * Wait until the Set Configuration request gets processed by the + * device. This is required by at least SanDisk Cruzer Pop USB 2.0 + * and Kingston DT Ultimate 32GB USB 3.0 on DWC2 OTG controller. + */ + mdelay(10); + debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber); @@ -1147,7 +1170,7 @@ int usb_setup_device(struct usb_device *dev, bool do_read, return ret; } -#ifndef CONFIG_DM_USB +#if !CONFIG_IS_ENABLED(DM_USB) /* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and @@ -1166,7 +1189,7 @@ int usb_new_device(struct usb_device *dev) * with the device. So a get_descriptor will fail before any * of that is done for XHCI unlike EHCI. */ -#ifdef CONFIG_USB_XHCI +#ifdef CONFIG_USB_XHCI_HCD do_read = false; #endif err = usb_setup_device(dev, do_read, dev->parent); @@ -1196,14 +1219,14 @@ int board_usb_cleanup(int index, enum usb_init_type init) bool usb_device_has_child_on_port(struct usb_device *parent, int port) { -#ifdef CONFIG_DM_USB +#if CONFIG_IS_ENABLED(DM_USB) return false; #else return parent->children[port] != NULL; #endif } -#ifdef CONFIG_DM_USB +#if CONFIG_IS_ENABLED(DM_USB) void usb_find_usb2_hub_address_port(struct usb_device *udev, uint8_t *hub_address, uint8_t *hub_port) {