* 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,
}
epno = dev->config.if_desc[ifno].no_of_ep;
if_desc = &dev->config.if_desc[ifno];
- if (epno > USB_MAXENDPOINTS) {
+ if (epno >= USB_MAXENDPOINTS) {
printf("Interface %d has too many endpoints!\n",
if_desc->desc.bInterfaceNumber);
return -EINVAL;
static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub)
{
- if (hub) {
- unsigned short portstatus;
- int err;
-
- /* reset the port for the second time */
- err = legacy_hub_port_reset(hub, dev->portnr - 1, &portstatus);
- if (err < 0) {
- printf("\n Couldn't reset port %i\n", dev->portnr);
- return err;
- }
- } else {
+ if (!hub)
usb_reset_root_port(dev);
- }
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);
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) {
"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);
#endif
}
+#ifdef CONFIG_DM_USB
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+ uint8_t *hub_address, uint8_t *hub_port)
+{
+ struct udevice *parent;
+ struct usb_device *uparent, *ttdev;
+
+ /*
+ * When called from usb-uclass.c: usb_scan_device() udev->dev points
+ * to the parent udevice, not the actual udevice belonging to the
+ * udev as the device is not instantiated yet. So when searching
+ * for the first usb-2 parent start with udev->dev not
+ * udev->dev->parent .
+ */
+ ttdev = udev;
+ parent = udev->dev;
+ uparent = dev_get_parent_priv(parent);
+
+ while (uparent->speed != USB_SPEED_HIGH) {
+ struct udevice *dev = parent;
+
+ if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
+ printf("Error: Cannot find high speed parent of usb-1 device\n");
+ *hub_address = 0;
+ *hub_port = 0;
+ return;
+ }
+
+ ttdev = dev_get_parent_priv(dev);
+ parent = dev->parent;
+ uparent = dev_get_parent_priv(parent);
+ }
+ *hub_address = uparent->devnum;
+ *hub_port = ttdev->portnr;
+}
+#else
+void usb_find_usb2_hub_address_port(struct usb_device *udev,
+ uint8_t *hub_address, uint8_t *hub_port)
+{
+ /* Find out the nearest parent which is high speed */
+ while (udev->parent->parent != NULL)
+ if (udev->parent->speed != USB_SPEED_HIGH) {
+ udev = udev->parent;
+ } else {
+ *hub_address = udev->parent->devnum;
+ *hub_port = udev->portnr;
+ return;
+ }
+
+ printf("Error: Cannot find high speed parent of usb-1 device\n");
+ *hub_address = 0;
+ *hub_port = 0;
+}
+#endif
+
+
/* EOF */