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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 +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 +--- + 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 edc3f96..92accae 100644 --- a/qemu.spec +++ b/qemu.spec @@ -38,7 +38,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 1.0 -Release: 12%{?dist} +Release: 13%{?dist} # Epoch because we pushed a qemu-1.0 package Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD @@ -145,6 +145,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 @@ -466,6 +472,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 @@ -869,6 +881,9 @@ fi %{_mandir}/man1/qemu-img.1* %changelog +* Mon Apr 2 2012 Hans de Goede - 2:1.0-13 +- Some more USB bugfixes from upstream + * Thu Mar 29 2012 Eduardo Habkost - 2:1.0-12 - Fix ExclusiveArch mistake that disabled all non-x86_64 builds on Fedora