X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/2d1fe1873a984d1c2c89ffa3d12949cafc718551..4aa23452e366790e6c50dea73c8bc5eea44e2f38:/hw/usb/hcd-ehci.c diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 22bdbf4a7d..a3ae9f260a 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -28,6 +28,7 @@ */ #include "hw/usb/hcd-ehci.h" +#include "trace.h" /* Capability Registers Base Address - section 2.2 */ #define CAPLENGTH 0x0000 /* 1-byte, 0x0001 reserved */ @@ -826,9 +827,9 @@ static void ehci_child_detach(USBPort *port, USBDevice *child) static void ehci_wakeup(USBPort *port) { EHCIState *s = port->opaque; - uint32_t portsc = s->portsc[port->index]; + uint32_t *portsc = &s->portsc[port->index]; - if (portsc & PORTSC_POWNER) { + if (*portsc & PORTSC_POWNER) { USBPort *companion = s->companion_ports[port->index]; if (companion->ops->wakeup) { companion->ops->wakeup(companion); @@ -836,6 +837,12 @@ static void ehci_wakeup(USBPort *port) return; } + if (*portsc & PORTSC_SUSPEND) { + trace_usb_ehci_port_wakeup(port->index); + *portsc |= PORTSC_FPRES; + ehci_raise_irq(s, USBSTS_PCD); + } + qemu_bh_schedule(s->async_bh); } @@ -1067,6 +1074,14 @@ static void ehci_port_write(void *ptr, hwaddr addr, } } + if ((val & PORTSC_SUSPEND) && !(*portsc & PORTSC_SUSPEND)) { + trace_usb_ehci_port_suspend(port); + } + if (!(val & PORTSC_FPRES) && (*portsc & PORTSC_FPRES)) { + trace_usb_ehci_port_resume(port); + val &= ~PORTSC_SUSPEND; + } + *portsc &= ~PORTSC_RO_MASK; *portsc |= val; trace_usb_ehci_portsc_change(addr + s->portscbase, addr >> 2, *portsc, old); @@ -2477,7 +2492,7 @@ const VMStateDescription vmstate_ehci = { .minimum_version_id = 1, .pre_save = usb_ehci_pre_save, .post_load = usb_ehci_post_load, - .fields = (VMStateField[]) { + .fields = (VMStateField[]) { /* mmio registers */ VMSTATE_UINT32(usbcmd, EHCIState), VMSTATE_UINT32(usbsts, EHCIState),