usb: emul: hub: Report the actual device speed of the emulation device
At present the usb hub emulator always reports its downstream port
speed as full speed. Actually it is high speed for sandbox-flash,
and low speed for sandbox-keyb. We can determine the device speed
by checking its device descriptor bcdUSB field, and do the proper
hub port status report based on that.
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
index 8ed7a0f..9a0f47b 100644
--- a/drivers/usb/emul/sandbox_hub.c
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -121,9 +121,12 @@
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 @@
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 @@
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 @@
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) {