Signed-off-by: Gonglei <arei.gong...@huawei.com> --- hw/usb/hcd-uhci.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 0820244..fe0ad81 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -680,6 +680,12 @@ static void uhci_wakeup(USBPort *port1) { UHCIState *s = port1->opaque; UHCIPort *port = &s->ports[port1->index]; + uint8_t *pci_conf = s->dev.config; + + /* Do not resume UHCI when UHCI PIRQ was disabled */ + if (pci_conf[0xc1] == 0x00 && pci_conf[0xc0] == 0x00) { + return; + } if (port->ctrl & UHCI_PORT_SUSPEND && !(port->ctrl & UHCI_PORT_RD)) { port->ctrl |= UHCI_PORT_RD; @@ -1241,6 +1247,10 @@ static int usb_uhci_common_initfn(PCIDevice *dev) /* TODO: reset value should be 0. */ pci_conf[USB_SBRN] = USB_RELEASE_1; // release number + /* LEGACY SUPPORT REGISTER - UHCI11D 5.2.1 */ + pci_conf[0xc0] |= 0x00; + pci_conf[0xc1] |= 0x20; /* Enable USB PIRQ */ + pci_config_set_interrupt_pin(pci_conf, u->info.irq_pin + 1); if (s->masterbus) { -- 1.7.12.4 > -----Original Message----- > From: Gonglei (Arei) > Sent: Tuesday, May 13, 2014 5:05 PM > To: qemu-devel@nongnu.org > Cc: 'Gerd Hoffmann'; Huangweidong (C); 'Michael S. Tsirkin' > Subject: usb: usb tablet freeze when save/restore guest os > > Hi, > > For recent Linux guests, the usb tablet will be suspended when it is idle. > When Qemu detect the usb tablet event, will call uhci_wakeup(), which > according the value of port->ctrl to decide to call uhci_resume() or not. > UHCI_PORT_RD bit is set to 1 for UHCI is resuming, and qemu will not call > uhci_resume(). The other way round, qemu will call uhci_resume() and then > post a interrupt to guest os, meanwhile set UHCI_PORT_RD bit to 1. > > In the guests, after handle the interrupt, will call uhci_finish_suspend(), > which > clear UHCI_PORT_RD bit, Then qemu will know that the UHCI resume > process has finished. > > In the situation of save/restore guest os, when the guest os is saving > memory iteratively, meanwhile the usb tablet work normally (by vnc). When > qemu > has set the UHCI_PORT_RD bit to 1, and post a interrupt to guest os, but > guest os has hibernated this moment, so the interrupt cannot be handled > in time. So, the UHCI_PORT_RD bit will not be cleared by > uhci_finish_suspend(). > > When we restore the guest os, and the usb tablet event happen again, but > because of UHCI_PORT_RD bit being set to 1, qemu consider the guest os is > handling the interrupt of resuming UHCI, so will not post another interrupt. > For guest os, will not handle UHCI event because it not receive an interrupt, > which cause usb tablet freeze. > > So, we should provide a mechanism for avoiding losing interrupt of UHCI. > IMHO the LEGACY SUPPORT REGISTER will give us some help, and I have > finished a patch and tested it work well. > > Anything idea? Thanks! > > > Best regards, > -Gonglei >