Beispiel #1
0
static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
					  struct QH *qh)
{
	struct usb_device *ttdev;
	int parent_devnum;

	if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
		return;

	/*
	 * For full / low speed devices we need to get the devnum and portnr of
	 * the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
	 * in the tree before that one!
	 */
#ifdef CONFIG_DM_USB
	/*
	 * 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 .
	 */
	struct udevice *parent;
	struct usb_device *uparent;

	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("ehci: Error cannot find high-speed parent of usb-1 device\n");
			return;
		}

		ttdev = dev_get_parent_priv(dev);
		parent = dev->parent;
		uparent = dev_get_parent_priv(parent);
	}
	parent_devnum = uparent->devnum;
#else
	ttdev = udev;
	while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
		ttdev = ttdev->parent;
	if (!ttdev->parent)
		return;
	parent_devnum = ttdev->parent->devnum;
#endif

	qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
				     QH_ENDPT2_HUBADDR(parent_devnum));
}
Beispiel #2
0
int mcs7830_write_hwaddr(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);

	return mcs7830_write_mac_common(udev, pdata->enetaddr);
}
Beispiel #3
0
int dm_spi_claim_bus(struct udevice *dev)
{
	struct udevice *bus = dev->parent;
	struct dm_spi_ops *ops = spi_get_ops(bus);
	struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
	struct spi_slave *slave = dev_get_parent_priv(dev);
	int speed;
	int ret;

	speed = slave->max_hz;
	if (spi->max_hz) {
		if (speed)
			speed = min(speed, (int)spi->max_hz);
		else
			speed = spi->max_hz;
	}
	if (!speed)
		speed = 100000;
	if (speed != slave->speed) {
		ret = spi_set_speed_mode(bus, speed, slave->mode);
		if (ret)
			return ret;
		slave->speed = speed;
	}

	return ops->claim_bus ? ops->claim_bus(dev) : 0;
}
static int fsl_qspi_child_pre_probe(struct udevice *dev)
{
	struct spi_slave *slave = dev_get_parent_priv(dev);

	slave->max_write_size = TX_BUFFER_SIZE;

	return 0;
}
Beispiel #5
0
static int testbus_child_pre_probe(struct udevice *dev)
{
	struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);

	parent_data->flag += FLAG_CHILD_PROBED;

	return 0;
}
Beispiel #6
0
/* Test that the bus can store data about each child */
static int test_bus_parent_data(struct unit_test_state *uts)
{
	struct dm_test_parent_data *parent_data;
	struct udevice *bus, *dev;
	struct uclass *uc;
	int value;

	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));

	/* Check that parent data is allocated */
	ut_assertok(device_find_child_by_seq(bus, 0, true, &dev));
	ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
	parent_data = dev_get_parent_priv(dev);
	ut_assert(NULL != parent_data);

	/* Check that it starts at 0 and goes away when device is removed */
	parent_data->sum += 5;
	ut_asserteq(5, parent_data->sum);
	device_remove(dev);
	ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));

	/* Check that we can do this twice */
	ut_assertok(device_get_child_by_seq(bus, 0, &dev));
	parent_data = dev_get_parent_priv(dev);
	ut_assert(NULL != parent_data);
	parent_data->sum += 5;
	ut_asserteq(5, parent_data->sum);

	/* Add parent data to all children */
	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));
	value = 5;
	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus) {
			ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
			continue;
		}
		ut_assertok(device_probe(dev));
		parent_data = dev_get_parent_priv(dev);

		parent_data->sum = value;
		value += 5;
	}

	/* Check it is still there */
	value = 5;
	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		parent_data = dev_get_parent_priv(dev);

		ut_asserteq(value, parent_data->sum);
		value += 5;
	}

	return 0;
}
Beispiel #7
0
static int zynqmp_qspi_child_pre_probe(struct udevice *bus)
{
	struct spi_slave *slave = dev_get_parent_priv(bus);
	struct zynqmp_qspi_priv *priv = dev_get_priv(bus->parent);

	slave->option = priv->is_dual;
	slave->bytemode = SPI_4BYTE_MODE;

	return 0;
}
Beispiel #8
0
static int testbus_child_post_remove(struct udevice *dev)
{
	struct dm_test_parent_data *parent_data = dev_get_parent_priv(dev);
	struct dm_test_state *dms = test_state;

	parent_data->flag += FLAG_CHILD_REMOVED;
	if (dms)
		dms->removed = dev;

	return 0;
}
Beispiel #9
0
static int spi_flash_std_probe(struct udevice *dev)
{
	struct spi_slave *slave = dev_get_parent_priv(dev);
	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
	struct spi_flash *flash;

	flash = dev_get_uclass_priv(dev);
	flash->dev = dev;
	flash->spi = slave;
	debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
	return spi_flash_probe_slave(flash);
}
Beispiel #10
0
static int zynq_qspi_child_pre_probe(struct udevice *bus)
{
    struct spi_slave *slave = dev_get_parent_priv(bus);
    struct zynq_qspi_priv *priv = dev_get_priv(bus->parent);

    slave->option = priv->is_dual;
    slave->dio = priv->is_dio;
    slave->op_mode_rx = SPI_OPM_RX_QOF;
    slave->op_mode_tx = SPI_OPM_TX_QPP;

    return 0;
}
Beispiel #11
0
/* Compatibility function - to be removed */
struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
				      int bus_node)
{
	struct udevice *bus, *dev;
	int ret;

	ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
	if (ret)
		return NULL;
	ret = device_get_child_by_of_offset(bus, node, &dev);
	if (ret)
		return NULL;
	return dev_get_parent_priv(dev);
}
Beispiel #12
0
int zynqmp_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout,
		     void *din, unsigned long flags)
{
	struct udevice *bus = dev->parent;
	struct zynqmp_qspi_priv *priv = dev_get_priv(bus);
	struct spi_slave *slave = dev_get_parent_priv(dev);

	debug("%s: priv: 0x%08lx bitlen: %d dout: 0x%08lx ", __func__,
	      (unsigned long)priv, bitlen, (unsigned long)dout);
	debug("din: 0x%08lx flags: 0x%lx\n", (unsigned long)din, flags);

	priv->tx_buf = dout;
	priv->rx_buf = din;
	priv->len = bitlen / 8;

	/*
	 * Festering sore.
	 * Assume that the beginning of a transfer with bits to
	 * transmit must contain a device command.
	 */
	if (dout && flags & SPI_XFER_BEGIN)
		priv->is_inst = 1;
	else
		priv->is_inst = 0;

	if (flags & SPI_XFER_END)
		priv->cs_change = 1;
	else
		priv->cs_change = 0;

	if (flags & SPI_XFER_U_PAGE)
		priv->u_page = 1;
	else
		priv->u_page = 0;

	priv->stripe = 0;
	priv->bus = 0;

	if (priv->is_dual == SF_DUAL_PARALLEL_FLASH) {
		if (flags & SPI_XFER_MASK)
			priv->bus = (flags & SPI_XFER_MASK) >> 8;
		if (flags & SPI_XFER_STRIPE)
			priv->stripe = 1;
	}

	priv->dummy_bytes = slave->dummy_bytes;
	zynqmp_qspi_transfer(priv);

	return 0;
}
Beispiel #13
0
/* Test that the bus ops are called when a child is probed/removed */
static int dm_test_bus_parent_ops(struct unit_test_state *uts)
{
	struct dm_test_parent_data *parent_data;
	struct dm_test_state *dms = uts->priv;
	struct udevice *bus, *dev;
	struct uclass *uc;

	test_state = dms;
	ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
	ut_assertok(uclass_get(UCLASS_TEST_FDT, &uc));

	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));

		ut_assertok(device_probe(dev));
		parent_data = dev_get_parent_priv(dev);
		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
	}

	uclass_foreach_dev(dev, uc) {
		/* Ignore these if they are not on this bus */
		if (dev->parent != bus)
			continue;
		parent_data = dev_get_parent_priv(dev);
		ut_asserteq(FLAG_CHILD_PROBED, parent_data->flag);
		ut_assertok(device_remove(dev));
		ut_asserteq_ptr(NULL, dev_get_parent_priv(dev));
		ut_asserteq_ptr(dms->removed, dev);
	}
	test_state = NULL;

	return 0;
}
Beispiel #14
0
static int mcs7830_eth_probe(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct mcs7830_private *priv = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct ueth_data *ueth = &priv->ueth;

	if (mcs7830_basic_reset(udev, priv))
		return 0;

	if (mcs7830_read_mac(udev, pdata->enetaddr))
		return 0;

	return usb_ether_register(dev, ueth, MCS7830_RX_URB_SIZE);
}
Beispiel #15
0
/*
 * st33zp24_spi_send
 * Send byte to TPM register according to the ST33ZP24 SPI protocol.
 * @param: tpm, the chip description
 * @param: tpm_register, the tpm tis register where the data should be written
 * @param: tpm_data, the tpm_data to write inside the tpm_register
 * @param: tpm_size, The length of the data
 * @return: should be zero if success else a negative error code.
 */
static int st33zp24_spi_write(struct udevice *dev, u8 tpm_register,
			      const u8 *tpm_data, size_t tpm_size)
{
	int total_length = 0, ret;
	struct spi_slave *slave = dev_get_parent_priv(dev);
	struct st33zp24_spi_phy *phy = dev_get_platdata(dev);

	u8 *tx_buf = (u8 *)phy->tx_buf;
	u8 *rx_buf = phy->rx_buf;

	tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0;
	tx_buf[total_length++] = tpm_register;

	if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) {
		tx_buf[total_length++] = tpm_size >> 8;
		tx_buf[total_length++] = tpm_size;
	}
Beispiel #16
0
static int spi_child_pre_probe(struct udevice *dev)
{
	struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
	struct spi_slave *slave = dev_get_parent_priv(dev);

	/*
	 * This is needed because we pass struct spi_slave around the place
	 * instead slave->dev (a struct udevice). So we have to have some
	 * way to access the slave udevice given struct spi_slave. Once we
	 * change the SPI API to use udevice instead of spi_slave, we can
	 * drop this.
	 */
	slave->dev = dev;

	slave->max_hz = plat->max_hz;
	slave->mode = plat->mode;
	slave->wordlen = SPI_DEFAULT_WORDLEN;

	return 0;
}
Beispiel #17
0
int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
		       const char *drv_name, const char *dev_name,
		       struct udevice **busp, struct spi_slave **devp)
{
	struct udevice *bus, *dev;
	struct dm_spi_slave_platdata *plat;
	bool created = false;
	int ret;

	ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
	if (ret) {
		printf("Invalid bus %d (err=%d)\n", busnum, ret);
		return ret;
	}
	ret = spi_find_chip_select(bus, cs, &dev);

	/*
	 * If there is no such device, create one automatically. This means
	 * that we don't need a device tree node or platform data for the
	 * SPI flash chip - we will bind to the correct driver.
	 */
	if (ret == -ENODEV && drv_name) {
		debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
		      __func__, dev_name, busnum, cs, drv_name);
		ret = device_bind_driver(bus, drv_name, dev_name, &dev);
		if (ret)
			return ret;
		plat = dev_get_parent_platdata(dev);
		plat->cs = cs;
		plat->max_hz = speed;
		plat->mode = mode;
		created = true;
	} else if (ret) {
		printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
		       ret);
		return ret;
	}

	if (!device_active(dev)) {
		struct spi_slave *slave;

		ret = device_probe(dev);
		if (ret)
			goto err;
		slave = dev_get_parent_priv(dev);
		slave->dev = dev;
	}

	plat = dev_get_parent_platdata(dev);
	if (!speed) {
		speed = plat->max_hz;
		mode = plat->mode;
	}
	ret = spi_set_speed_mode(bus, speed, mode);
	if (ret)
		goto err;

	*busp = bus;
	*devp = dev_get_parent_priv(dev);
	debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp);

	return 0;

err:
	debug("%s: Error path, created=%d, device '%s'\n", __func__,
	      created, dev->name);
	if (created) {
		device_remove(dev);
		device_unbind(dev);
	}

	return ret;
}
Beispiel #18
0
int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize)
{
	struct usb_device *udev = dev_get_parent_priv(dev);
	struct usb_interface_descriptor *iface_desc;
	bool ep_in_found = false, ep_out_found = false;
	struct usb_interface *iface;
	const int ifnum = 0; /* Always use interface 0 */
	int ret, i;

	iface = &udev->config.if_desc[ifnum];
	iface_desc = &udev->config.if_desc[ifnum].desc;

	/* Initialize the ueth_data structure with some useful info */
	ueth->ifnum = ifnum;
	ueth->subclass = iface_desc->bInterfaceSubClass;
	ueth->protocol = iface_desc->bInterfaceProtocol;

	/*
	 * We are expecting a minimum of 3 endpoints - in, out (bulk), and int.
	 * We will ignore any others.
	 */
	for (i = 0; i < iface_desc->bNumEndpoints; i++) {
		int ep_addr = iface->ep_desc[i].bEndpointAddress;

		/* is it an BULK endpoint? */
		if ((iface->ep_desc[i].bmAttributes &
		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
			if (ep_addr & USB_DIR_IN && !ep_in_found) {
				ueth->ep_in = ep_addr &
					USB_ENDPOINT_NUMBER_MASK;
				ep_in_found = true;
			} else if (!(ep_addr & USB_DIR_IN) && !ep_out_found) {
				ueth->ep_out = ep_addr &
					USB_ENDPOINT_NUMBER_MASK;
				ep_out_found = true;
			}
		}

		/* is it an interrupt endpoint? */
		if ((iface->ep_desc[i].bmAttributes &
		    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
			ueth->ep_int = iface->ep_desc[i].bEndpointAddress &
				USB_ENDPOINT_NUMBER_MASK;
			ueth->irqinterval = iface->ep_desc[i].bInterval;
		}
	}
	debug("Endpoints In %d Out %d Int %d\n", ueth->ep_in, ueth->ep_out,
	      ueth->ep_int);

	/* Do some basic sanity checks, and bail if we find a problem */
	if (!ueth->ep_in || !ueth->ep_out || !ueth->ep_int) {
		debug("%s: %s: Cannot find endpoints\n", __func__, dev->name);
		return -ENXIO;
	}

	ueth->rxsize = rxsize;
	ueth->rxbuf = memalign(ARCH_DMA_MINALIGN, rxsize);
	if (!ueth->rxbuf)
		return -ENOMEM;

	ret = usb_set_interface(udev, iface_desc->bInterfaceNumber, ifnum);
	if (ret) {
		debug("%s: %s: Cannot set interface: %d\n", __func__, dev->name,
		      ret);
		return ret;
	}
	ueth->pusb_dev = udev;

	return 0;
}
Beispiel #19
0
static int mcs7830_eth_start(struct udevice *dev)
{
	struct usb_device *udev = dev_get_parent_priv(dev);

	return mcs7830_init_common(udev);
}
Beispiel #20
0
/**
 * Setup an xHCI virtual device for a Set Address command
 *
 * @param udev pointer to the Device Data Structure
 * @return returns negative value on failure else 0 on success
 */
void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
				     struct usb_device *udev, int hop_portnr)
{
	struct xhci_virt_device *virt_dev;
	struct xhci_ep_ctx *ep0_ctx;
	struct xhci_slot_ctx *slot_ctx;
	u32 port_num = 0;
	u64 trb_64 = 0;
	int slot_id = udev->slot_id;
	int speed = udev->speed;
	int route = 0;
#if CONFIG_IS_ENABLED(DM_USB)
	struct usb_device *dev = udev;
	struct usb_hub_device *hub;
#endif

	virt_dev = ctrl->devs[slot_id];

	BUG_ON(!virt_dev);

	/* Extract the EP0 and Slot Ctrl */
	ep0_ctx = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx, 0);
	slot_ctx = xhci_get_slot_ctx(ctrl, virt_dev->in_ctx);

	/* Only the control endpoint is valid - one endpoint context */
	slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1));

#if CONFIG_IS_ENABLED(DM_USB)
	/* Calculate the route string for this device */
	port_num = dev->portnr;
	while (!usb_hub_is_root_hub(dev->dev)) {
		hub = dev_get_uclass_priv(dev->dev);
		/*
		 * Each hub in the topology is expected to have no more than
		 * 15 ports in order for the route string of a device to be
		 * unique. SuperSpeed hubs are restricted to only having 15
		 * ports, but FS/LS/HS hubs are not. The xHCI specification
		 * says that if the port number the device is greater than 15,
		 * that portion of the route string shall be set to 15.
		 */
		if (port_num > 15)
			port_num = 15;
		route |= port_num << (hub->hub_depth * 4);
		dev = dev_get_parent_priv(dev->dev);
		port_num = dev->portnr;
		dev = dev_get_parent_priv(dev->dev->parent);
	}

	debug("route string %x\n", route);
#endif
	slot_ctx->dev_info |= route;

	switch (speed) {
	case USB_SPEED_SUPER:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
		break;
	case USB_SPEED_HIGH:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_HS);
		break;
	case USB_SPEED_FULL:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_FS);
		break;
	case USB_SPEED_LOW:
		slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_LS);
		break;
	default:
		/* Speed was set earlier, this shouldn't happen. */
		BUG();
	}

#if CONFIG_IS_ENABLED(DM_USB)
	/* Set up TT fields to support FS/LS devices */
	if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) {
		struct udevice *parent = udev->dev;

		dev = udev;
		do {
			port_num = dev->portnr;
			dev = dev_get_parent_priv(parent);
			if (usb_hub_is_root_hub(dev->dev))
				break;
			parent = dev->dev->parent;
		} while (dev->speed != USB_SPEED_HIGH);

		if (!usb_hub_is_root_hub(dev->dev)) {
			hub = dev_get_uclass_priv(dev->dev);
			if (hub->tt.multi)
				slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
			slot_ctx->tt_info |= cpu_to_le32(TT_PORT(port_num));
			slot_ctx->tt_info |= cpu_to_le32(TT_SLOT(dev->slot_id));
		}
	}
#endif

	port_num = hop_portnr;
	debug("port_num = %d\n", port_num);

	slot_ctx->dev_info2 |=
			cpu_to_le32(((port_num & ROOT_HUB_PORT_MASK) <<
				ROOT_HUB_PORT_SHIFT));

	/* Step 4 - ring already allocated */
	/* Step 5 */
	ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT);
	debug("SPEED = %d\n", speed);

	switch (speed) {
	case USB_SPEED_SUPER:
		ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) <<
					MAX_PACKET_SHIFT));
		debug("Setting Packet size = 512bytes\n");
		break;
	case USB_SPEED_HIGH:
	/* USB core guesses at a 64-byte max packet first for FS devices */
	case USB_SPEED_FULL:
		ep0_ctx->ep_info2 |= cpu_to_le32(((64 & MAX_PACKET_MASK) <<
					MAX_PACKET_SHIFT));
		debug("Setting Packet size = 64bytes\n");
		break;
	case USB_SPEED_LOW:
		ep0_ctx->ep_info2 |= cpu_to_le32(((8 & MAX_PACKET_MASK) <<
					MAX_PACKET_SHIFT));
		debug("Setting Packet size = 8bytes\n");
		break;
	default:
		/* New speed? */
		BUG();
	}

	/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
	ep0_ctx->ep_info2 |=
			cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
			((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));

	trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs;
	ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);

	/*
	 * xHCI spec 6.2.3:
	 * software shall set 'Average TRB Length' to 8 for control endpoints.
	 */
	ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(8));

	/* Steps 7 and 8 were done in xhci_alloc_virt_device() */

	xhci_flush_cache((uintptr_t)ep0_ctx, sizeof(struct xhci_ep_ctx));
	xhci_flush_cache((uintptr_t)slot_ctx, sizeof(struct xhci_slot_ctx));
}
int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat)
{
	struct usb_device *udev = dev_get_parent_priv(dev);

	return legacy_hub_port_reset(udev, port, portstat);
}
int usb_hub_scan(struct udevice *hub)
{
	struct usb_device *udev = dev_get_parent_priv(hub);

	return usb_hub_configure(udev);
}