diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-01-14 10:27:29 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-01-14 10:27:29 -0600 |
commit | b55160c3d9b38c5d481ceccc30e397430f26fe92 (patch) | |
tree | 4f294ebabe09855bb98fa72fff1957ac4215d7f9 | |
parent | 167eb811d006b95e9a26d4a0e681907ae77f5ce4 (diff) | |
parent | 036078475427f2562c8e505f6bb44dbf5d8cbd95 (diff) |
Merge remote-tracking branch 'kraxel/usb.76' into staging
* kraxel/usb.76:
usb-host: Initialize dev->port the obviously safe way
usb-host: Drop superfluous null test from usb_host_auto_scan()
ehci: Assert state machine is sane w.r.t. EHCIQueue
xhci: nuke transfe5rs on detach
xhci: call xhci_detach_slot on root port detach too
xhci: create xhci_detach_slot helper function
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r-- | hw/usb/hcd-ehci.c | 4 | ||||
-rw-r--r-- | hw/usb/hcd-xhci.c | 31 | ||||
-rw-r--r-- | hw/usb/host-linux.c | 4 |
3 files changed, 31 insertions, 8 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 320b7e7239..70406592ef 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2092,18 +2092,22 @@ static void ehci_advance_state(EHCIState *ehci, int async) break; case EST_ADVANCEQUEUE: + assert(q != NULL); again = ehci_state_advqueue(q); break; case EST_FETCHQTD: + assert(q != NULL); again = ehci_state_fetchqtd(q); break; case EST_HORIZONTALQH: + assert(q != NULL); again = ehci_state_horizqh(q); break; case EST_EXECUTE: + assert(q != NULL); again = ehci_state_execute(q); if (async) { ehci->async_stepdown = 0; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 92f2eee3bc..5fb0c488e8 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1197,6 +1197,7 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid, ep = epctx->transfers[xferi].packet.ep; } killed += xhci_ep_nuke_one_xfer(&epctx->transfers[xferi]); + epctx->transfers[xferi].packet.ep = NULL; xferi = (xferi + 1) % TD_QUEUE; } if (ep) { @@ -2198,6 +2199,28 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr return slotid; } +/* cleanup slot state on usb device detach */ +static void xhci_detach_slot(XHCIState *xhci, USBPort *uport) +{ + int slot, ep; + + for (slot = 0; slot < xhci->numslots; slot++) { + if (xhci->slots[slot].uport == uport) { + break; + } + } + if (slot == xhci->numslots) { + return; + } + + for (ep = 0; ep < 31; ep++) { + if (xhci->slots[slot].eps[ep]) { + xhci_ep_nuke_xfers(xhci, slot+1, ep+1); + } + } + xhci->slots[slot].uport = NULL; +} + static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx) { dma_addr_t ctx; @@ -2940,6 +2963,7 @@ static void xhci_detach(USBPort *usbport) XHCIState *xhci = usbport->opaque; XHCIPort *port = xhci_lookup_port(xhci, usbport); + xhci_detach_slot(xhci, usbport); xhci_port_update(port, 1); } @@ -2971,13 +2995,8 @@ static void xhci_child_detach(USBPort *uport, USBDevice *child) { USBBus *bus = usb_bus_from_device(child); XHCIState *xhci = container_of(bus, XHCIState, bus); - int i; - for (i = 0; i < xhci->numslots; i++) { - if (xhci->slots[i].uport == uport) { - xhci->slots[i].uport = NULL; - } - } + xhci_detach_slot(xhci, uport); } static USBPortOps xhci_uport_ops = { diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c index e8e6a42fb9..ad75ce0702 100644 --- a/hw/usb/host-linux.c +++ b/hw/usb/host-linux.c @@ -1314,7 +1314,7 @@ static int usb_host_open(USBHostDevice *dev, int bus_num, dev->bus_num = bus_num; dev->addr = addr; - strcpy(dev->port, port); + pstrcpy(dev->port, sizeof(dev->port), port); dev->fd = fd; /* read the device description */ @@ -1760,7 +1760,7 @@ static int usb_host_auto_scan(void *opaque, int bus_num, if (f->addr > 0 && f->addr != addr) { continue; } - if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) { + if (f->port != NULL && strcmp(f->port, port) != 0) { continue; } |