summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-10-18 14:16:58 +0200
committerHans de Goede <hdegoede@redhat.com>2013-11-21 17:18:42 +0100
commit098210fbb47f896c408d3e15a3dd12404821f03f (patch)
tree978a50f9097819ceba082b390d1e7f1b0459ea75
parent418c8b8ec7d7597114907701ae0906f22fdd5b1b (diff)
xhci: Add a few missing checks for disconnected devices
One of the reworks of qemu's usb core made changes to usb-port's disconnect handling. Now ports with a device will always have a non 0 dev member, but if the device is not attached (which is possible with usb redirection), dev->attached will be 0. So supplement all checks for dev to also check dev->attached, and add an extra check in a path where a device check was completely missing. This fixes various crashes (asserts triggering) I've been seeing when xhci attached usb devices get disconnected at the wrong time. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--hw/usb/hcd-xhci.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 93683481a..bafe08590 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1600,7 +1600,8 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
}
if (!xhci->slots[slotid-1].uport ||
- !xhci->slots[slotid-1].uport->dev) {
+ !xhci->slots[slotid-1].uport->dev ||
+ !xhci->slots[slotid-1].uport->dev->attached) {
return CC_USB_TRANSACTION_ERROR;
}
@@ -2087,6 +2088,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
return;
}
+ /* If the device has been detached, but the guest has not noticed this
+ yet the 2 above checks will succeed, but we must NOT continue */
+ if (!xhci->slots[slotid - 1].uport ||
+ !xhci->slots[slotid - 1].uport->dev ||
+ !xhci->slots[slotid - 1].uport->dev->attached) {
+ return;
+ }
+
if (epctx->retry) {
XHCITransfer *xfer = epctx->retry;
@@ -2311,7 +2320,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
trace_usb_xhci_slot_address(slotid, uport->path);
dev = uport->dev;
- if (!dev) {
+ if (!dev || !dev->attached) {
fprintf(stderr, "xhci: port %s not connected\n", uport->path);
return CC_USB_TRANSACTION_ERROR;
}