diff mbox

[4/9] xhci: Add a few missing checks for disconnected devices

Message ID 1384868224-15389-5-git-send-email-hdegoede@redhat.com
State New
Headers show

Commit Message

Hans de Goede Nov. 19, 2013, 1:36 p.m. UTC
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>
---
 hw/usb/hcd-xhci.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 9368348..bafe085 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;
     }