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>
master
Bin Meng 7 years ago committed by Marek Vasut
parent 848436a48d
commit d7771f0c5c
  1. 33
      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) {

Loading…
Cancel
Save