From 7c79f507526e173a8dd5dbe42dd5ec87ec410512 Mon Sep 17 00:00:00 2001 From: Xiaoguang Wu Date: Thu, 28 Feb 2019 15:50:27 +0800 Subject: [PATCH] DM USB: xHCI: workaround for libusb timing issue On some platforms, the VBus will drop after suspending is done, hence a disconnect and re-connect for device connected before suspending will be triggered in DM. But during the stress test, when the free memory is limited to very low level, and put huge workload to SOS, under certain possibility, the DM will receive re-connect event first and disconnect event later, this behavior will result of failing to emulate USB device to UOS. The reason is due to a timing issue from libusb. Before we could upstream fixing patch to libusb or find some other better solution, this workaround patch will be used to avoid errors happen. Tracked-On: #2823 Signed-off-by: Xiaoguang Wu Acked-by: Yu Wang --- devicemodel/hw/pci/xhci.c | 30 +++++++++++++-------------- devicemodel/hw/platform/usb_pmapper.c | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index ae478e31b..d1260e600 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -958,21 +958,6 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data) state = xdev->native_ports[index].state; vport = xdev->native_ports[index].vport; - if (state == VPORT_CONNECTED && vport > 0) { - /* - * When this place is reached, it means the physical - * USB device is disconnected before the emulation - * procedure is started. The related states should be - * cleared for future connecting. - */ - UPRINTF(LFTL, "disconnect VPORT_CONNECTED device: " - "%d-%s vport %d\r\n", di->path.bus, - usb_dev_path(&di->path), vport); - pci_xhci_disconnect_port(xdev, vport, 0); - xdev->native_ports[index].state = VPORT_ASSIGNED; - return 0; - } - edev = xdev->devices[vport]; for (slot = 1; slot < XHCI_MAX_SLOTS; ++slot) if (xdev->slots[slot] == edev) @@ -996,6 +981,21 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data) } } + if (state == VPORT_CONNECTED && vport > 0) { + /* + * When this place is reached, it means the physical + * USB device is disconnected before the emulation + * procedure is started. The related states should be + * cleared for future connecting. + */ + UPRINTF(LFTL, "disconnect VPORT_CONNECTED device: " + "%d-%s vport %d\r\n", di->path.bus, + usb_dev_path(&di->path), vport); + pci_xhci_disconnect_port(xdev, vport, 0); + xdev->native_ports[index].state = VPORT_ASSIGNED; + return 0; + } + assert(state == VPORT_EMULATED || state == VPORT_CONNECTED); xdev->native_ports[index].state = VPORT_ASSIGNED; xdev->native_ports[index].vport = 0; diff --git a/devicemodel/hw/platform/usb_pmapper.c b/devicemodel/hw/platform/usb_pmapper.c index 630130260..9ea7cb02c 100755 --- a/devicemodel/hw/platform/usb_pmapper.c +++ b/devicemodel/hw/platform/usb_pmapper.c @@ -597,7 +597,7 @@ usb_dev_native_toggle_if_drivers(struct usb_dev *udev, int attach) return -1; } - UPRINTF(LDBG, "%s driver\r\n", attach == 1 ? "attach" : "detach"); + UPRINTF(LINF, "%s driver\r\n", attach == 1 ? "attach" : "detach"); c = config->bConfigurationValue; for (i = 0; i < config->bNumInterfaces; i++) {