[qemu/f17] Some more USB bugfixes from upstream

Hans de Goede jwrdegoede at fedoraproject.org
Mon Apr 2 12:09:35 UTC 2012


commit 18956f263a7a1b5c7fad657313000a18c8ce6074
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Apr 2 14:11:35 2012 +0200

    Some more USB bugfixes from upstream

 ...-ehci-frindex-always-is-a-14-bits-counter.patch |   74 ++++++++++++++++++++
 0142-usb-ehci-Drop-unused-sofv-value.patch         |   49 +++++++++++++
 ...otify-our-peer-when-we-reject-a-device-du.patch |   36 ++++++++++
 ...-An-interface-count-of-0-is-a-valid-value.patch |   47 ++++++++++++
 ...eset-device-address-and-speed-on-disconne.patch |   30 ++++++++
 ...ot-finding-an-async-urb-id-is-not-an-erro.patch |   31 ++++++++
 qemu.spec                                          |   17 ++++-
 7 files changed, 283 insertions(+), 1 deletions(-)
---
diff --git a/0141-usb-ehci-frindex-always-is-a-14-bits-counter.patch b/0141-usb-ehci-frindex-always-is-a-14-bits-counter.patch
new file mode 100644
index 0000000..4481332
--- /dev/null
+++ b/0141-usb-ehci-frindex-always-is-a-14-bits-counter.patch
@@ -0,0 +1,74 @@
+From 9d604ddc4770f8f25de148e9b35687817a5d4110 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 28 Mar 2012 20:31:32 +0200
+Subject: [PATCH 141/146] usb-ehci: frindex always is a 14 bits counter
+
+frindex always is a 14 bits counter, and not a 13 bits one as we were
+emulating. There are some subtle hints to this in the spec, first of all
+"Table 2-12. FRINDEX - Frame Index Register" says:
+"Bit 13:0 Frame Index. The value in this register increments at the end of
+each time frame (e.g. micro-frame). Bits [N:3] are used for the Frame List
+current index. This means that each location of the frame list is accessed
+8 times (frames or micro-frames) before moving to the next index. The
+following illustrates values of N based on the value of the Frame List
+Size field in the USBCMD register.
+
+USBCMD[Frame List Size]	Number Elements		 N
+00b				1024		12
+01b				 512		11
+10b				 256		10
+11b			    Reserved"
+
+Notice how the text talks about "Bits [N:3]" are used ..., it does
+NOT say that when N == 12 (our case) the counter will wrap from 8191 to 0,
+or in otherwords that it is a 13 bits counter (bits 0 - 12).
+
+The other hint is in "Table 2-10. USBSTS USB Status Register Bit Definitions":
+
+"Bit 3 Frame List Rollover - R/WC. The Host Controller sets this bit to a one
+when the Frame List Index (see Section 2.3.4) rolls over from its maximum value
+to zero. The exact value at which the rollover occurs depends on the frame
+list size. For example, if the frame list size (as programmed in the Frame
+List Size field of the USBCMD register) is 1024, the Frame Index Register
+rolls over every time FRINDEX[13] toggles. Similarly, if the size is 512,
+the Host Controller sets this bit to a one every time FRINDEX[12] toggles."
+
+Notice how this text talks about setting bit 3 when bit 13 of frindex toggles
+(when there are 1024 entries, so our case), so this indicates that frindex
+has a bit 13 making it a 14 bit counter.
+
+Besides these clear hints the real proof is in the pudding. Before this
+patch I could not stream data from a USB2 webcam under Windows XP, after
+this cam using a USB2 webcam under Windows XP works fine, and no regressions
+with other operating systems were seen.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ hw/usb-ehci.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
+index b5d7037..3934bf0 100644
+--- a/hw/usb-ehci.c
++++ b/hw/usb-ehci.c
+@@ -2157,11 +2157,15 @@ static void ehci_frame_timer(void *opaque)
+         if ( !(ehci->usbsts & USBSTS_HALT)) {
+             ehci->frindex += 8;
+ 
+-            if (ehci->frindex > 0x00001fff) {
+-                ehci->frindex = 0;
++            if (ehci->frindex == 0x00002000) {
+                 ehci_set_interrupt(ehci, USBSTS_FLR);
+             }
+ 
++            if (ehci->frindex == 0x00004000) {
++                ehci_set_interrupt(ehci, USBSTS_FLR);
++                ehci->frindex = 0;
++            }
++
+             ehci->sofv = (ehci->frindex - 1) >> 3;
+             ehci->sofv &= 0x000003ff;
+         }
+-- 
+1.7.9.3
+
diff --git a/0142-usb-ehci-Drop-unused-sofv-value.patch b/0142-usb-ehci-Drop-unused-sofv-value.patch
new file mode 100644
index 0000000..d2cf3bf
--- /dev/null
+++ b/0142-usb-ehci-Drop-unused-sofv-value.patch
@@ -0,0 +1,49 @@
+From ef3477db39f2eb38610b7e99a4a4f4d8ddb903df Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 29 Mar 2012 16:37:34 +0200
+Subject: [PATCH 142/146] usb-ehci: Drop unused sofv value
+
+The sofv value only ever gets a value assigned and is never used (read)
+anywhere, so we can just drop it.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ hw/usb-ehci.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
+index 3934bf0..ff69587 100644
+--- a/hw/usb-ehci.c
++++ b/hw/usb-ehci.c
+@@ -403,7 +403,6 @@ struct EHCIState {
+     /*
+      *  Internal states, shadow registers, etc
+      */
+-    uint32_t sofv;
+     QEMUTimer *frame_timer;
+     int attach_poll_counter;
+     int astate;                        // Current state in asynchronous schedule
+@@ -1082,10 +1081,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
+         val &= USBINTR_MASK;
+         break;
+ 
+-    case FRINDEX:
+-        s->sofv = val >> 3;
+-        break;
+-
+     case CONFIGFLAG:
+         val &= 0x1;
+         if (val) {
+@@ -2165,9 +2160,6 @@ static void ehci_frame_timer(void *opaque)
+                 ehci_set_interrupt(ehci, USBSTS_FLR);
+                 ehci->frindex = 0;
+             }
+-
+-            ehci->sofv = (ehci->frindex - 1) >> 3;
+-            ehci->sofv &= 0x000003ff;
+         }
+ 
+         if (frames - i > ehci->maxframes) {
+-- 
+1.7.9.3
+
diff --git a/0143-usb-redir-Notify-our-peer-when-we-reject-a-device-du.patch b/0143-usb-redir-Notify-our-peer-when-we-reject-a-device-du.patch
new file mode 100644
index 0000000..1bf631a
--- /dev/null
+++ b/0143-usb-redir-Notify-our-peer-when-we-reject-a-device-du.patch
@@ -0,0 +1,36 @@
+From 89c9752afa77c6936ab9839d8fb1ce42147086b2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 29 Mar 2012 16:41:23 +0200
+Subject: [PATCH 143/146] usb-redir: Notify our peer when we reject a device
+ due to a speed mismatch
+
+Also cleanup (reset) our device state when we reject a device due to a
+speed mismatch.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ usb-redir.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/usb-redir.c b/usb-redir.c
+index f64443e..8ee3f07 100644
+--- a/usb-redir.c
++++ b/usb-redir.c
+@@ -845,7 +845,13 @@ static void usbredir_do_attach(void *opaque)
+ {
+     USBRedirDevice *dev = opaque;
+ 
+-    usb_device_attach(&dev->dev);
++    if (usb_device_attach(&dev->dev) != 0) {
++        usbredir_device_disconnect(dev);
++        if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
++            usbredirparser_send_filter_reject(dev->parser);
++            usbredirparser_do_write(dev->parser);
++        }
++    }
+ }
+ 
+ /*
+-- 
+1.7.9.3
+
diff --git a/0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch b/0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch
new file mode 100644
index 0000000..f654331
--- /dev/null
+++ b/0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch
@@ -0,0 +1,47 @@
+From c6b10d4d87d8158c1b0bd8648491db8501dff784 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Sat, 31 Mar 2012 13:07:24 +0200
+Subject: [PATCH 144/146] usb-redir: An interface count of 0 is a valid value
+
+An interface-count of 0 happens when a device is in unconfigured state when
+it gets redirected. So we should not use 0 to detect not having received
+interface info from our peer.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ usb-redir.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/usb-redir.c b/usb-redir.c
+index 8ee3f07..3187b68 100644
+--- a/usb-redir.c
++++ b/usb-redir.c
+@@ -39,6 +39,7 @@
+ #include "hw/usb.h"
+ 
+ #define MAX_ENDPOINTS 32
++#define NO_INTERFACE_INFO 255 /* Valid interface_count always <= 32 */
+ #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
+ #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
+ 
+@@ -995,7 +996,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
+ 
+ static int usbredir_check_filter(USBRedirDevice *dev)
+ {
+-    if (dev->interface_info.interface_count == 0) {
++    if (dev->interface_info.interface_count == NO_INTERFACE_INFO) {
+         ERROR("No interface info for device\n");
+         goto error;
+     }
+@@ -1158,7 +1159,7 @@ static void usbredir_device_disconnect(void *priv)
+     for (i = 0; i < MAX_ENDPOINTS; i++) {
+         QTAILQ_INIT(&dev->endpoint[i].bufpq);
+     }
+-    dev->interface_info.interface_count = 0;
++    dev->interface_info.interface_count = NO_INTERFACE_INFO;
+ }
+ 
+ static void usbredir_interface_info(void *priv,
+-- 
+1.7.9.3
+
diff --git a/0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch b/0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch
new file mode 100644
index 0000000..b0c7c81
--- /dev/null
+++ b/0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch
@@ -0,0 +1,30 @@
+From 442d81d00308b0145307b175a1910c7443184a3f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Sat, 31 Mar 2012 13:12:09 +0200
+Subject: [PATCH 145/146] usb-redir: Reset device address and speed on
+ disconnect
+
+Without this disconnected devices look like the last redirected device
+in the monitor in "info usb".
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ usb-redir.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/usb-redir.c b/usb-redir.c
+index 3187b68..1a9d766 100644
+--- a/usb-redir.c
++++ b/usb-redir.c
+@@ -1160,6 +1160,8 @@ static void usbredir_device_disconnect(void *priv)
+         QTAILQ_INIT(&dev->endpoint[i].bufpq);
+     }
+     dev->interface_info.interface_count = NO_INTERFACE_INFO;
++    dev->dev.addr = 0;
++    dev->dev.speed = 0;
+ }
+ 
+ static void usbredir_interface_info(void *priv,
+-- 
+1.7.9.3
+
diff --git a/0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch b/0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch
new file mode 100644
index 0000000..dcb1a9a
--- /dev/null
+++ b/0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch
@@ -0,0 +1,31 @@
+From b467871a6a08b8ff12382e33e49f991fe02f3cc7 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Sat, 31 Mar 2012 13:17:13 +0200
+Subject: [PATCH 146/146] usb-redir: Not finding an async urb id is not an
+ error
+
+We clear our pending async urb list on device disconnect and we may still
+receive "packet complete" packets from our peer after this, which will then
+refer to packet ids no longer in our list.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ usb-redir.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/usb-redir.c b/usb-redir.c
+index 1a9d766..a41c231 100644
+--- a/usb-redir.c
++++ b/usb-redir.c
+@@ -286,7 +286,7 @@ static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
+             return aurb;
+         }
+     }
+-    ERROR("could not find async urb for packet_id %u\n", packet_id);
++    DPRINTF("could not find async urb for packet_id %u\n", packet_id);
+     return NULL;
+ }
+ 
+-- 
+1.7.9.3
+
diff --git a/qemu.spec b/qemu.spec
index a3f31c9..ec75464 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -1,7 +1,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 1.0
-Release: 10%{?dist}
+Release: 11%{?dist}
 # Epoch because we pushed a qemu-1.0 package
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -108,6 +108,12 @@ Patch137: 0137-usb-return-BABBLE-rather-then-NAK-when-we-receive-to.patch
 Patch138: 0138-usb-add-USB_RET_IOERROR.patch
 Patch139: 0139-usb-ehci-fix-reset.patch
 Patch140: 0140-usb-ehci-sanity-check-iso-xfers.patch
+Patch141: 0141-usb-ehci-frindex-always-is-a-14-bits-counter.patch
+Patch142: 0142-usb-ehci-Drop-unused-sofv-value.patch
+Patch143: 0143-usb-redir-Notify-our-peer-when-we-reject-a-device-du.patch
+Patch144: 0144-usb-redir-An-interface-count-of-0-is-a-valid-value.patch
+Patch145: 0145-usb-redir-Reset-device-address-and-speed-on-disconne.patch
+Patch146: 0146-usb-redir-Not-finding-an-async-urb-id-is-not-an-erro.patch
 
 # General bug fixes
 Patch201: Fix_save-restore_of_in-kernel_i8259.patch
@@ -425,6 +431,12 @@ such as kvm_stat.
 %patch138 -p1
 %patch139 -p1
 %patch140 -p1
+%patch141 -p1
+%patch142 -p1
+%patch143 -p1
+%patch144 -p1
+%patch145 -p1
+%patch146 -p1
 
 %patch201 -p1
 %patch202 -p1
@@ -816,6 +828,9 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Mon Apr  2 2012 Hans de Goede <hdegoede at redhat.com> - 2:1.0-11
+- Some more USB bugfixes from upstream
+
 * Wed Mar 28 2012 Daniel P. Berrange <berrange at redhat.com> - 2:1.0-10
 - Switch to use iPXE for netboot ROMs
 


More information about the scm-commits mailing list