diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-01-20 17:09:58 +0100 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2012-02-10 12:16:31 +0100 |
commit | 8c735e431d384663137a709c8207f4ada3146205 (patch) | |
tree | 86e18e661ecbb5130834705f45257cafe914cf84 /hw | |
parent | b819d7169a8f026c7b9174b7cbce8ab50fc7908a (diff) |
xhci: remote wakeup support
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/usb-xhci.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c index 65214af9c4..3026edbcdd 100644 --- a/hw/usb-xhci.c +++ b/hw/usb-xhci.c @@ -2698,6 +2698,26 @@ static void xhci_detach(USBPort *usbport) xhci_update_port(xhci, port, 1); } +static void xhci_wakeup(USBPort *usbport) +{ + XHCIState *xhci = usbport->opaque; + XHCIPort *port = &xhci->ports[usbport->index]; + int nr = port->port.index + 1; + XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS, nr << 24}; + uint32_t pls; + + pls = (port->portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK; + if (pls != 3) { + return; + } + port->portsc |= 0xf << PORTSC_PLS_SHIFT; + if (port->portsc & PORTSC_PLC) { + return; + } + port->portsc |= PORTSC_PLC; + xhci_event(xhci, &ev); +} + static void xhci_complete(USBPort *port, USBPacket *packet) { XHCITransfer *xfer = container_of(packet, XHCITransfer, packet); @@ -2714,6 +2734,7 @@ static void xhci_child_detach(USBPort *port, USBDevice *child) static USBPortOps xhci_port_ops = { .attach = xhci_attach, .detach = xhci_detach, + .wakeup = xhci_wakeup, .complete = xhci_complete, .child_detach = xhci_child_detach, }; |