summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-08-26 15:33:38 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-26 15:33:38 -0700
commit419e42eb73f7618bc1e08cdd815df3bb114e575b (patch)
tree4b3625b85a3da8b11d7c0e18c9226cbc626a1402
parentd9d7239bdd99cea72c95444ce8f0935ec65c6a27 (diff)
downloadstable-queue-419e42eb73f7618bc1e08cdd815df3bb114e575b.tar.gz
3.0 patches
-rw-r--r--queue-3.0/series12
-rw-r--r--queue-3.0/usb-ehci-do-not-rely-on-port_suspend-to-stop-usb-resuming-in-ehci_bus_resume.patch54
-rw-r--r--queue-3.0/usb-musb-cppi-fix-build-errors-due-to-dbg-and-missing.patch96
-rw-r--r--queue-3.0/usb-option-add-yuga-device-id-to-driver.patch124
-rw-r--r--queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k3806.patch41
-rw-r--r--queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k4605.patch56
-rw-r--r--queue-3.0/usb-option-driver-k3765-k4505-avoid-cdc_data-interface.patch33
-rw-r--r--queue-3.0/xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch165
-rw-r--r--queue-3.0/xhci-fix-memory-leak-during-failed-enqueue.patch131
-rw-r--r--queue-3.0/xhci-fix-port-u3-status-check-condition.patch34
-rw-r--r--queue-3.0/xhci-handle-zero-length-isochronous-packets.patch96
-rw-r--r--queue-3.0/xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch116
-rw-r--r--queue-3.0/xhci-report-usb2-port-in-resuming-as-suspend.patch78
13 files changed, 1036 insertions, 0 deletions
diff --git a/queue-3.0/series b/queue-3.0/series
index 0d226bf4bc..320a3bfe87 100644
--- a/queue-3.0/series
+++ b/queue-3.0/series
@@ -13,3 +13,15 @@ tty-add-spi-prefix-for-spi-modalias.patch
tty-pty-fix-pty-counting.patch
usb-ftdi_sio-add-calao-reference-board-support.patch
usb-s5p-ehci-fix-a-null-pointer-deference.patch
+usb-option-driver-add-pid-of-huawei-vodafone-k3806.patch
+usb-option-driver-add-pid-of-huawei-vodafone-k4605.patch
+usb-option-add-yuga-device-id-to-driver.patch
+usb-option-driver-k3765-k4505-avoid-cdc_data-interface.patch
+usb-musb-cppi-fix-build-errors-due-to-dbg-and-missing.patch
+usb-ehci-do-not-rely-on-port_suspend-to-stop-usb-resuming-in-ehci_bus_resume.patch
+xhci-fix-port-u3-status-check-condition.patch
+xhci-report-usb2-port-in-resuming-as-suspend.patch
+xhci-fix-memory-leak-during-failed-enqueue.patch
+xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch
+xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch
+xhci-handle-zero-length-isochronous-packets.patch
diff --git a/queue-3.0/usb-ehci-do-not-rely-on-port_suspend-to-stop-usb-resuming-in-ehci_bus_resume.patch b/queue-3.0/usb-ehci-do-not-rely-on-port_suspend-to-stop-usb-resuming-in-ehci_bus_resume.patch
new file mode 100644
index 0000000000..88b845bb11
--- /dev/null
+++ b/queue-3.0/usb-ehci-do-not-rely-on-port_suspend-to-stop-usb-resuming-in-ehci_bus_resume.patch
@@ -0,0 +1,54 @@
+From d0f2fb2500b1c5fe4967eb45d8c9bc758d7aef80 Mon Sep 17 00:00:00 2001
+From: Wang Zhi <zhi.wang@windriver.com>
+Date: Wed, 17 Aug 2011 10:39:31 +0800
+Subject: USB: EHCI: Do not rely on PORT_SUSPEND to stop USB resuming in ehci_bus_resume().
+
+From: Wang Zhi <zhi.wang@windriver.com>
+
+commit d0f2fb2500b1c5fe4967eb45d8c9bc758d7aef80 upstream.
+
+From EHCI Spec p.28 HC should clear PORT_SUSPEND when SW clears
+PORT_RESUME. In Intel Oaktrail platform, MPH (Multi-Port Host
+Controller) core clears PORT_SUSPEND directly when SW sets PORT_RESUME
+bit. If we rely on PORT_SUSPEND bit to stop USB resume, we will miss
+the action of clearing PORT_RESUME. This will cause unexpected long
+resume signal on USB bus.
+
+Signed-off-by: Wang Zhi <zhi.wang@windriver.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hub.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -343,7 +343,7 @@ static int ehci_bus_resume (struct usb_h
+ u32 temp;
+ u32 power_okay;
+ int i;
+- u8 resume_needed = 0;
++ unsigned long resume_needed = 0;
+
+ if (time_before (jiffies, ehci->next_statechange))
+ msleep(5);
+@@ -416,7 +416,7 @@ static int ehci_bus_resume (struct usb_h
+ if (test_bit(i, &ehci->bus_suspended) &&
+ (temp & PORT_SUSPEND)) {
+ temp |= PORT_RESUME;
+- resume_needed = 1;
++ set_bit(i, &resume_needed);
+ }
+ ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
+ }
+@@ -431,8 +431,7 @@ static int ehci_bus_resume (struct usb_h
+ i = HCS_N_PORTS (ehci->hcs_params);
+ while (i--) {
+ temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
+- if (test_bit(i, &ehci->bus_suspended) &&
+- (temp & PORT_SUSPEND)) {
++ if (test_bit(i, &resume_needed)) {
+ temp &= ~(PORT_RWC_BITS | PORT_RESUME);
+ ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
+ ehci_vdbg (ehci, "resumed port %d\n", i + 1);
diff --git a/queue-3.0/usb-musb-cppi-fix-build-errors-due-to-dbg-and-missing.patch b/queue-3.0/usb-musb-cppi-fix-build-errors-due-to-dbg-and-missing.patch
new file mode 100644
index 0000000000..b60c1ab619
--- /dev/null
+++ b/queue-3.0/usb-musb-cppi-fix-build-errors-due-to-dbg-and-missing.patch
@@ -0,0 +1,96 @@
+From f847a79ab3c1faca3022061045cd22e4678c1b1c Mon Sep 17 00:00:00 2001
+From: Per Forlin <per.forlin@linaro.org>
+Date: Wed, 3 Aug 2011 15:39:15 +0200
+Subject: usb: musb: cppi: fix build errors due to DBG and missing
+ musb variable
+
+From: Per Forlin <per.forlin@linaro.org>
+
+commit f847a79ab3c1faca3022061045cd22e4678c1b1c upstream.
+
+Replace DBG with dev_dbg and fix invalid access of musb->controller.
+With this patch cppi_dma builds successfully.
+
+Signed-off-by: Per Forlin <per.forlin@linaro.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/cppi_dma.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/musb/cppi_dma.c
++++ b/drivers/usb/musb/cppi_dma.c
+@@ -226,8 +226,10 @@ static int cppi_controller_stop(struct d
+ struct cppi *controller;
+ void __iomem *tibase;
+ int i;
++ struct musb *musb;
+
+ controller = container_of(c, struct cppi, controller);
++ musb = controller->musb;
+
+ tibase = controller->tibase;
+ /* DISABLE INDIVIDUAL CHANNEL Interrupts */
+@@ -289,9 +291,11 @@ cppi_channel_allocate(struct dma_control
+ u8 index;
+ struct cppi_channel *cppi_ch;
+ void __iomem *tibase;
++ struct musb *musb;
+
+ controller = container_of(c, struct cppi, controller);
+ tibase = controller->tibase;
++ musb = controller->musb;
+
+ /* ep0 doesn't use DMA; remember cppi indices are 0..N-1 */
+ index = ep->epnum - 1;
+@@ -339,7 +343,8 @@ static void cppi_channel_release(struct
+ c = container_of(channel, struct cppi_channel, channel);
+ tibase = c->controller->tibase;
+ if (!c->hw_ep)
+- dev_dbg(musb->controller, "releasing idle DMA channel %p\n", c);
++ dev_dbg(c->controller->musb->controller,
++ "releasing idle DMA channel %p\n", c);
+ else if (!c->transmit)
+ core_rxirq_enable(tibase, c->index + 1);
+
+@@ -357,10 +362,11 @@ cppi_dump_rx(int level, struct cppi_chan
+
+ musb_ep_select(base, c->index + 1);
+
+- DBG(level, "RX DMA%d%s: %d left, csr %04x, "
+- "%08x H%08x S%08x C%08x, "
+- "B%08x L%08x %08x .. %08x"
+- "\n",
++ dev_dbg(c->controller->musb->controller,
++ "RX DMA%d%s: %d left, csr %04x, "
++ "%08x H%08x S%08x C%08x, "
++ "B%08x L%08x %08x .. %08x"
++ "\n",
+ c->index, tag,
+ musb_readl(c->controller->tibase,
+ DAVINCI_RXCPPI_BUFCNT0_REG + 4 * c->index),
+@@ -387,10 +393,11 @@ cppi_dump_tx(int level, struct cppi_chan
+
+ musb_ep_select(base, c->index + 1);
+
+- DBG(level, "TX DMA%d%s: csr %04x, "
+- "H%08x S%08x C%08x %08x, "
+- "F%08x L%08x .. %08x"
+- "\n",
++ dev_dbg(c->controller->musb->controller,
++ "TX DMA%d%s: csr %04x, "
++ "H%08x S%08x C%08x %08x, "
++ "F%08x L%08x .. %08x"
++ "\n",
+ c->index, tag,
+ musb_readw(c->hw_ep->regs, MUSB_TXCSR),
+
+@@ -1022,6 +1029,7 @@ static bool cppi_rx_scan(struct cppi *cp
+ int i;
+ dma_addr_t safe2ack;
+ void __iomem *regs = rx->hw_ep->regs;
++ struct musb *musb = cppi->musb;
+
+ cppi_dump_rx(6, rx, "/K");
+
diff --git a/queue-3.0/usb-option-add-yuga-device-id-to-driver.patch b/queue-3.0/usb-option-add-yuga-device-id-to-driver.patch
new file mode 100644
index 0000000000..869a05cfc1
--- /dev/null
+++ b/queue-3.0/usb-option-add-yuga-device-id-to-driver.patch
@@ -0,0 +1,124 @@
+From c6eb2d75ffcdfafa37ff010bf467de20d468ef79 Mon Sep 17 00:00:00 2001
+From: "Gavin.zhu" <gavin.kx@qq.com>
+Date: Mon, 22 Aug 2011 13:51:53 -0700
+Subject: USB: option: add YUGA device id to driver
+
+From: "Gavin.zhu" <gavin.kx@qq.com>
+
+commit c6eb2d75ffcdfafa37ff010bf467de20d468ef79 upstream.
+
+Signed-off-by: Gavin.zhu <gavin.kx@qq.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 92 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -418,6 +418,56 @@ static void option_instat_callback(struc
+ #define SAMSUNG_VENDOR_ID 0x04e8
+ #define SAMSUNG_PRODUCT_GT_B3730 0x6889
+
++/* YUGA products www.yuga-info.com*/
++#define YUGA_VENDOR_ID 0x257A
++#define YUGA_PRODUCT_CEM600 0x1601
++#define YUGA_PRODUCT_CEM610 0x1602
++#define YUGA_PRODUCT_CEM500 0x1603
++#define YUGA_PRODUCT_CEM510 0x1604
++#define YUGA_PRODUCT_CEM800 0x1605
++#define YUGA_PRODUCT_CEM900 0x1606
++
++#define YUGA_PRODUCT_CEU818 0x1607
++#define YUGA_PRODUCT_CEU816 0x1608
++#define YUGA_PRODUCT_CEU828 0x1609
++#define YUGA_PRODUCT_CEU826 0x160A
++#define YUGA_PRODUCT_CEU518 0x160B
++#define YUGA_PRODUCT_CEU516 0x160C
++#define YUGA_PRODUCT_CEU528 0x160D
++#define YUGA_PRODUCT_CEU526 0x160F
++
++#define YUGA_PRODUCT_CWM600 0x2601
++#define YUGA_PRODUCT_CWM610 0x2602
++#define YUGA_PRODUCT_CWM500 0x2603
++#define YUGA_PRODUCT_CWM510 0x2604
++#define YUGA_PRODUCT_CWM800 0x2605
++#define YUGA_PRODUCT_CWM900 0x2606
++
++#define YUGA_PRODUCT_CWU718 0x2607
++#define YUGA_PRODUCT_CWU716 0x2608
++#define YUGA_PRODUCT_CWU728 0x2609
++#define YUGA_PRODUCT_CWU726 0x260A
++#define YUGA_PRODUCT_CWU518 0x260B
++#define YUGA_PRODUCT_CWU516 0x260C
++#define YUGA_PRODUCT_CWU528 0x260D
++#define YUGA_PRODUCT_CWU526 0x260F
++
++#define YUGA_PRODUCT_CLM600 0x2601
++#define YUGA_PRODUCT_CLM610 0x2602
++#define YUGA_PRODUCT_CLM500 0x2603
++#define YUGA_PRODUCT_CLM510 0x2604
++#define YUGA_PRODUCT_CLM800 0x2605
++#define YUGA_PRODUCT_CLM900 0x2606
++
++#define YUGA_PRODUCT_CLU718 0x2607
++#define YUGA_PRODUCT_CLU716 0x2608
++#define YUGA_PRODUCT_CLU728 0x2609
++#define YUGA_PRODUCT_CLU726 0x260A
++#define YUGA_PRODUCT_CLU518 0x260B
++#define YUGA_PRODUCT_CLU516 0x260C
++#define YUGA_PRODUCT_CLU528 0x260D
++#define YUGA_PRODUCT_CLU526 0x260F
++
+ /* some devices interfaces need special handling due to a number of reasons */
+ enum option_blacklist_reason {
+ OPTION_BLACKLIST_NONE = 0,
+@@ -1009,6 +1059,48 @@ static const struct usb_device_id option
+ { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
+ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
+ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM500) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM510) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM800) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM900) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU818) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU816) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU828) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU826) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU518) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU516) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU528) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEU526) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM600) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM610) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM500) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM510) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM800) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWM900) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU718) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU716) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU728) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU726) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU518) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU516) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU528) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CWU526) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM600) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM610) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM500) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM510) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM800) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLM900) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU718) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU716) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU728) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU726) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU518) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
++ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k3806.patch b/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k3806.patch
new file mode 100644
index 0000000000..4a05fcf6a2
--- /dev/null
+++ b/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k3806.patch
@@ -0,0 +1,41 @@
+From 0e69d75ccb2f091757b38d4d6a2ed739e06b615e Mon Sep 17 00:00:00 2001
+From: Andrew Bird <ajb@spheresystems.co.uk>
+Date: Tue, 16 Aug 2011 13:57:14 -0600
+Subject: USB option driver add PID of Huawei Vodafone K3806
+
+From: Andrew Bird <ajb@spheresystems.co.uk>
+
+commit 0e69d75ccb2f091757b38d4d6a2ed739e06b615e upstream.
+
+This patch adds the product ID of Huawei's Vodafone K3806 mobile broadband
+modem to option.c. This is necessary so that the driver gets loaded on
+demand without the intervention of usb_modeswitch. This has the benefit of
+it becoming available faster and also ensures that the option driver is not
+bound to a network interface that should be claimed by cdc_ether.
+
+Signed-off-by: Andrew Bird <ajb@spheresystems.co.uk>
+Signed-off-by: Alex Chiang <achiang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -148,6 +148,7 @@ static void option_instat_callback(struc
+ #define HUAWEI_PRODUCT_K4505 0x1464
+ #define HUAWEI_PRODUCT_K3765 0x1465
+ #define HUAWEI_PRODUCT_E14AC 0x14AC
++#define HUAWEI_PRODUCT_K3806 0x14AE
+ #define HUAWEI_PRODUCT_K3770 0x14C9
+ #define HUAWEI_PRODUCT_K3771 0x14CA
+ #define HUAWEI_PRODUCT_K4510 0x14CB
+@@ -551,6 +552,7 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
diff --git a/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k4605.patch b/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k4605.patch
new file mode 100644
index 0000000000..dcbccec636
--- /dev/null
+++ b/queue-3.0/usb-option-driver-add-pid-of-huawei-vodafone-k4605.patch
@@ -0,0 +1,56 @@
+From 7e1805844da18a37e6d251d286f93c94b52d791e Mon Sep 17 00:00:00 2001
+From: Andrew Bird <ajb@spheresystems.co.uk>
+Date: Tue, 16 Aug 2011 13:58:21 -0600
+Subject: USB option driver add PID of Huawei Vodafone K4605
+
+From: Andrew Bird <ajb@spheresystems.co.uk>
+
+commit 7e1805844da18a37e6d251d286f93c94b52d791e upstream.
+
+This patch adds the product ID of Huawei's Vodafone K4605 mobile broadband
+modem to option.c. This is necessary so that the driver gets loaded on
+demand without the intervention of usb_modeswitch. This has the benefit of
+it becoming available faster and also ensures that the option driver is not
+bound to a network interface that should be claimed by suitable network
+driver.
+
+Signed-off-by: Andrew Bird <ajb@spheresystems.co.uk>
+Signed-off-by: Alex Chiang <achiang@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -149,6 +149,7 @@ static void option_instat_callback(struc
+ #define HUAWEI_PRODUCT_K3765 0x1465
+ #define HUAWEI_PRODUCT_E14AC 0x14AC
+ #define HUAWEI_PRODUCT_K3806 0x14AE
++#define HUAWEI_PRODUCT_K4605 0x14C6
+ #define HUAWEI_PRODUCT_K3770 0x14C9
+ #define HUAWEI_PRODUCT_K3771 0x14CA
+ #define HUAWEI_PRODUCT_K4510 0x14CB
+@@ -553,6 +554,7 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
+@@ -1136,10 +1138,11 @@ static int option_probe(struct usb_seria
+ serial->interface->cur_altsetting->desc.bInterfaceClass != 0xff)
+ return -ENODEV;
+
+- /* Don't bind network interfaces on Huawei K3765 & K4505 */
++ /* Don't bind network interfaces on Huawei K3765, K4505 & K4605 */
+ if (serial->dev->descriptor.idVendor == HUAWEI_VENDOR_ID &&
+ (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 ||
+- serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505) &&
++ serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 ||
++ serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) &&
+ serial->interface->cur_altsetting->desc.bInterfaceNumber == 1)
+ return -ENODEV;
+
diff --git a/queue-3.0/usb-option-driver-k3765-k4505-avoid-cdc_data-interface.patch b/queue-3.0/usb-option-driver-k3765-k4505-avoid-cdc_data-interface.patch
new file mode 100644
index 0000000000..933a931303
--- /dev/null
+++ b/queue-3.0/usb-option-driver-k3765-k4505-avoid-cdc_data-interface.patch
@@ -0,0 +1,33 @@
+From 6118514e8749105334f46ccec6faf9a439be6cf9 Mon Sep 17 00:00:00 2001
+From: Andrew Bird <ajb@spheresystems.co.uk>
+Date: Wed, 17 Aug 2011 00:20:03 +0100
+Subject: USB option driver K3765/K4505 avoid CDC_DATA interface
+
+From: Andrew Bird <ajb@spheresystems.co.uk>
+
+commit 6118514e8749105334f46ccec6faf9a439be6cf9 upstream.
+
+Currently the Option driver avoids binding interface 1 on Huawei K3765
+and K4505 broadband modems as it should be handled by the cdc_ether
+driver instead. This patch ensures we don't bind the interface 2
+on those devices as that is CDC_DATA.
+
+Signed-off-by: Andrew Bird <ajb@spheresystems.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1235,7 +1235,8 @@ static int option_probe(struct usb_seria
+ (serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K3765 ||
+ serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4505 ||
+ serial->dev->descriptor.idProduct == HUAWEI_PRODUCT_K4605) &&
+- serial->interface->cur_altsetting->desc.bInterfaceNumber == 1)
++ (serial->interface->cur_altsetting->desc.bInterfaceNumber == 1 ||
++ serial->interface->cur_altsetting->desc.bInterfaceNumber == 2))
+ return -ENODEV;
+
+ /* Don't bind network interface on Samsung GT-B3730, it is handled by a separate module */
diff --git a/queue-3.0/xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch b/queue-3.0/xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch
new file mode 100644
index 0000000000..e4134e6ac4
--- /dev/null
+++ b/queue-3.0/xhci-fix-failed-enqueue-in-the-middle-of-isoch-td.patch
@@ -0,0 +1,165 @@
+From 522989a27c7badb608155b1f1dea3487ed431f74 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 29 Jul 2011 12:44:32 -0700
+Subject: xhci: Fix failed enqueue in the middle of isoch TD.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 522989a27c7badb608155b1f1dea3487ed431f74 upstream.
+
+When an isochronous transfer is enqueued, xhci_queue_isoc_tx_prepare()
+will ensure that there is enough room on the transfer rings for all of the
+isochronous TDs for that URB. However, when xhci_queue_isoc_tx() is
+enqueueing individual isoc TDs, the prepare_transfer() function can fail
+if the endpoint state has changed to disabled, error, or some other
+unknown state.
+
+With the current code, if Nth TD (not the first TD) fails, the ring is
+left in a sorry state. The partially enqueued TDs are left on the ring,
+and the first TRB of the TD is not given back to the hardware. The
+enqueue pointer is left on the TRB after the last successfully enqueued
+TD. This means the ring is basically useless. Any new transfers will be
+enqueued after the failed TDs, which the hardware will never read because
+the cycle bit indicates it does not own them. The ring will fill up with
+untransferred TDs, and the endpoint will be basically unusable.
+
+The untransferred TDs will also remain on the TD list. Since the td_list
+is a FIFO, this basically means the ring handler will be waiting on TDs
+that will never be completed (or worse, dereference memory that doesn't
+exist any more).
+
+Change the code to clean up the isochronous ring after a failed transfer.
+If the first TD failed, simply return and allow the xhci_urb_enqueue
+function to free the urb_priv. If the Nth TD failed, first remove the TDs
+from the td_list. Then convert the TRBs that were enqueued into No-op
+TRBs. Make sure to flip the cycle bit on all enqueued TRBs (including any
+link TRBs in the middle or between TDs), but leave the cycle bit of the
+first TRB (which will show software-owned) intact. Then move the ring
+enqueue pointer back to the first TRB and make sure to change the
+xhci_ring's cycle state to what is appropriate for that ring segment.
+
+This ensures that the No-op TRBs will be overwritten by subsequent TDs,
+and the hardware will not start executing random TRBs because the cycle
+bit was left as hardware-owned.
+
+This bug is unlikely to be hit, but it was something I noticed while
+tracking down the watchdog timer issue. I verified that the fix works by
+injecting some errors on the 250th isochronous URB queued, although I
+could not verify that the ring is in the correct state because uvcvideo
+refused to talk to the device after the first usb_submit_urb() failed.
+Ring debugging shows that the ring looks correct, however.
+
+This patch should be backported to kernels as old as 2.6.36.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 50 +++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 44 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -516,8 +516,12 @@ void xhci_find_new_dequeue_state(struct
+ (unsigned long long) addr);
+ }
+
++/* flip_cycle means flip the cycle bit of all but the first and last TRB.
++ * (The last TRB actually points to the ring enqueue pointer, which is not part
++ * of this TD.) This is used to remove partially enqueued isoc TDs from a ring.
++ */
+ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
+- struct xhci_td *cur_td)
++ struct xhci_td *cur_td, bool flip_cycle)
+ {
+ struct xhci_segment *cur_seg;
+ union xhci_trb *cur_trb;
+@@ -531,6 +535,12 @@ static void td_to_noop(struct xhci_hcd *
+ * leave the pointers intact.
+ */
+ cur_trb->generic.field[3] &= cpu_to_le32(~TRB_CHAIN);
++ /* Flip the cycle bit (link TRBs can't be the first
++ * or last TRB).
++ */
++ if (flip_cycle)
++ cur_trb->generic.field[3] ^=
++ cpu_to_le32(TRB_CYCLE);
+ xhci_dbg(xhci, "Cancel (unchain) link TRB\n");
+ xhci_dbg(xhci, "Address = %p (0x%llx dma); "
+ "in seg %p (0x%llx dma)\n",
+@@ -544,6 +554,11 @@ static void td_to_noop(struct xhci_hcd *
+ cur_trb->generic.field[2] = 0;
+ /* Preserve only the cycle bit of this TRB */
+ cur_trb->generic.field[3] &= cpu_to_le32(TRB_CYCLE);
++ /* Flip the cycle bit except on the first or last TRB */
++ if (flip_cycle && cur_trb != cur_td->first_trb &&
++ cur_trb != cur_td->last_trb)
++ cur_trb->generic.field[3] ^=
++ cpu_to_le32(TRB_CYCLE);
+ cur_trb->generic.field[3] |= cpu_to_le32(
+ TRB_TYPE(TRB_TR_NOOP));
+ xhci_dbg(xhci, "Cancel TRB %p (0x%llx dma) "
+@@ -722,7 +737,7 @@ static void handle_stopped_endpoint(stru
+ cur_td->urb->stream_id,
+ cur_td, &deq_state);
+ else
+- td_to_noop(xhci, ep_ring, cur_td);
++ td_to_noop(xhci, ep_ring, cur_td, false);
+ remove_finished_td:
+ /*
+ * The event handler won't see a completion for this TD anymore,
+@@ -3231,6 +3246,7 @@ static int xhci_queue_isoc_tx(struct xhc
+ start_trb = &ep_ring->enqueue->generic;
+ start_cycle = ep_ring->cycle_state;
+
++ urb_priv = urb->hcpriv;
+ /* Queue the first TRB, even if it's zero-length */
+ for (i = 0; i < num_tds; i++) {
+ unsigned int total_packet_count;
+@@ -3254,12 +3270,13 @@ static int xhci_queue_isoc_tx(struct xhc
+
+ ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index,
+ urb->stream_id, trbs_per_td, urb, i, mem_flags);
+- if (ret < 0)
+- return ret;
++ if (ret < 0) {
++ if (i == 0)
++ return ret;
++ goto cleanup;
++ }
+
+- urb_priv = urb->hcpriv;
+ td = urb_priv->td[i];
+-
+ for (j = 0; j < trbs_per_td; j++) {
+ u32 remainder = 0;
+ field = TRB_TBC(burst_count) | TRB_TLBPC(residue);
+@@ -3349,6 +3366,27 @@ static int xhci_queue_isoc_tx(struct xhc
+ giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
+ start_cycle, start_trb);
+ return 0;
++cleanup:
++ /* Clean up a partially enqueued isoc transfer. */
++
++ for (i--; i >= 0; i--)
++ list_del(&urb_priv->td[i]->td_list);
++
++ /* Use the first TD as a temporary variable to turn the TDs we've queued
++ * into No-ops with a software-owned cycle bit. That way the hardware
++ * won't accidentally start executing bogus TDs when we partially
++ * overwrite them. td->first_trb and td->start_seg are already set.
++ */
++ urb_priv->td[0]->last_trb = ep_ring->enqueue;
++ /* Every TRB except the first & last will have its cycle bit flipped. */
++ td_to_noop(xhci, ep_ring, urb_priv->td[0], true);
++
++ /* Reset the ring enqueue back to the first TRB and its cycle bit. */
++ ep_ring->enqueue = urb_priv->td[0]->first_trb;
++ ep_ring->enq_seg = urb_priv->td[0]->start_seg;
++ ep_ring->cycle_state = start_cycle;
++ usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
++ return ret;
+ }
+
+ /*
diff --git a/queue-3.0/xhci-fix-memory-leak-during-failed-enqueue.patch b/queue-3.0/xhci-fix-memory-leak-during-failed-enqueue.patch
new file mode 100644
index 0000000000..b9780008e5
--- /dev/null
+++ b/queue-3.0/xhci-fix-memory-leak-during-failed-enqueue.patch
@@ -0,0 +1,131 @@
+From d13565c12828ce0cd2a3862bf6260164a0653352 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 22 Jul 2011 14:34:34 -0700
+Subject: xhci: Fix memory leak during failed enqueue.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit d13565c12828ce0cd2a3862bf6260164a0653352 upstream.
+
+When the isochronous transfer support was introduced, and the xHCI driver
+switched to using urb->hcpriv to store an "urb_priv" pointer, a couple of
+memory leaks were introduced into the URB enqueue function in its error
+handling paths.
+
+xhci_urb_enqueue allocates urb_priv, but it doesn't free it if changing
+the control endpoint's max packet size fails or the bulk endpoint is in
+the middle of allocating or deallocating streams.
+
+xhci_urb_enqueue also doesn't free urb_priv if any of the four endpoint
+types' enqueue functions fail. Instead, it expects those functions to
+free urb_priv if an error occurs. However, the bulk, control, and
+interrupt enqueue functions do not free urb_priv if the endpoint ring is
+NULL. It will, however, get freed if prepare_transfer() fails in those
+enqueue functions.
+
+Several of the error paths in the isochronous endpoint enqueue function
+also fail to free it. xhci_queue_isoc_tx_prepare() doesn't free urb_priv
+if prepare_ring() indicates there is not enough room for all the
+isochronous TDs in this URB. If individual isochronous TDs fail to be
+queued (perhaps due to an endpoint state change), urb_priv is also leaked.
+
+This argues that the freeing of urb_priv should be done in the function
+that allocated it, xhci_urb_enqueue.
+
+This patch looks rather ugly, but refactoring the code will have to wait
+because this patch needs to be backported to stable kernels.
+
+This patch should be backported to kernels as old as 2.6.36.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 5 +----
+ drivers/usb/host/xhci.c | 21 +++++++++++++++++----
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2508,11 +2508,8 @@ static int prepare_transfer(struct xhci_
+
+ if (td_index == 0) {
+ ret = usb_hcd_link_urb_to_ep(bus_to_hcd(urb->dev->bus), urb);
+- if (unlikely(ret)) {
+- xhci_urb_free_priv(xhci, urb_priv);
+- urb->hcpriv = NULL;
++ if (unlikely(ret))
+ return ret;
+- }
+ }
+
+ td->urb = urb;
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1085,8 +1085,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd
+ if (urb->dev->speed == USB_SPEED_FULL) {
+ ret = xhci_check_maxpacket(xhci, slot_id,
+ ep_index, urb);
+- if (ret < 0)
++ if (ret < 0) {
++ xhci_urb_free_priv(xhci, urb_priv);
++ urb->hcpriv = NULL;
+ return ret;
++ }
+ }
+
+ /* We have a spinlock and interrupts disabled, so we must pass
+@@ -1097,6 +1100,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd
+ goto dying;
+ ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
++ if (ret)
++ goto free_priv;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
+ spin_lock_irqsave(&xhci->lock, flags);
+@@ -1117,6 +1122,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd
+ ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
+ }
++ if (ret)
++ goto free_priv;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else if (usb_endpoint_xfer_int(&urb->ep->desc)) {
+ spin_lock_irqsave(&xhci->lock, flags);
+@@ -1124,6 +1131,8 @@ int xhci_urb_enqueue(struct usb_hcd *hcd
+ goto dying;
+ ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
++ if (ret)
++ goto free_priv;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ } else {
+ spin_lock_irqsave(&xhci->lock, flags);
+@@ -1131,18 +1140,22 @@ int xhci_urb_enqueue(struct usb_hcd *hcd
+ goto dying;
+ ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb,
+ slot_id, ep_index);
++ if (ret)
++ goto free_priv;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ }
+ exit:
+ return ret;
+ dying:
+- xhci_urb_free_priv(xhci, urb_priv);
+- urb->hcpriv = NULL;
+ xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for "
+ "non-responsive xHCI host.\n",
+ urb->ep->desc.bEndpointAddress, urb);
++ ret = -ESHUTDOWN;
++free_priv:
++ xhci_urb_free_priv(xhci, urb_priv);
++ urb->hcpriv = NULL;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+- return -ESHUTDOWN;
++ return ret;
+ }
+
+ /* Get the right ring for the given URB.
diff --git a/queue-3.0/xhci-fix-port-u3-status-check-condition.patch b/queue-3.0/xhci-fix-port-u3-status-check-condition.patch
new file mode 100644
index 0000000000..00cbe8a245
--- /dev/null
+++ b/queue-3.0/xhci-fix-port-u3-status-check-condition.patch
@@ -0,0 +1,34 @@
+From 5ac04bf190e6f8b17238aef179ebd7f2bdfec919 Mon Sep 17 00:00:00 2001
+From: Andiry Xu <andiry.xu@amd.com>
+Date: Wed, 3 Aug 2011 16:46:48 +0800
+Subject: xHCI: fix port U3 status check condition
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+commit 5ac04bf190e6f8b17238aef179ebd7f2bdfec919 upstream.
+
+Fix the port U3 status check when Clear PORT_SUSPEND Feature.
+The port status should be masked with PORT_PLS_MASK to check if it's in
+U3 state.
+
+This should be backported to kernels as old as 2.6.37.
+
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -664,7 +664,7 @@ int xhci_hub_control(struct usb_hcd *hcd
+ xhci_dbg(xhci, "PORTSC %04x\n", temp);
+ if (temp & PORT_RESET)
+ goto error;
+- if (temp & XDEV_U3) {
++ if ((temp & PORT_PLS_MASK) == XDEV_U3) {
+ if ((temp & PORT_PE) == 0)
+ goto error;
+
diff --git a/queue-3.0/xhci-handle-zero-length-isochronous-packets.patch b/queue-3.0/xhci-handle-zero-length-isochronous-packets.patch
new file mode 100644
index 0000000000..78d66d1eea
--- /dev/null
+++ b/queue-3.0/xhci-handle-zero-length-isochronous-packets.patch
@@ -0,0 +1,96 @@
+From 48df4a6fd8c40c0bbcbca2044f5f2bc75dcf6db1 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 12 Aug 2011 10:23:01 -0700
+Subject: xhci: Handle zero-length isochronous packets.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 48df4a6fd8c40c0bbcbca2044f5f2bc75dcf6db1 upstream.
+
+For a long time, the xHCI driver has had this note:
+ /* FIXME: Ignoring zero-length packets, can those happen? */
+
+It turns out that, yes, there are drivers that need to queue zero-length
+transfers for isochronous OUT transfers. Without this patch, users will
+see kernel hang messages when a driver attempts to enqueue an isochronous
+URB with a zero length transfer (because count_isoc_trbs_needed will return
+zero for that TD, xhci_td->last_trb will never be set, and updating the
+dequeue pointer will cause an infinite loop).
+
+Matěj ran into this issue when using an NI Audio4DJ USB soundcard
+with the snd-usb-caiaq driver. See
+ https://bugzilla.kernel.org/show_bug.cgi?id=40702
+
+Fix count_isoc_trbs_needed() to return 1 for zero-length transfers (thanks
+Alan on the math help). Update the various TRB field calculations to deal
+with zero-length transfers. We're still transferring one packet with a
+zero-length data payload, so the total_packet_count should be 1. The
+Transfer Burst Count (TBC) and Transfer Last Burst Packet Count (TLBPC)
+fields should be set to zero.
+
+This patch should be backported to kernels as old as 2.6.36.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Tested-by: Matěj Laitl <matej@laitl.cz>
+Cc: Daniel Mack <zonque@gmail.com>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2692,6 +2692,10 @@ static u32 xhci_v1_0_td_remainder(int ru
+ {
+ int packets_transferred;
+
++ /* One TRB with a zero-length data packet. */
++ if (running_total == 0 && trb_buff_len == 0)
++ return 0;
++
+ /* All the TRB queueing functions don't count the current TRB in
+ * running_total.
+ */
+@@ -3133,20 +3137,15 @@ static int count_isoc_trbs_needed(struct
+ struct urb *urb, int i)
+ {
+ int num_trbs = 0;
+- u64 addr, td_len, running_total;
++ u64 addr, td_len;
+
+ addr = (u64) (urb->transfer_dma + urb->iso_frame_desc[i].offset);
+ td_len = urb->iso_frame_desc[i].length;
+
+- running_total = TRB_MAX_BUFF_SIZE - (addr & (TRB_MAX_BUFF_SIZE - 1));
+- running_total &= TRB_MAX_BUFF_SIZE - 1;
+- if (running_total != 0)
+- num_trbs++;
+-
+- while (running_total < td_len) {
++ num_trbs = DIV_ROUND_UP(td_len + (addr & (TRB_MAX_BUFF_SIZE - 1)),
++ TRB_MAX_BUFF_SIZE);
++ if (num_trbs == 0)
+ num_trbs++;
+- running_total += TRB_MAX_BUFF_SIZE;
+- }
+
+ return num_trbs;
+ }
+@@ -3258,9 +3257,11 @@ static int xhci_queue_isoc_tx(struct xhc
+ addr = start_addr + urb->iso_frame_desc[i].offset;
+ td_len = urb->iso_frame_desc[i].length;
+ td_remain_len = td_len;
+- /* FIXME: Ignoring zero-length packets, can those happen? */
+ total_packet_count = roundup(td_len,
+ le16_to_cpu(urb->ep->desc.wMaxPacketSize));
++ /* A zero-length transfer still involves at least one packet. */
++ if (total_packet_count == 0)
++ total_packet_count++;
+ burst_count = xhci_get_burst_count(xhci, urb->dev, urb,
+ total_packet_count);
+ residue = xhci_get_last_burst_packet_count(xhci,
diff --git a/queue-3.0/xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch b/queue-3.0/xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch
new file mode 100644
index 0000000000..a81fd0ee38
--- /dev/null
+++ b/queue-3.0/xhci-remove-tds-from-td-lists-when-urbs-are-canceled.patch
@@ -0,0 +1,116 @@
+From 585df1d90cb07a02ca6c7a7d339e56e46d50dafb Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 2 Aug 2011 15:43:40 -0700
+Subject: xhci: Remove TDs from TD lists when URBs are canceled.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 585df1d90cb07a02ca6c7a7d339e56e46d50dafb upstream.
+
+When a driver tries to cancel an URB, and the host controller is dying,
+xhci_urb_dequeue will giveback the URB without removing the xhci_tds
+that comprise that URB from the td_list or the cancelled_td_list. This
+can cause a race condition between the driver calling URB dequeue and
+the stop endpoint command watchdog timer.
+
+If the timer fires on a dying host, and a driver attempts to resubmit
+while the watchdog timer has dropped the xhci->lock to giveback a
+cancelled URB, URBs may be given back by the xhci_urb_dequeue() function.
+At that point, the URB's priv pointer will be freed and set to NULL, but
+the TDs will remain on the td_list. This will cause an oops in
+xhci_giveback_urb_in_irq() when the watchdog timer attempts to loop
+through the endpoints' td_lists, giving back killed URBs.
+
+Make sure that xhci_urb_dequeue() removes TDs from the TD lists and
+canceled TD lists before it gives back the URB.
+
+This patch should be backported to kernels as old as 2.6.36.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Cc: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 16 ++++++++--------
+ drivers/usb/host/xhci.c | 7 +++++++
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -744,7 +744,7 @@ remove_finished_td:
+ * so remove it from the endpoint ring's TD list. Keep it in
+ * the cancelled TD list for URB completion later.
+ */
+- list_del(&cur_td->td_list);
++ list_del_init(&cur_td->td_list);
+ }
+ last_unlinked_td = cur_td;
+ xhci_stop_watchdog_timer_in_irq(xhci, ep);
+@@ -772,7 +772,7 @@ remove_finished_td:
+ do {
+ cur_td = list_entry(ep->cancelled_td_list.next,
+ struct xhci_td, cancelled_td_list);
+- list_del(&cur_td->cancelled_td_list);
++ list_del_init(&cur_td->cancelled_td_list);
+
+ /* Clean up the cancelled URB */
+ /* Doesn't matter what we pass for status, since the core will
+@@ -880,9 +880,9 @@ void xhci_stop_endpoint_command_watchdog
+ cur_td = list_first_entry(&ring->td_list,
+ struct xhci_td,
+ td_list);
+- list_del(&cur_td->td_list);
++ list_del_init(&cur_td->td_list);
+ if (!list_empty(&cur_td->cancelled_td_list))
+- list_del(&cur_td->cancelled_td_list);
++ list_del_init(&cur_td->cancelled_td_list);
+ xhci_giveback_urb_in_irq(xhci, cur_td,
+ -ESHUTDOWN, "killed");
+ }
+@@ -891,7 +891,7 @@ void xhci_stop_endpoint_command_watchdog
+ &temp_ep->cancelled_td_list,
+ struct xhci_td,
+ cancelled_td_list);
+- list_del(&cur_td->cancelled_td_list);
++ list_del_init(&cur_td->cancelled_td_list);
+ xhci_giveback_urb_in_irq(xhci, cur_td,
+ -ESHUTDOWN, "killed");
+ }
+@@ -1582,10 +1582,10 @@ td_cleanup:
+ else
+ *status = 0;
+ }
+- list_del(&td->td_list);
++ list_del_init(&td->td_list);
+ /* Was this TD slated to be cancelled but completed anyway? */
+ if (!list_empty(&td->cancelled_td_list))
+- list_del(&td->cancelled_td_list);
++ list_del_init(&td->cancelled_td_list);
+
+ urb_priv->td_cnt++;
+ /* Giveback the urb when all the tds are completed */
+@@ -3370,7 +3370,7 @@ cleanup:
+ /* Clean up a partially enqueued isoc transfer. */
+
+ for (i--; i >= 0; i--)
+- list_del(&urb_priv->td[i]->td_list);
++ list_del_init(&urb_priv->td[i]->td_list);
+
+ /* Use the first TD as a temporary variable to turn the TDs we've queued
+ * into No-ops with a software-owned cycle bit. That way the hardware
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1252,6 +1252,13 @@ int xhci_urb_dequeue(struct usb_hcd *hcd
+ if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
+ xhci_dbg(xhci, "HW died, freeing TD.\n");
+ urb_priv = urb->hcpriv;
++ for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
++ td = urb_priv->td[i];
++ if (!list_empty(&td->td_list))
++ list_del_init(&td->td_list);
++ if (!list_empty(&td->cancelled_td_list))
++ list_del_init(&td->cancelled_td_list);
++ }
+
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&xhci->lock, flags);
diff --git a/queue-3.0/xhci-report-usb2-port-in-resuming-as-suspend.patch b/queue-3.0/xhci-report-usb2-port-in-resuming-as-suspend.patch
new file mode 100644
index 0000000000..8139a95916
--- /dev/null
+++ b/queue-3.0/xhci-report-usb2-port-in-resuming-as-suspend.patch
@@ -0,0 +1,78 @@
+From 8a8ff2f9399b23b968901f585ccb5a70a537c5ae Mon Sep 17 00:00:00 2001
+From: Andiry Xu <andiry.xu@amd.com>
+Date: Wed, 3 Aug 2011 16:46:49 +0800
+Subject: xHCI: report USB2 port in resuming as suspend
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+commit 8a8ff2f9399b23b968901f585ccb5a70a537c5ae upstream.
+
+When a USB2 port initiate a remote wakeup, software shall ensure that
+resume is signaled for at least 20ms, and then write '0' to the PLS field.
+According to this, xhci driver do the following things:
+
+1. When receive a remote wakeup event in irq_handler, set the resume_done
+ value as jiffies + 20ms, and modify rh_timer to poll root hub status at
+ that time;
+2. When receive a GetPortStatus request, if the jiffies is after the
+ resume_done value, clear the resume signal and resume_done.
+
+However, if usb_port_resume() is called before the rh_timer triggered, it
+will indicate the port as Suspend Cleared and skip the clear resume signal
+part. The device will fail the usb_get_status request in finish_port_resume(),
+and usbcore will try a reset-resume instead. Device will work OK after
+reset-resume, but resume_done value is not cleared in this case, and
+xhci_bus_suspend() will fail because when it finds a non-zero resume_done
+value, it will regard the port as resuming and return -EBUSY.
+
+This causes issue on some platforms that the system fail to suspend
+after remote wakeup from suspend by USB2 devices connected to xHCI port.
+
+To fix this issue, report the port status as suspend if the resume is
+signaling less that 20ms, and usb_port_resume() will wait 25ms and check
+port status again, so xHCI driver can clear the resume signaling and
+resume_done value.
+
+This should be backported to kernels as old as 2.6.37.
+
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-hub.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -463,11 +463,12 @@ int xhci_hub_control(struct usb_hcd *hcd
+ && (temp & PORT_POWER))
+ status |= USB_PORT_STAT_SUSPEND;
+ }
+- if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
++ if ((temp & PORT_PLS_MASK) == XDEV_RESUME &&
++ !DEV_SUPERSPEED(temp)) {
+ if ((temp & PORT_RESET) || !(temp & PORT_PE))
+ goto error;
+- if (!DEV_SUPERSPEED(temp) && time_after_eq(jiffies,
+- bus_state->resume_done[wIndex])) {
++ if (time_after_eq(jiffies,
++ bus_state->resume_done[wIndex])) {
+ xhci_dbg(xhci, "Resume USB2 port %d\n",
+ wIndex + 1);
+ bus_state->resume_done[wIndex] = 0;
+@@ -487,6 +488,14 @@ int xhci_hub_control(struct usb_hcd *hcd
+ xhci_ring_device(xhci, slot_id);
+ bus_state->port_c_suspend |= 1 << wIndex;
+ bus_state->suspended_ports &= ~(1 << wIndex);
++ } else {
++ /*
++ * The resume has been signaling for less than
++ * 20ms. Report the port status as SUSPEND,
++ * let the usbcore check port status again
++ * and clear resume signaling later.
++ */
++ status |= USB_PORT_STAT_SUSPEND;
+ }
+ }
+ if ((temp & PORT_PLS_MASK) == XDEV_U0