diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index 1ffa6f0b4..b75059b6a 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -66,6 +66,8 @@ #include "vmcfg.h" #include "tpm.h" #include "virtio.h" +#include "usb.h" +#include "xhci.h" #define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */ @@ -631,6 +633,7 @@ vm_suspend_resume(struct vmctx *ctx) vm_stop_watchdog(ctx); wait_for_resume(ctx); + wait_for_xhci_resume(); pm_backto_wakeup(ctx); vm_reset_watchdog(ctx); diff --git a/devicemodel/hw/pci/xhci.c b/devicemodel/hw/pci/xhci.c index 47e72bcf2..b1181d9b3 100644 --- a/devicemodel/hw/pci/xhci.c +++ b/devicemodel/hw/pci/xhci.c @@ -485,6 +485,24 @@ static struct pci_xhci_option_elem xhci_option_table[] = { {"cap", pci_xhci_parse_extcap} }; +void +wait_for_xhci_resume() +{ + /* The reason of waiting for resuming is USB virtualization + * needs do TWO PASS SEQUENTIAL enumerations: one for SOS and + * the other for UOS after SOS USB resuming work is completely + * done. So, theoretically, virtual USB resuming MUST use more + * time than its native counterpart. + */ + + /* FIXME: will substitute it by dynamic way. The thought is + * waiting time is calculated by the number of USB devices + * attached. More devices, more waiting time, no device no + * waiting. + */ + sleep(5); +} + static int pci_xhci_get_free_vport(struct pci_xhci_vdev *xdev, struct usb_native_devinfo *di) diff --git a/devicemodel/include/xhci.h b/devicemodel/include/xhci.h index 65ee07a42..724724851 100755 --- a/devicemodel/include/xhci.h +++ b/devicemodel/include/xhci.h @@ -377,4 +377,6 @@ struct xhci_event_ring_seg { volatile uint32_t dwEvrsReserved; }; +void wait_for_xhci_resume(); + #endif /* _XHCI_H_ */