mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-06-08 01:54:44 +00:00
DM USB: xHCI: enable Flat Mode Hub emulation support.
Flat Mode for hub emulation means DM emulates USB devices under hub but hide hub itself. Under this design the Guest OS cannot see any emulated hub. So in the perspective of Guest OS, all the emulated devices are under root hub. This patch is used to enable feature as mentioned above. And please NOTE, it is the initial version of hub flat Mode hub emulation, there are one limitation: only one physical hub is supported. If second physical hub is connected, the connect and disconnect behavior in second hub may affect the function of first emulated hub. The USB HUB device model should be the final long term solution, but it is very complex. Use flat mode HUB emulation as the short term solution first to support some USB touch devices which integrated internal HUB. Signed-off-by: Liang Yang <liang3.yang@intel.com> Reviewed-by: Xiaoguang Wu <xiaoguang.wu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com> Tracked-On: #1243
This commit is contained in:
@@ -855,6 +855,65 @@ out:
|
||||
return xfer->status;
|
||||
}
|
||||
|
||||
int
|
||||
usb_dev_is_hub(void *pdata)
|
||||
{
|
||||
struct libusb_device *ldev;
|
||||
struct libusb_device_descriptor desc;
|
||||
int rc;
|
||||
|
||||
assert(pdata);
|
||||
|
||||
ldev = pdata;
|
||||
rc = libusb_get_device_descriptor(ldev, &desc);
|
||||
|
||||
if (rc)
|
||||
return USB_TYPE_INVALID;
|
||||
|
||||
if (desc.bDeviceClass == LIBUSB_CLASS_HUB)
|
||||
return USB_HUB;
|
||||
else
|
||||
return USB_DEV;
|
||||
|
||||
}
|
||||
|
||||
enum usb_native_dev_type
|
||||
usb_get_parent_dev_type(void *pdata, uint16_t *bus, uint16_t *port)
|
||||
{
|
||||
struct libusb_device *ldev;
|
||||
struct libusb_device *libdev;
|
||||
struct libusb_device_descriptor desc;
|
||||
int rc;
|
||||
|
||||
assert(pdata);
|
||||
assert(bus);
|
||||
assert(port);
|
||||
|
||||
ldev = pdata;
|
||||
libdev = libusb_get_parent(ldev);
|
||||
|
||||
if (libdev == NULL) {
|
||||
UPRINTF(LWRN, "libusb_get_parent return NULL\r\n");
|
||||
return USB_TYPE_INVALID;
|
||||
}
|
||||
|
||||
*bus = libusb_get_bus_number(libdev);
|
||||
*port = libusb_get_port_number(libdev);
|
||||
|
||||
rc = libusb_get_device_descriptor(libdev, &desc);
|
||||
if (rc) {
|
||||
UPRINTF(LWRN, "libusb_get_device_descriptor error %d\r\n", rc);
|
||||
return USB_TYPE_INVALID;
|
||||
}
|
||||
|
||||
if (*port == 0)
|
||||
return ROOT_HUB;
|
||||
if (desc.bDeviceClass == LIBUSB_CLASS_HUB)
|
||||
return USB_HUB;
|
||||
|
||||
return USB_TYPE_INVALID;
|
||||
}
|
||||
|
||||
void *
|
||||
usb_dev_init(void *pdata, char *opt)
|
||||
{
|
||||
@@ -1039,6 +1098,9 @@ usb_dev_native_sys_disconn_cb(struct libusb_context *ctx, struct libusb_device
|
||||
*ldev, libusb_hotplug_event event, void *pdata)
|
||||
{
|
||||
uint8_t port;
|
||||
uint16_t pport;
|
||||
uint16_t pbus;
|
||||
int rc;
|
||||
|
||||
UPRINTF(LDBG, "disconnect event\r\n");
|
||||
|
||||
@@ -1048,6 +1110,13 @@ usb_dev_native_sys_disconn_cb(struct libusb_context *ctx, struct libusb_device
|
||||
}
|
||||
|
||||
port = libusb_get_port_number(ldev);
|
||||
rc = usb_get_parent_dev_type(ldev, &pbus, &pport);
|
||||
if (rc == USB_TYPE_INVALID) {
|
||||
UPRINTF(LWRN, "usb_get_parent_dev_type return %d\r\n", rc);
|
||||
return 0;
|
||||
} else if (rc == USB_HUB)
|
||||
port += PORT_HUB_BASE;
|
||||
|
||||
if (g_ctx.disconn_cb)
|
||||
g_ctx.disconn_cb(g_ctx.hci_data, &port);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user