diff options
Diffstat (limited to 'drivers/usb/emul/usb-emul-uclass.c')
-rw-r--r-- | drivers/usb/emul/usb-emul-uclass.c | 59 |
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), }; |