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:
parent
8e28812768
commit
dc007f395f
|
|
@ -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…
Reference in New Issue