From e9211514e706c32668816fd52829ec06d9c2881e Mon Sep 17 00:00:00 2001 From: Xiaoguang Wu Date: Wed, 11 Sep 2019 00:07:37 +0800 Subject: [PATCH] DM USB: modify disconnecting logic to support Windows 10 The Windows 10 feeds back quicker than Linux OS when error occured due to device disconnecting, it will quickly reset the xHCI controller before the DM starts to emulate disconnect event and it may cause some unexpected errors such as crash. This patch will do one more check when error happens, if the error is induced by device disconnecting, the DM will not report error and just wait until the disconnect event is reported to the guest. This change could produce the correct hehavior as we expected. Tracked-On: #3628 Signed-off-by: Xiaoguang Wu Acked-by: Yu Wang --- devicemodel/hw/platform/usb_pmapper.c | 8 ++++++++ devicemodel/hw/usb_core.c | 14 ++++++++++++++ devicemodel/include/usb_core.h | 1 + 3 files changed, 23 insertions(+) diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index 2b60c7b74..a3a00883f 100644 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -214,6 +214,14 @@ usb_dev_comp_cb(struct libusb_transfer *trn) xfer->status = USB_ERR_SHORT_XFER; goto out; case LIBUSB_TRANSFER_ERROR: + /* + * If this error happened due to device disconnecting, there is + * nothing should do and just wait usb_dev_native_sys_disconn_cb + * to do the 'unplugging process'. + */ + if (usb_native_is_device_existed(&info->path) == 0) + goto cancel_out; + is_stalled = 1; xfer->status = USB_ERR_STALLED; goto stall_out; diff --git a/devicemodel/hw/usb_core.c b/devicemodel/hw/usb_core.c index e49c9d201..963017bb4 100644 --- a/devicemodel/hw/usb_core.c +++ b/devicemodel/hw/usb_core.c @@ -181,6 +181,20 @@ usb_native_is_port_existed(uint8_t bus_num, uint8_t port_num) return 1; } +int +usb_native_is_device_existed(struct usb_devpath *path) +{ + char _path[128]; + int ret = 0; + + if (path) { + snprintf(_path, sizeof(_path), "%s/%s", NATIVE_USBSYS_DEVDIR, + usb_dev_path(path)); + ret = (access(_path, F_OK) == 0); + } + return ret; +} + void usb_parse_log_level(char level) { switch (level) { diff --git a/devicemodel/include/usb_core.h b/devicemodel/include/usb_core.h index 2ebda3e6b..52cef5655 100644 --- a/devicemodel/include/usb_core.h +++ b/devicemodel/include/usb_core.h @@ -247,6 +247,7 @@ void usb_parse_log_level(char level); struct usb_devemu *usb_emu_finddev(char *name); int usb_native_is_bus_existed(uint8_t bus_num); int usb_native_is_port_existed(uint8_t bus_num, uint8_t port_num); +int usb_native_is_device_existed(struct usb_devpath *path); struct usb_block *usb_block_append(struct usb_xfer *xfer, void *buf, int blen, void *hcb, int hcb_len); int usb_get_hub_port_num(struct usb_devpath *path);