Newer
Older
dev->maxpacketsize = PACKET_SIZE_8;
break;
case 16:
dev->maxpacketsize = PACKET_SIZE_16;
break;
case 32:
dev->maxpacketsize = PACKET_SIZE_32;
break;
case 64:
dev->maxpacketsize = PACKET_SIZE_64;
break;
default:
printf("%s: invalid max packet size\n", __func__);
return -EIO;
return 0;
}
static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
struct usb_device *parent)
/*
* Allocate usb 3.0 device context.
* USB 3.0 (xHCI) protocol tries to allocate device slot
* and related data structures first. This call does that.
* Refer to sec 4.3.2 in xHCI spec rev1.0
*/
err = usb_alloc_device(dev);
if (err) {
printf("Cannot allocate device context to get SLOT_ID\n");
}
err = usb_setup_descriptor(dev, do_read);
if (err)
return err;
err = usb_hub_port_reset(dev, parent);
if (err)
return err;
dev->devnum = addr;
err = usb_set_address(dev); /* set address */
if (err < 0) {
printf("\n USB device not accepting new address " \
"(error=%lX)\n", dev->status);
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;
}
int usb_select_config(struct usb_device *dev)
err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
if (err)
return err;
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
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);
err = usb_get_configuration_len(dev, 0);
if (err >= 0) {
tmpbuf = (unsigned char *)malloc_cache_aligned(err);
if (!tmpbuf)
err = -ENOMEM;
else
err = usb_get_configuration_no(dev, 0, tmpbuf, err);
}
if (err < 0) {
printf("usb_new_device: Cannot read configuration, " \
"skipping device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
/*
* we set the default configuration here
* This seems premature. If the driver wants a different configuration
* it will need to select itself.
*/
err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
if (err < 0) {
printf("failed to set default configuration " \
"len %d, status %lX\n", dev->act_len, dev->status);
/*
* 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);
memset(dev->mf, 0, sizeof(dev->mf));
memset(dev->prod, 0, sizeof(dev->prod));
memset(dev->serial, 0, sizeof(dev->serial));
if (dev->descriptor.iManufacturer)
usb_string(dev, dev->descriptor.iManufacturer,
dev->mf, sizeof(dev->mf));
usb_string(dev, dev->descriptor.iProduct,
dev->prod, sizeof(dev->prod));
usb_string(dev, dev->descriptor.iSerialNumber,
dev->serial, sizeof(dev->serial));
debug("Manufacturer %s\n", dev->mf);
debug("Product %s\n", dev->prod);
debug("SerialNumber %s\n", dev->serial);
return 0;
}
int usb_setup_device(struct usb_device *dev, bool do_read,
struct usb_device *parent)
{
int addr;
int ret;
/* We still haven't set the Address yet */
addr = dev->devnum;
dev->devnum = 0;
ret = usb_prepare_device(dev, addr, do_read, parent);
if (ret)
return ret;
ret = usb_select_config(dev);
return ret;
}
#ifndef CONFIG_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
* get the ball rolling..
*
* Returns 0 for success, != 0 for error.
*/
int usb_new_device(struct usb_device *dev)
{
bool do_read = true;
int err;
/*
* XHCI needs to issue a Address device command to setup
* proper device context structures, before it can interact
* with the device. So a get_descriptor will fail before any
* of that is done for XHCI unlike EHCI.
*/
#ifdef CONFIG_USB_XHCI_HCD
do_read = false;
#endif
err = usb_setup_device(dev, do_read, dev->parent);
if (err)
return err;
/* Now probe if the device is a hub */
err = usb_hub_probe(dev, 0);
if (err < 0)
return err;
int board_usb_init(int index, enum usb_init_type init)
__weak
int board_usb_cleanup(int index, enum usb_init_type init)
{
return 0;
}
bool usb_device_has_child_on_port(struct usb_device *parent, int port)
{
#ifdef CONFIG_DM_USB
return false;
#else
return parent->children[port] != NULL;
#endif
}
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
#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