summaryrefslogtreecommitdiff
path: root/drivers/usb/emul/sandbox_hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/emul/sandbox_hub.c')
-rw-r--r--drivers/usb/emul/sandbox_hub.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index 1432858fd5..9a0f47b81c 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -121,9 +121,12 @@ struct sandbox_hub_priv {
int change[SANDBOX_NUM_PORTS];
};
-static struct udevice *hub_find_device(struct udevice *hub, int port)
+static struct udevice *hub_find_device(struct udevice *hub, int port,
+ enum usb_device_speed *speed)
{
struct udevice *dev;
+ struct usb_generic_descriptor **gen_desc;
+ struct usb_device_descriptor **dev_desc;
for (device_find_first_child(hub, &dev);
dev;
@@ -131,8 +134,27 @@ static struct udevice *hub_find_device(struct udevice *hub, int port)
struct sandbox_hub_platdata *plat;
plat = dev_get_parent_platdata(dev);
- if (plat->port == port)
+ if (plat->port == port) {
+ gen_desc = plat->plat.desc_list;
+ gen_desc = usb_emul_find_descriptor(gen_desc,
+ USB_DT_DEVICE, 0);
+ dev_desc = (struct usb_device_descriptor **)gen_desc;
+
+ switch (le16_to_cpu((*dev_desc)->bcdUSB)) {
+ case 0x0100:
+ *speed = USB_SPEED_LOW;
+ break;
+ case 0x0101:
+ *speed = USB_SPEED_FULL;
+ break;
+ case 0x0200:
+ default:
+ *speed = USB_SPEED_HIGH;
+ break;
+ }
+
return dev;
+ }
}
return NULL;
@@ -146,7 +168,8 @@ static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
int ret = 0;
if ((clear | set) & USB_PORT_STAT_POWER) {
- struct udevice *dev = hub_find_device(hub, port);
+ enum usb_device_speed speed;
+ struct udevice *dev = hub_find_device(hub, port, &speed);
if (dev) {
if (set & USB_PORT_STAT_POWER) {
@@ -156,6 +179,10 @@ static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
if (!ret) {
set |= USB_PORT_STAT_CONNECTION |
USB_PORT_STAT_ENABLE;
+ if (speed == USB_SPEED_LOW)
+ set |= USB_PORT_STAT_LOW_SPEED;
+ else if (speed == USB_SPEED_HIGH)
+ set |= USB_PORT_STAT_HIGH_SPEED;
}
} else if (clear & USB_PORT_STAT_POWER) {
@@ -274,15 +301,16 @@ static int sandbox_hub_submit_control_msg(struct udevice *bus,
static int sandbox_hub_bind(struct udevice *dev)
{
- return usb_emul_setup_device(dev, PACKET_SIZE_64, hub_strings,
- hub_desc_list);
+ return usb_emul_setup_device(dev, hub_strings, hub_desc_list);
}
static int sandbox_child_post_bind(struct udevice *dev)
{
struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
+ struct usb_emul_platdata *emul = dev_get_uclass_platdata(dev);
plat->port = dev_read_u32_default(dev, "reg", -1);
+ emul->port1 = plat->port + 1;
return 0;
}