DM USB: xHCI: enable 'cold plug' mode

USB device is connected before UOS is booted up, this scenario is
called 'cold plug' for easy to refer.

Under 'cold plug' situation, the libusb will not report 'connect'
event to device model, hence UOS will not discover 'cold plugged'
device.

This patch add support to fix this issue.

Signed-off-by: Xiaoguang Wu <xiaoguang.wu@intel.com>
Reviewed-by: Liang Yang <liang3.yang@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
Tracked-On: #1242
This commit is contained in:
Xiaoguang Wu
2018-09-10 22:01:43 +08:00
committed by lijinxia
parent 612037e138
commit b4755cdc52
2 changed files with 146 additions and 22 deletions

View File

@@ -21,6 +21,85 @@ static struct usb_dev_sys_ctx_info g_ctx;
static inline uint8_t usb_dev_get_ep_type(struct usb_dev *udev, int pid,
int epnum);
static int
usb_dev_scan_dev()
{
int i, num_devs;
struct libusb_device **devlist;
struct libusb_device *ldev;
struct usb_native_devinfo di;
struct libusb_device_descriptor d;
int rc;
if (!g_ctx.libusb_ctx)
return -1;
num_devs = libusb_get_device_list(g_ctx.libusb_ctx, &devlist);
if (num_devs < 0)
return -1;
for (i = 0; i < num_devs; ++i) {
ldev = devlist[i];
memset(&di, 0, sizeof(di));
di.bus = libusb_get_bus_number(ldev);
di.port = libusb_get_port_number(ldev);
di.speed = libusb_get_device_speed(ldev);
rc = libusb_get_device_descriptor(ldev, &d);
if (rc) {
UPRINTF(LWRN, "fail to get descriptor for %d-%d\r\n",
di.bus, di.port);
continue;
}
di.pid = d.idProduct;
di.vid = d.idVendor;
di.bcd = d.bcdUSB;
di.priv_data = ldev;
if (di.port == 0)
continue;
if (d.bDeviceClass != LIBUSB_CLASS_HUB)
continue;
if (g_ctx.conn_cb)
g_ctx.conn_cb(g_ctx.hci_data, &di);
}
for (i = 0; i < num_devs; ++i) {
ldev = devlist[i];
memset(&di, 0, sizeof(di));
di.bus = libusb_get_bus_number(ldev);
di.port = libusb_get_port_number(ldev);
di.speed = libusb_get_device_speed(ldev);
rc = libusb_get_device_descriptor(ldev, &d);
if (rc) {
UPRINTF(LWRN, "fail to get descriptor for %d-%d\r\n",
di.bus, di.port);
continue;
}
di.pid = d.idProduct;
di.vid = d.idVendor;
di.bcd = d.bcdUSB;
di.priv_data = ldev;
if (di.port == 0)
continue;
if (d.bDeviceClass == LIBUSB_CLASS_HUB)
continue;
if (g_ctx.conn_cb)
g_ctx.conn_cb(g_ctx.hci_data, &di);
}
return num_devs;
}
static int
libusb_speed_to_usb_speed(int libusb_speed)
{
@@ -1134,6 +1213,7 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
libusb_hotplug_callback_handle native_conn_handle;
libusb_hotplug_callback_handle native_disconn_handle;
int native_pid, native_vid, native_cls, rc;
int num_devs;
assert(conn_cb);
assert(disconn_cb);
@@ -1155,6 +1235,10 @@ usb_dev_sys_init(usb_dev_sys_cb conn_cb, usb_dev_sys_cb disconn_cb,
g_ctx.disconn_cb = disconn_cb;
g_ctx.notify_cb = notify_cb;
g_ctx.intr_cb = intr_cb;
num_devs = usb_dev_scan_dev();
UPRINTF(LINF, "found %d devices before Guest OS booted\r\n", num_devs);
native_conn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
native_disconn_evt = LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
native_pid = LIBUSB_HOTPLUG_MATCH_ANY;