Blame 0027-usb-redir-Device-disconnect-re-connect-robustness-fi.patch

Justin M. Forbes fc5c27
>From a6fba82709859fc91e676ce53079eb250bb55750 Mon Sep 17 00:00:00 2001
Justin M. Forbes fc5c27
From: Hans de Goede <hdegoede@redhat.com>
Justin M. Forbes fc5c27
Date: Thu, 4 Aug 2011 14:41:07 +0200
Justin M. Forbes fc5c27
Subject: [PATCH 27/28] usb-redir: Device disconnect + re-connect robustness
Justin M. Forbes fc5c27
 fixes
Justin M. Forbes fc5c27
Justin M. Forbes fc5c27
These fixes mainly target the other side sending some (error status)
Justin M. Forbes fc5c27
packets after a disconnect packet. In some cases these would get queued
Justin M. Forbes fc5c27
up and then reported to the controller when a new device gets connected.
Justin M. Forbes fc5c27
Justin M. Forbes fc5c27
* Fully reset device state on disconnect
Justin M. Forbes fc5c27
* Don't allow a connect message when already connected
Justin M. Forbes fc5c27
* Ignore iso and interrupt status messages when disconnected
Justin M. Forbes fc5c27
Justin M. Forbes fc5c27
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Justin M. Forbes fc5c27
---
Justin M. Forbes fc5c27
 usb-redir.c |   22 +++++++++++++++++++++-
Justin M. Forbes fc5c27
 1 files changed, 21 insertions(+), 1 deletions(-)
Justin M. Forbes fc5c27
Justin M. Forbes fc5c27
diff --git a/usb-redir.c b/usb-redir.c
Justin M. Forbes fc5c27
index 9ce2c8b..6d8f986 100644
Justin M. Forbes fc5c27
--- a/usb-redir.c
Justin M. Forbes fc5c27
+++ b/usb-redir.c
Justin M. Forbes fc5c27
@@ -905,6 +905,11 @@ static void usbredir_device_connect(void *priv,
Justin M. Forbes fc5c27
 {
Justin M. Forbes fc5c27
     USBRedirDevice *dev = priv;
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
+    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
Justin M. Forbes fc5c27
+        ERROR("Received device connect while already connected\n");
Justin M. Forbes fc5c27
+        return;
Justin M. Forbes fc5c27
+    }
Justin M. Forbes fc5c27
+
Justin M. Forbes fc5c27
     switch (device_connect->speed) {
Justin M. Forbes fc5c27
     case usb_redir_speed_low:
Justin M. Forbes fc5c27
         DPRINTF("attaching low speed device\n");
Justin M. Forbes fc5c27
@@ -933,19 +938,26 @@ static void usbredir_device_connect(void *priv,
Justin M. Forbes fc5c27
 static void usbredir_device_disconnect(void *priv)
Justin M. Forbes fc5c27
 {
Justin M. Forbes fc5c27
     USBRedirDevice *dev = priv;
Justin M. Forbes fc5c27
+    int i;
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
     /* Stop any pending attaches */
Justin M. Forbes fc5c27
     qemu_del_timer(dev->attach_timer);
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
     if (dev->dev.attached) {
Justin M. Forbes fc5c27
         usb_device_detach(&dev->dev);
Justin M. Forbes fc5c27
-        usbredir_cleanup_device_queues(dev);
Justin M. Forbes fc5c27
         /*
Justin M. Forbes fc5c27
          * Delay next usb device attach to give the guest a chance to see
Justin M. Forbes fc5c27
          * see the detach / attach in case of quick close / open succession
Justin M. Forbes fc5c27
          */
Justin M. Forbes fc5c27
         dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
Justin M. Forbes fc5c27
     }
Justin M. Forbes fc5c27
+
Justin M. Forbes fc5c27
+    /* Reset state so that the next dev connected starts with a clean slate */
Justin M. Forbes fc5c27
+    usbredir_cleanup_device_queues(dev);
Justin M. Forbes fc5c27
+    memset(dev->endpoint, 0, sizeof(dev->endpoint));
Justin M. Forbes fc5c27
+    for (i = 0; i < MAX_ENDPOINTS; i++) {
Justin M. Forbes fc5c27
+        QTAILQ_INIT(&dev->endpoint[i].bufpq);
Justin M. Forbes fc5c27
+    }
Justin M. Forbes fc5c27
 }
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
 static void usbredir_interface_info(void *priv,
Justin M. Forbes fc5c27
@@ -1037,6 +1049,10 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id,
Justin M. Forbes fc5c27
     DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
Justin M. Forbes fc5c27
             ep, id);
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
+    if (!dev->dev.attached) {
Justin M. Forbes fc5c27
+        return;
Justin M. Forbes fc5c27
+    }
Justin M. Forbes fc5c27
+
Justin M. Forbes fc5c27
     dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
Justin M. Forbes fc5c27
     if (iso_stream_status->status == usb_redir_stall) {
Justin M. Forbes fc5c27
         DPRINTF("iso stream stopped by peer ep %02X\n", ep);
Justin M. Forbes fc5c27
@@ -1054,6 +1070,10 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
Justin M. Forbes fc5c27
     DPRINTF("interrupt recv status %d ep %02X id %u\n",
Justin M. Forbes fc5c27
             interrupt_receiving_status->status, ep, id);
Justin M. Forbes fc5c27
 
Justin M. Forbes fc5c27
+    if (!dev->dev.attached) {
Justin M. Forbes fc5c27
+        return;
Justin M. Forbes fc5c27
+    }
Justin M. Forbes fc5c27
+
Justin M. Forbes fc5c27
     dev->endpoint[EP2I(ep)].interrupt_error =
Justin M. Forbes fc5c27
         interrupt_receiving_status->status;
Justin M. Forbes fc5c27
     if (interrupt_receiving_status->status == usb_redir_stall) {
Justin M. Forbes fc5c27
-- 
Justin M. Forbes fc5c27
1.7.5.1
Justin M. Forbes fc5c27