UPSTREAM: 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.

Change-Id: I1b0848d856fb0e3351bfb5c678cc387d5bb5ca9f
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
(cherry picked from commit d7771f0c5cd429286c7555360d779d21568e3ba0)
This commit is contained in:
Bin Meng 2017-10-01 06:19:41 -07:00 committed by Frank Wang
parent 8e28812768
commit dc007f395f
1 changed files with 30 additions and 3 deletions

View File

@ -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) {