summaryrefslogtreecommitdiff
path: root/drivers/usb/emul/usb-emul-uclass.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/emul/usb-emul-uclass.c')
-rw-r--r--drivers/usb/emul/usb-emul-uclass.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c
index 6e03c1e0d9e..fbe11f31353 100644
--- a/drivers/usb/emul/usb-emul-uclass.c
+++ b/drivers/usb/emul/usb-emul-uclass.c
@@ -52,7 +52,7 @@ static int usb_emul_get_string(struct usb_string *strings, int index,
return -EINVAL;
}
-static struct usb_generic_descriptor **find_descriptor(
+struct usb_generic_descriptor **usb_emul_find_descriptor(
struct usb_generic_descriptor **ptr, int type, int index)
{
debug("%s: type=%x, index=%d\n", __func__, type, index);
@@ -91,8 +91,7 @@ static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
length);
}
- ptr = find_descriptor((struct usb_generic_descriptor **)plat->desc_list,
- type, index);
+ ptr = usb_emul_find_descriptor(plat->desc_list, type, index);
if (!ptr) {
debug("%s: Could not find descriptor type %d, index %d\n",
__func__, type, index);
@@ -107,7 +106,7 @@ static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
return upto ? upto : length ? -EIO : 0;
}
-static int usb_emul_find_devnum(int devnum, struct udevice **emulp)
+static int usb_emul_find_devnum(int devnum, int port1, struct udevice **emulp)
{
struct udevice *dev;
struct uclass *uc;
@@ -120,7 +119,37 @@ static int usb_emul_find_devnum(int devnum, struct udevice **emulp)
uclass_foreach_dev(dev, uc) {
struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
- if (udev->devnum == devnum) {
+ /*
+ * devnum is initialzied to zero at the beginning of the
+ * enumeration process in usb_setup_device(). At this
+ * point, udev->devnum has not been assigned to any valid
+ * USB address either, so we can't rely on the comparison
+ * result between udev->devnum and devnum to select an
+ * emulator device.
+ */
+ if (!devnum) {
+ struct usb_emul_platdata *plat;
+
+ /*
+ * If the parent is sandbox USB controller, we are
+ * the root hub. And there is only one root hub
+ * in the system.
+ */
+ if (device_get_uclass_id(dev->parent) == UCLASS_USB) {
+ debug("%s: Found emulator '%s'\n",
+ __func__, dev->name);
+ *emulp = dev;
+ return 0;
+ }
+
+ plat = dev_get_uclass_platdata(dev);
+ if (plat->port1 == port1) {
+ debug("%s: Found emulator '%s', port %d\n",
+ __func__, dev->name, port1);
+ *emulp = dev;
+ return 0;
+ }
+ } else if (udev->devnum == devnum) {
debug("%s: Found emulator '%s', addr %d\n", __func__,
dev->name, udev->devnum);
*emulp = dev;
@@ -132,18 +161,19 @@ static int usb_emul_find_devnum(int devnum, struct udevice **emulp)
return -ENOENT;
}
-int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp)
+int usb_emul_find(struct udevice *bus, ulong pipe, int port1,
+ struct udevice **emulp)
{
int devnum = usb_pipedevice(pipe);
- return usb_emul_find_devnum(devnum, emulp);
+ return usb_emul_find_devnum(devnum, port1, emulp);
}
int usb_emul_find_for_dev(struct udevice *dev, struct udevice **emulp)
{
struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
- return usb_emul_find_devnum(udev->devnum, emulp);
+ return usb_emul_find_devnum(udev->devnum, 0, emulp);
}
int usb_emul_control(struct udevice *emul, struct usb_device *udev,
@@ -229,8 +259,8 @@ int usb_emul_int(struct udevice *emul, struct usb_device *udev,
return ops->interrupt(emul, udev, pipe, buffer, length, interval);
}
-int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
- struct usb_string *strings, void **desc_list)
+int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings,
+ void **desc_list)
{
struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
struct usb_generic_descriptor **ptr;
@@ -264,18 +294,11 @@ int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
return 0;
}
-void usb_emul_reset(struct udevice *dev)
-{
- struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
-
- plat->devnum = 0;
- plat->configno = 0;
-}
-
UCLASS_DRIVER(usb_emul) = {
.id = UCLASS_USB_EMUL,
.name = "usb_emul",
.post_bind = dm_scan_fdt_dev,
+ .per_device_platdata_auto_alloc_size = sizeof(struct usb_emul_platdata),
.per_child_auto_alloc_size = sizeof(struct usb_device),
.per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
};