Skip to content

Commit ba68bd4

Browse files
xiaoguangwuNanlinXie
authored andcommitted
DM USB: xHCI: fix enumeration error after rebooting
When the physical USB device is disconnected before DM's emulation is ready, the virtual connection state is not cleared properly. This will cause the DM refuse to do emulation for future physical connection. This patch clears those states mentioned above and hence fix the 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: #1367
1 parent 4544d28 commit ba68bd4

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

devicemodel/hw/pci/xhci.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
631631
struct usb_native_devinfo di;
632632
struct usb_dev *udev;
633633
uint8_t port, slot;
634-
uint8_t status;
634+
uint16_t status;
635635
int need_intr = 1;
636636

637637
assert(hci_data);
@@ -646,8 +646,8 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
646646
return -1;
647647
}
648648

649-
status = VPORT_STATE(xdev->port_map_tbl[di.bus][di.port]);
650-
if (status == VPORT_HUB_CONNECTED) {
649+
status = xdev->port_map_tbl[di.bus][di.port];
650+
if (VPORT_STATE(status) == VPORT_HUB_CONNECTED) {
651651
xdev->port_map_tbl[di.bus][di.port] =
652652
VPORT_NUM_STATE(VPORT_ASSIGNED, 0);
653653
return 0;
@@ -679,7 +679,23 @@ pci_xhci_native_usb_dev_disconn_cb(void *hci_data, void *dev_data)
679679
}
680680
}
681681

682-
if (port == XHCI_MAX_DEVS + 1) {
682+
if (port > XHCI_MAX_DEVS) {
683+
if (VPORT_STATE(status) == VPORT_CONNECTED &&
684+
VPORT_NUM(status) > 0) {
685+
/*
686+
* When this place is reached, it means the physical
687+
* USB device is disconnected before the emulation
688+
* procedure is started. The related states should be
689+
* cleared for future connecting.
690+
*/
691+
UPRINTF(LFTL, "disconnect VPORT_CONNECTED device: "
692+
"%d-%d vport %d\r\n", di.bus, di.port,
693+
VPORT_NUM(status));
694+
pci_xhci_disconnect_port(xdev, VPORT_NUM(status), 0);
695+
xdev->port_map_tbl[di.bus][di.port] = VPORT_NUM_STATE(
696+
VPORT_ASSIGNED, 0);
697+
}
698+
683699
UPRINTF(LFTL, "fail to find physical port %d\r\n", di.port);
684700
return -1;
685701
}

0 commit comments

Comments
 (0)