]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Dec 2013 18:12:33 +0000 (10:12 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Dec 2013 18:12:33 +0000 (10:12 -0800)
added patches:
futex-fix-handling-of-read-only-mapped-hugepages.patch
input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch
iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch
media-af9035-fix-broken-i2c-and-usb-i-o.patch
nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch
pci-disable-bus-master-only-on-kexec-reboot.patch
usb-dwc3-fix-implementation-of-endpoint-wedge.patch
usb-gadget-composite-reset-delayed_status-on-reset_config.patch
usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch
usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch
usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch
usb-option-support-new-huawei-devices.patch
usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch
usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch

15 files changed:
queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch [new file with mode: 0644]
queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch [new file with mode: 0644]
queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch [new file with mode: 0644]
queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch [new file with mode: 0644]
queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch [new file with mode: 0644]
queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch [new file with mode: 0644]
queue-3.12/series
queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch [new file with mode: 0644]
queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch [new file with mode: 0644]
queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch [new file with mode: 0644]
queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch [new file with mode: 0644]
queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch [new file with mode: 0644]
queue-3.12/usb-option-support-new-huawei-devices.patch [new file with mode: 0644]
queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch [new file with mode: 0644]
queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch [new file with mode: 0644]

diff --git a/queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch b/queue-3.12/futex-fix-handling-of-read-only-mapped-hugepages.patch
new file mode 100644 (file)
index 0000000..b903d57
--- /dev/null
@@ -0,0 +1,44 @@
+From f12d5bfceb7e1f9051563381ec047f7f13956c3c Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 12 Dec 2013 09:38:42 -0800
+Subject: futex: fix handling of read-only-mapped hugepages
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit f12d5bfceb7e1f9051563381ec047f7f13956c3c upstream.
+
+The hugepage code had the exact same bug that regular pages had in
+commit 7485d0d3758e ("futexes: Remove rw parameter from
+get_futex_key()").
+
+The regular page case was fixed by commit 9ea71503a8ed ("futex: Fix
+regression with read only mappings"), but the transparent hugepage case
+(added in a5b338f2b0b1: "thp: update futex compound knowledge") case
+remained broken.
+
+Found by Dave Jones and his trinity tool.
+
+Reported-and-tested-by: Dave Jones <davej@fedoraproject.org>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Darren Hart <dvhart@linux.intel.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/futex.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -288,7 +288,7 @@ again:
+               put_page(page);
+               /* serialize against __split_huge_page_splitting() */
+               local_irq_disable();
+-              if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) {
++              if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
+                       page_head = compound_head(page);
+                       /*
+                        * page_head is valid pointer but we must pin
diff --git a/queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch b/queue-3.12/input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch
new file mode 100644 (file)
index 0000000..1b3fb8b
--- /dev/null
@@ -0,0 +1,94 @@
+From 4ef38351d770cc421f4a0c7a849fd13207fc5741 Mon Sep 17 00:00:00 2001
+From: Christian Engelmayer <christian.engelmayer@frequentis.com>
+Date: Tue, 26 Nov 2013 18:16:17 -0800
+Subject: Input: usbtouchscreen - separate report and transmit buffer size handling
+
+From: Christian Engelmayer <christian.engelmayer@frequentis.com>
+
+commit 4ef38351d770cc421f4a0c7a849fd13207fc5741 upstream.
+
+This patch supports the separate handling of the USB transfer buffer length
+and the length of the buffer used for multi packet support. For devices
+supporting multiple report or diagnostic packets, the USB transfer size is now
+limited to the USB endpoints wMaxPacketSize - otherwise it defaults to the
+configured report packet size as before.
+
+This fixes an issue where event reporting can be delayed for an arbitrary
+time for multi packet devices. For instance the report size for eGalax devices
+is defined to the 16 byte maximum diagnostic packet size as opposed to the 5
+byte report packet size. In case the driver requests 16 byte from the USB
+interrupt endpoint, the USB host controller driver needs to split up the
+request into 2 accesses according to the endpoints wMaxPacketSize of 8 byte.
+When the first transfer is answered by the eGalax device with not less than
+the full 8 byte requested, the host controller has got no way of knowing
+whether the touch controller has got additional data queued and will issue
+the second transfer. If per example a liftoff event finishes at such a
+wMaxPacketSize boundary, the data will not be available to the usbtouch driver
+until a further event is triggered and transfered to the host. From user
+perspective the BTN_TOUCH release event in this case is stuck until the next
+touch down event.
+
+Signed-off-by: Christian Engelmayer <christian.engelmayer@frequentis.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/touchscreen/usbtouchscreen.c |   22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/drivers/input/touchscreen/usbtouchscreen.c
++++ b/drivers/input/touchscreen/usbtouchscreen.c
+@@ -106,6 +106,7 @@ struct usbtouch_device_info {
+ struct usbtouch_usb {
+       unsigned char *data;
+       dma_addr_t data_dma;
++      int data_size;
+       unsigned char *buffer;
+       int buf_len;
+       struct urb *irq;
+@@ -1521,7 +1522,7 @@ static int usbtouch_reset_resume(struct
+ static void usbtouch_free_buffers(struct usb_device *udev,
+                                 struct usbtouch_usb *usbtouch)
+ {
+-      usb_free_coherent(udev, usbtouch->type->rept_size,
++      usb_free_coherent(udev, usbtouch->data_size,
+                         usbtouch->data, usbtouch->data_dma);
+       kfree(usbtouch->buffer);
+ }
+@@ -1566,7 +1567,20 @@ static int usbtouch_probe(struct usb_int
+       if (!type->process_pkt)
+               type->process_pkt = usbtouch_process_pkt;
+-      usbtouch->data = usb_alloc_coherent(udev, type->rept_size,
++      usbtouch->data_size = type->rept_size;
++      if (type->get_pkt_len) {
++              /*
++               * When dealing with variable-length packets we should
++               * not request more than wMaxPacketSize bytes at once
++               * as we do not know if there is more data coming or
++               * we filled exactly wMaxPacketSize bytes and there is
++               * nothing else.
++               */
++              usbtouch->data_size = min(usbtouch->data_size,
++                                        usb_endpoint_maxp(endpoint));
++      }
++
++      usbtouch->data = usb_alloc_coherent(udev, usbtouch->data_size,
+                                           GFP_KERNEL, &usbtouch->data_dma);
+       if (!usbtouch->data)
+               goto out_free;
+@@ -1626,12 +1640,12 @@ static int usbtouch_probe(struct usb_int
+       if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
+               usb_fill_int_urb(usbtouch->irq, udev,
+                        usb_rcvintpipe(udev, endpoint->bEndpointAddress),
+-                       usbtouch->data, type->rept_size,
++                       usbtouch->data, usbtouch->data_size,
+                        usbtouch_irq, usbtouch, endpoint->bInterval);
+       else
+               usb_fill_bulk_urb(usbtouch->irq, udev,
+                        usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
+-                       usbtouch->data, type->rept_size,
++                       usbtouch->data, usbtouch->data_size,
+                        usbtouch_irq, usbtouch);
+       usbtouch->irq->dev = udev;
diff --git a/queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch b/queue-3.12/iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch
new file mode 100644 (file)
index 0000000..7eb1dbf
--- /dev/null
@@ -0,0 +1,157 @@
+From 6960a059b2c618f32fe549f13287b3d2278c09e9 Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Date: Mon, 11 Nov 2013 15:23:01 +0200
+Subject: iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
+
+From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+
+commit 6960a059b2c618f32fe549f13287b3d2278c09e9 upstream.
+
+We changed the timeout for the interrupt coealescing for
+calibration, but that wasn't effective since we changed
+that value back before loading the firmware. Since
+calibrations are notification from firmware and not Rx
+packets, this doesn't change anyway - the firmware will
+fire an interrupt straight away regardless of the interrupt
+coalescing value.
+Also, a HW issue has been discovered in 7000 devices series.
+The work around is to disable the new interrupt coalescing
+timeout feature - do this by setting bit 31 in
+CSR_INT_COALESCING.
+This has been fixed in 7265 which means that we can't rely
+on the device family and must have a hint in the iwl_cfg
+structure.
+
+Fixes: 99cd47142399 ("iwlwifi: add 7000 series device configuration")
+Reviewed-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-7000.c   |    7 +++++++
+ drivers/net/wireless/iwlwifi/iwl-config.h |    3 +++
+ drivers/net/wireless/iwlwifi/iwl-csr.h    |    5 +----
+ drivers/net/wireless/iwlwifi/pcie/rx.c    |    4 ++++
+ drivers/net/wireless/iwlwifi/pcie/trans.c |    3 ---
+ 5 files changed, 15 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
+@@ -125,6 +125,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL7260_NVM_VERSION,
+       .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
+@@ -135,6 +136,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_hig
+       .nvm_ver = IWL7260_NVM_VERSION,
+       .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
+       .high_temp = true,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl7260_2n_cfg = {
+@@ -144,6 +146,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL7260_NVM_VERSION,
+       .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl7260_n_cfg = {
+@@ -153,6 +156,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL7260_NVM_VERSION,
+       .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl3160_2ac_cfg = {
+@@ -162,6 +166,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL3160_NVM_VERSION,
+       .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl3160_2n_cfg = {
+@@ -171,6 +176,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL3160_NVM_VERSION,
+       .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ const struct iwl_cfg iwl3160_n_cfg = {
+@@ -180,6 +186,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
+       .ht_params = &iwl7000_ht_params,
+       .nvm_ver = IWL3160_NVM_VERSION,
+       .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
++      .host_interrupt_operation_mode = true,
+ };
+ MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
+--- a/drivers/net/wireless/iwlwifi/iwl-config.h
++++ b/drivers/net/wireless/iwlwifi/iwl-config.h
+@@ -207,6 +207,8 @@ struct iwl_eeprom_params {
+  * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
+  * @internal_wimax_coex: internal wifi/wimax combo device
+  * @high_temp: Is this NIC is designated to be in high temperature.
++ * @host_interrupt_operation_mode: device needs host interrupt operation
++ *    mode set
+  *
+  * We enable the driver to be backward compatible wrt. hardware features.
+  * API differences in uCode shouldn't be handled here but through TLVs
+@@ -235,6 +237,7 @@ struct iwl_cfg {
+       enum iwl_led_mode led_mode;
+       const bool rx_with_siso_diversity;
+       const bool internal_wimax_coex;
++      const bool host_interrupt_operation_mode;
+       bool high_temp;
+ };
+--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
++++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
+@@ -463,14 +463,11 @@
+  * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
+  *
+  * default interrupt coalescing timer is 64 x 32 = 2048 usecs
+- * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
+  */
+ #define IWL_HOST_INT_TIMEOUT_MAX      (0xFF)
+ #define IWL_HOST_INT_TIMEOUT_DEF      (0x40)
+ #define IWL_HOST_INT_TIMEOUT_MIN      (0x0)
+-#define IWL_HOST_INT_CALIB_TIMEOUT_MAX        (0xFF)
+-#define IWL_HOST_INT_CALIB_TIMEOUT_DEF        (0x10)
+-#define IWL_HOST_INT_CALIB_TIMEOUT_MIN        (0x0)
++#define IWL_HOST_INT_OPER_MODE                BIT(31)
+ /*****************************************************************************
+  *                        7000/3000 series SHR DTS addresses                 *
+--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
+@@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct i
+       /* Set interrupt coalescing timer to default (2048 usecs) */
+       iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
++
++      /* W/A for interrupt coalescing bug in 7260 and 3160 */
++      if (trans->cfg->host_interrupt_operation_mode)
++              iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE);
+ }
+ static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
+--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
+@@ -276,9 +276,6 @@ static int iwl_pcie_nic_init(struct iwl_
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
+       iwl_pcie_apm_init(trans);
+-      /* Set interrupt coalescing calibration timer to default (512 usecs) */
+-      iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
+-
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
+       iwl_pcie_set_pwr(trans, false);
diff --git a/queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch b/queue-3.12/media-af9035-fix-broken-i2c-and-usb-i-o.patch
new file mode 100644 (file)
index 0000000..301dc5e
--- /dev/null
@@ -0,0 +1,53 @@
+From 9323297dc0ea9141f8099e474657391bb3ad98f8 Mon Sep 17 00:00:00 2001
+From: Antti Palosaari <crope@iki.fi>
+Date: Wed, 27 Nov 2013 17:23:00 -0300
+Subject: media: af9035: fix broken I2C and USB I/O
+
+From: Antti Palosaari <crope@iki.fi>
+
+commit 9323297dc0ea9141f8099e474657391bb3ad98f8 upstream.
+
+There was three small buffer len calculation bugs which caused
+driver non-working. These are coming from recent commit:
+commit 7760e148350bf6df95662bc0db3734e9d991cb03
+[media] af9035: Don't use dynamic static allocation
+
+Signed-off-by: Antti Palosaari <crope@iki.fi>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/media/usb/dvb-usb-v2/af9035.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/media/usb/dvb-usb-v2/af9035.c
++++ b/drivers/media/usb/dvb-usb-v2/af9035.c
+@@ -131,7 +131,7 @@ static int af9035_wr_regs(struct dvb_usb
+ {
+       u8 wbuf[MAX_XFER_SIZE];
+       u8 mbox = (reg >> 16) & 0xff;
+-      struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
++      struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
+       if (6 + len > sizeof(wbuf)) {
+               dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n",
+@@ -238,7 +238,7 @@ static int af9035_i2c_master_xfer(struct
+               } else {
+                       /* I2C */
+                       u8 buf[MAX_XFER_SIZE];
+-                      struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
++                      struct usb_req req = { CMD_I2C_RD, 0, 5 + msg[0].len,
+                                       buf, msg[1].len, msg[1].buf };
+                       if (5 + msg[0].len > sizeof(buf)) {
+@@ -274,8 +274,8 @@ static int af9035_i2c_master_xfer(struct
+               } else {
+                       /* I2C */
+                       u8 buf[MAX_XFER_SIZE];
+-                      struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
+-                                      0, NULL };
++                      struct usb_req req = { CMD_I2C_WR, 0, 5 + msg[0].len,
++                                      buf, 0, NULL };
+                       if (5 + msg[0].len > sizeof(buf)) {
+                               dev_warn(&d->udev->dev,
diff --git a/queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch b/queue-3.12/nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch
new file mode 100644 (file)
index 0000000..1966830
--- /dev/null
@@ -0,0 +1,59 @@
+From 781c2a5a5f75eacc04663aced0f0f1a648d4f308 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Mon, 2 Dec 2013 15:26:19 -0500
+Subject: nfsd: when reusing an existing repcache entry, unhash it first
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 781c2a5a5f75eacc04663aced0f0f1a648d4f308 upstream.
+
+The DRC code will attempt to reuse an existing, expired cache entry in
+preference to allocating a new one. It'll then search the cache, and if
+it gets a hit it'll then free the cache entry that it was going to
+reuse.
+
+The cache code doesn't unhash the entry that it's going to reuse
+however, so it's possible for it end up designating an entry for reuse
+and then subsequently freeing the same entry after it finds it.  This
+leads it to a later use-after-free situation and usually some list
+corruption warnings or an oops.
+
+Fix this by simply unhashing the entry that we intend to reuse. That
+will mean that it's not findable via a search and should prevent this
+situation from occurring.
+
+Reported-by: Christoph Hellwig <hch@infradead.org>
+Reported-by: g. artim <gartim@gmail.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfscache.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/nfsd/nfscache.c
++++ b/fs/nfsd/nfscache.c
+@@ -132,6 +132,13 @@ nfsd_reply_cache_alloc(void)
+ }
+ static void
++nfsd_reply_cache_unhash(struct svc_cacherep *rp)
++{
++      hlist_del_init(&rp->c_hash);
++      list_del_init(&rp->c_lru);
++}
++
++static void
+ nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
+ {
+       if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) {
+@@ -417,7 +424,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp
+               rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
+               if (nfsd_cache_entry_expired(rp) ||
+                   num_drc_entries >= max_drc_entries) {
+-                      lru_put_end(rp);
++                      nfsd_reply_cache_unhash(rp);
+                       prune_cache_entries();
+                       goto search_cache;
+               }
diff --git a/queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch b/queue-3.12/pci-disable-bus-master-only-on-kexec-reboot.patch
new file mode 100644 (file)
index 0000000..0df05f4
--- /dev/null
@@ -0,0 +1,97 @@
+From 4fc9bbf98fd66f879e628d8537ba7c240be2b58e Mon Sep 17 00:00:00 2001
+From: Khalid Aziz <khalid.aziz@oracle.com>
+Date: Wed, 27 Nov 2013 15:19:25 -0700
+Subject: PCI: Disable Bus Master only on kexec reboot
+
+From: Khalid Aziz <khalid.aziz@oracle.com>
+
+commit 4fc9bbf98fd66f879e628d8537ba7c240be2b58e upstream.
+
+Add a flag to tell the PCI subsystem that kernel is shutting down in
+preparation to kexec a kernel.  Add code in PCI subsystem to use this flag
+to clear Bus Master bit on PCI devices only in case of kexec reboot.
+
+This fixes a power-off problem on Acer Aspire V5-573G and likely other
+machines and avoids any other issues caused by clearing Bus Master bit on
+PCI devices in normal shutdown path.  The problem was introduced by
+b566a22c2332 ("PCI: disable Bus Master on PCI device shutdown").
+
+This patch is based on discussion at
+http://marc.info/?l=linux-pci&m=138425645204355&w=2
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=63861
+Reported-by: Chang Liu <cl91tp@gmail.com>
+Signed-off-by: Khalid Aziz <khalid.aziz@oracle.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Konstantin Khlebnikov <koct9i@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pci-driver.c |   12 +++++++++---
+ include/linux/kexec.h    |    3 +++
+ kernel/kexec.c           |    4 ++++
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/pci/pci-driver.c
++++ b/drivers/pci/pci-driver.c
+@@ -19,6 +19,7 @@
+ #include <linux/cpu.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/suspend.h>
++#include <linux/kexec.h>
+ #include "pci.h"
+ struct pci_dynid {
+@@ -388,12 +389,17 @@ static void pci_device_shutdown(struct d
+       pci_msi_shutdown(pci_dev);
+       pci_msix_shutdown(pci_dev);
++#ifdef CONFIG_KEXEC
+       /*
+-       * Turn off Bus Master bit on the device to tell it to not
+-       * continue to do DMA. Don't touch devices in D3cold or unknown states.
++       * If this is a kexec reboot, turn off Bus Master bit on the
++       * device to tell it to not continue to do DMA. Don't touch
++       * devices in D3cold or unknown states.
++       * If it is not a kexec reboot, firmware will hit the PCI
++       * devices with big hammer and stop their DMA any way.
+        */
+-      if (pci_dev->current_state <= PCI_D3hot)
++      if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot))
+               pci_clear_master(pci_dev);
++#endif
+ }
+ #ifdef CONFIG_PM
+--- a/include/linux/kexec.h
++++ b/include/linux/kexec.h
+@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NO
+ extern size_t vmcoreinfo_size;
+ extern size_t vmcoreinfo_max_size;
++/* flag to track if kexec reboot is in progress */
++extern bool kexec_in_progress;
++
+ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
+               unsigned long long *crash_size, unsigned long long *crash_base);
+ int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
+--- a/kernel/kexec.c
++++ b/kernel/kexec.c
+@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE
+ size_t vmcoreinfo_size;
+ size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
++/* Flag to indicate we are going to kexec a new kernel */
++bool kexec_in_progress = false;
++
+ /* Location of the reserved area for the crash kernel */
+ struct resource crashk_res = {
+       .name  = "Crash kernel",
+@@ -1675,6 +1678,7 @@ int kernel_kexec(void)
+       } else
+ #endif
+       {
++              kexec_in_progress = true;
+               kernel_restart_prepare(NULL);
+               printk(KERN_EMERG "Starting new kernel\n");
+               machine_shutdown();
index 2ed04e8205d076cb37f75116203777ea7d6d1a98..a3e3149823b39e13ebd295274443e1d1ed2d83b8 100644 (file)
@@ -23,3 +23,17 @@ hwmon-w83l786ng-fix-fan-speed-control-mode-setting-and-reporting.patch
 hwmon-w83l768ng-fix-fan-speed-control-range.patch
 xfs-growfs-overruns-agfl-buffer-on-v4-filesystems.patch
 xfs-underflow-bug-in-xfs_attrlist_by_handle.patch
+iwlwifi-pcie-fix-interrupt-coalescing-for-7260-3160.patch
+pci-disable-bus-master-only-on-kexec-reboot.patch
+futex-fix-handling-of-read-only-mapped-hugepages.patch
+nfsd-when-reusing-an-existing-repcache-entry-unhash-it-first.patch
+usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch
+usb-dwc3-fix-implementation-of-endpoint-wedge.patch
+usb-gadget-composite-reset-delayed_status-on-reset_config.patch
+usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch
+usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch
+usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch
+usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch
+usb-option-support-new-huawei-devices.patch
+input-usbtouchscreen-separate-report-and-transmit-buffer-size-handling.patch
+media-af9035-fix-broken-i2c-and-usb-i-o.patch
diff --git a/queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch b/queue-3.12/usb-dwc3-fix-implementation-of-endpoint-wedge.patch
new file mode 100644 (file)
index 0000000..8643130
--- /dev/null
@@ -0,0 +1,58 @@
+From a535d81c92615b8ffb99b7e1fd1fb01effaed1af Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 1 Nov 2013 12:05:12 -0400
+Subject: usb: dwc3: fix implementation of endpoint wedge
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit a535d81c92615b8ffb99b7e1fd1fb01effaed1af upstream.
+
+The dwc3 UDC driver doesn't implement endpoint wedging correctly.
+When an endpoint is wedged, the gadget driver should be allowed to
+clear the wedge by calling usb_ep_clear_halt().  Only the host is
+prevented from resetting the endpoint.
+
+This patch fixes the implementation.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Pratyush Anand <pratyush.anand@st.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/dwc3/ep0.c    |    2 ++
+ drivers/usb/dwc3/gadget.c |    5 +----
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -459,6 +459,8 @@ static int dwc3_ep0_handle_feature(struc
+                       dep = dwc3_wIndex_to_dep(dwc, wIndex);
+                       if (!dep)
+                               return -EINVAL;
++                      if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
++                              break;
+                       ret = __dwc3_gadget_ep_set_halt(dep, set);
+                       if (ret)
+                               return -EINVAL;
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1200,9 +1200,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc
+               else
+                       dep->flags |= DWC3_EP_STALL;
+       } else {
+-              if (dep->flags & DWC3_EP_WEDGE)
+-                      return 0;
+-
+               ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
+                       DWC3_DEPCMD_CLEARSTALL, &params);
+               if (ret)
+@@ -1210,7 +1207,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc
+                                       value ? "set" : "clear",
+                                       dep->name);
+               else
+-                      dep->flags &= ~DWC3_EP_STALL;
++                      dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE);
+       }
+       return ret;
diff --git a/queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch b/queue-3.12/usb-gadget-composite-reset-delayed_status-on-reset_config.patch
new file mode 100644 (file)
index 0000000..3c83ad7
--- /dev/null
@@ -0,0 +1,32 @@
+From 2bac51a1827a18821150ed8c9f9752c02f9c2b02 Mon Sep 17 00:00:00 2001
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Date: Mon, 11 Nov 2013 23:43:32 +0100
+Subject: usb: gadget: composite: reset delayed_status on reset_config
+
+From: Michael Grzeschik <m.grzeschik@pengutronix.de>
+
+commit 2bac51a1827a18821150ed8c9f9752c02f9c2b02 upstream.
+
+The delayed_status value is used to keep track of status response
+packets on ep0. It needs to be reset or the set_config function would
+still delay the answer, if the usb device got unplugged while waiting
+for setup_continue to be called.
+
+Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/composite.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -593,6 +593,7 @@ static void reset_config(struct usb_comp
+               bitmap_zero(f->endpoints, 32);
+       }
+       cdev->config = NULL;
++      cdev->delayed_status = 0;
+ }
+ static int set_config(struct usb_composite_dev *cdev,
diff --git a/queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch b/queue-3.12/usb-hub-use-correct-reset-for-wedged-usb3-devices-that-are-notattached.patch
new file mode 100644 (file)
index 0000000..dcd84f8
--- /dev/null
@@ -0,0 +1,37 @@
+From 2d51f3cd11f414c56a87dc018196b85fd50b04a4 Mon Sep 17 00:00:00 2001
+From: Julius Werner <jwerner@chromium.org>
+Date: Thu, 7 Nov 2013 10:59:14 -0800
+Subject: usb: hub: Use correct reset for wedged USB3 devices that are NOTATTACHED
+
+From: Julius Werner <jwerner@chromium.org>
+
+commit 2d51f3cd11f414c56a87dc018196b85fd50b04a4 upstream.
+
+This patch adds a check for USB_STATE_NOTATTACHED to the
+hub_port_warm_reset_required() workaround for ports that end up in
+Compliance Mode in hub_events() when trying to decide which reset
+function to use. Trying to call usb_reset_device() with a NOTATTACHED
+device will just fail and leave the port broken.
+
+Signed-off-by: Julius Werner <jwerner@chromium.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4836,8 +4836,9 @@ static void hub_events(void)
+                                       hub->ports[i - 1]->child;
+                               dev_dbg(hub_dev, "warm reset port %d\n", i);
+-                              if (!udev || !(portstatus &
+-                                              USB_PORT_STAT_CONNECTION)) {
++                              if (!udev ||
++                                  !(portstatus & USB_PORT_STAT_CONNECTION) ||
++                                  udev->state == USB_STATE_NOTATTACHED) {
+                                       status = hub_port_reset(hub, i,
+                                                       NULL, HUB_BH_RESET_TIME,
+                                                       true);
diff --git a/queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch b/queue-3.12/usb-musb-musb_cppi41-factor-most-of-cppi41_dma_callback-into-cppi41_trans_done.patch
new file mode 100644 (file)
index 0000000..2f7789c
--- /dev/null
@@ -0,0 +1,114 @@
+From d373a8534d5e1e7a350e40d3c11961a7cd8d530b Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 12 Nov 2013 16:37:46 +0100
+Subject: usb: musb: musb_cppi41: factor most of cppi41_dma_callback() into cppi41_trans_done()
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit d373a8534d5e1e7a350e40d3c11961a7cd8d530b upstream.
+
+This patch moves most of the logic in cppi41_dma_callback() into
+cppi41_trans_done() where it can be called from another function.
+Instead of computing "transferred" (the number of bytes transferred in
+the last transaction) in cppi41_trans_done() the member
+"cppi41_channel->prog_len" is now set to 0 if the transfer as a whole
+can be considered as done. If it is != 0 then the next iteration is
+assumed.
+This is a preparation for a workaround.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_cppi41.c |   59 +++++++++++++++++++++++++----------------
+ 1 file changed, 36 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/musb/musb_cppi41.c
++++ b/drivers/usb/musb/musb_cppi41.c
+@@ -96,31 +96,15 @@ static void update_rx_toggle(struct cppi
+       cppi41_channel->usb_toggle = toggle;
+ }
+-static void cppi41_dma_callback(void *private_data)
++static void cppi41_dma_callback(void *private_data);
++
++static void cppi41_trans_done(struct dma_channel *channel)
+ {
+-      struct dma_channel *channel = private_data;
+       struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+       struct musb *musb = hw_ep->musb;
+-      unsigned long flags;
+-      struct dma_tx_state txstate;
+-      u32 transferred;
+-      spin_lock_irqsave(&musb->lock, flags);
+-
+-      dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
+-                      &txstate);
+-      transferred = cppi41_channel->prog_len - txstate.residue;
+-      cppi41_channel->transferred += transferred;
+-
+-      dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
+-              hw_ep->epnum, cppi41_channel->transferred,
+-              cppi41_channel->total_len);
+-
+-      update_rx_toggle(cppi41_channel);
+-
+-      if (cppi41_channel->transferred == cppi41_channel->total_len ||
+-                      transferred < cppi41_channel->packet_sz) {
++      if (!cppi41_channel->prog_len) {
+               /* done, complete */
+               cppi41_channel->channel.actual_len =
+@@ -150,10 +134,8 @@ static void cppi41_dma_callback(void *pr
+                               remain_bytes,
+                               direction,
+                               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+-              if (WARN_ON(!dma_desc)) {
+-                      spin_unlock_irqrestore(&musb->lock, flags);
++              if (WARN_ON(!dma_desc))
+                       return;
+-              }
+               dma_desc->callback = cppi41_dma_callback;
+               dma_desc->callback_param = channel;
+@@ -166,6 +148,37 @@ static void cppi41_dma_callback(void *pr
+                       musb_writew(epio, MUSB_RXCSR, csr);
+               }
+       }
++}
++
++static void cppi41_dma_callback(void *private_data)
++{
++      struct dma_channel *channel = private_data;
++      struct cppi41_dma_channel *cppi41_channel = channel->private_data;
++      struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
++      struct musb *musb = hw_ep->musb;
++      unsigned long flags;
++      struct dma_tx_state txstate;
++      u32 transferred;
++
++      spin_lock_irqsave(&musb->lock, flags);
++
++      dmaengine_tx_status(cppi41_channel->dc, cppi41_channel->cookie,
++                      &txstate);
++      transferred = cppi41_channel->prog_len - txstate.residue;
++      cppi41_channel->transferred += transferred;
++
++      dev_dbg(musb->controller, "DMA transfer done on hw_ep=%d bytes=%d/%d\n",
++              hw_ep->epnum, cppi41_channel->transferred,
++              cppi41_channel->total_len);
++
++      update_rx_toggle(cppi41_channel);
++
++      if (cppi41_channel->transferred == cppi41_channel->total_len ||
++                      transferred < cppi41_channel->packet_sz)
++              cppi41_channel->prog_len = 0;
++
++      cppi41_trans_done(channel);
++
+       spin_unlock_irqrestore(&musb->lock, flags);
+ }
diff --git a/queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch b/queue-3.12/usb-musb-musb_cppi41-handle-pre-mature-tx-complete-interrupt.patch
new file mode 100644 (file)
index 0000000..f7beb1d
--- /dev/null
@@ -0,0 +1,268 @@
+From a655f481d83d6d37bec0a2ddfdd24c30ff8f541f Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 12 Nov 2013 16:37:47 +0100
+Subject: usb: musb: musb_cppi41: handle pre-mature TX complete interrupt
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit a655f481d83d6d37bec0a2ddfdd24c30ff8f541f upstream.
+
+The TX-complete interrupt of the CPPI41 on AM335x fires too early.
+Adding a loop and counting how long it takes until the
+MUSB_TXCSR_TXPKTRDY bit is cleared I see
+FS:
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadc54002, len=1514 is_tx=1
+|cppi41_dma_callback() 74 loops
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8802, len=1514 is_tx=1
+|cppi41_dma_callback() 66 loops
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadcd8002, len=1514 is_tx=1
+|cppi41_dma_callback() 136 loops
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=64, mode=0, dma_addr=0xadf55802, len=1514 is_tx=1
+|cppi41_dma_callback() 136 loops
+
+avg: 110 - 150us
+
+HS:
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xaca6f002, len=1514 is_tx=1
+|cppi41_dma_callback() 0 loops
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f802, len=1514 is_tx=1
+|cppi41_dma_callback() 2 loops
+|musb-hdrc musb-hdrc.0.auto: configure ep1/80 packet_sz=512, mode=0, dma_addr=0xadd6f002, len=1514 is_tx=1
+|cppi41_dma_callback() 13 loops
+
+avg: 2us
+
+for the same test case. One loop means a udelay(1). The delay seems to
+depend on the packet size. On HS the bit is always cleared for small
+packet sizes while on FS it is never the case, it mostly around 110us.
+This testing has been performed with g_ether (musb as device) and using BULK
+transfers.
+
+INTR transfers are way more fun: during init the gadget sends a INT
+packet to the host and cppi41 says "transfer done" shortly after. The
+MUSB_TXCSR_TXPKTRDY bit is set even seconds later. The reason is that the host
+did not try to receive it, it does so after the interface (on host side) has
+been configured. Until this happens, that packet remains in musb's FIFO.
+
+To fix this, two things are done:
+- No DMA transfers for INT based endpoints. These transfer are usually
+  very small and rare so it is likely better to skip the DMA engine and
+  stuff the four bytes directly into the FIFO
+- on HS we poll up to 25us and hope that bit goes away. If not we setup
+  a hrtimer to poll for it. The 140us delay is a rule of thumb. In FS
+  the command
+  | ping 10.10.10.10 -c1 -s65130
+  creates about 44 1514bytes transfers. About 19 of them need a second
+  timer to complete.
+
+Reported-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_cppi41.c |  113 +++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 108 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/musb/musb_cppi41.c
++++ b/drivers/usb/musb/musb_cppi41.c
+@@ -38,6 +38,7 @@ struct cppi41_dma_channel {
+       u32 prog_len;
+       u32 transferred;
+       u32 packet_sz;
++      struct list_head tx_check;
+ };
+ #define MUSB_DMA_NUM_CHANNELS 15
+@@ -47,6 +48,8 @@ struct cppi41_dma_controller {
+       struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
+       struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
+       struct musb *musb;
++      struct hrtimer early_tx;
++      struct list_head early_tx_list;
+       u32 rx_mode;
+       u32 tx_mode;
+       u32 auto_req;
+@@ -96,11 +99,23 @@ static void update_rx_toggle(struct cppi
+       cppi41_channel->usb_toggle = toggle;
+ }
++static bool musb_is_tx_fifo_empty(struct musb_hw_ep *hw_ep)
++{
++      u8              epnum = hw_ep->epnum;
++      struct musb     *musb = hw_ep->musb;
++      void __iomem    *epio = musb->endpoints[epnum].regs;
++      u16             csr;
++
++      csr = musb_readw(epio, MUSB_TXCSR);
++      if (csr & MUSB_TXCSR_TXPKTRDY)
++              return false;
++      return true;
++}
++
+ static void cppi41_dma_callback(void *private_data);
+-static void cppi41_trans_done(struct dma_channel *channel)
++static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
+ {
+-      struct cppi41_dma_channel *cppi41_channel = channel->private_data;
+       struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
+       struct musb *musb = hw_ep->musb;
+@@ -138,7 +153,7 @@ static void cppi41_trans_done(struct dma
+                       return;
+               dma_desc->callback = cppi41_dma_callback;
+-              dma_desc->callback_param = channel;
++              dma_desc->callback_param = &cppi41_channel->channel;
+               cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
+               dma_async_issue_pending(dc);
+@@ -150,6 +165,41 @@ static void cppi41_trans_done(struct dma
+       }
+ }
++static enum hrtimer_restart cppi41_recheck_tx_req(struct hrtimer *timer)
++{
++      struct cppi41_dma_controller *controller;
++      struct cppi41_dma_channel *cppi41_channel, *n;
++      struct musb *musb;
++      unsigned long flags;
++      enum hrtimer_restart ret = HRTIMER_NORESTART;
++
++      controller = container_of(timer, struct cppi41_dma_controller,
++                      early_tx);
++      musb = controller->musb;
++
++      spin_lock_irqsave(&musb->lock, flags);
++      list_for_each_entry_safe(cppi41_channel, n, &controller->early_tx_list,
++                      tx_check) {
++              bool empty;
++              struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep;
++
++              empty = musb_is_tx_fifo_empty(hw_ep);
++              if (empty) {
++                      list_del_init(&cppi41_channel->tx_check);
++                      cppi41_trans_done(cppi41_channel);
++              }
++      }
++
++      if (!list_empty(&controller->early_tx_list)) {
++              ret = HRTIMER_RESTART;
++              hrtimer_forward_now(&controller->early_tx,
++                              ktime_set(0, 150 * NSEC_PER_USEC));
++      }
++
++      spin_unlock_irqrestore(&musb->lock, flags);
++      return ret;
++}
++
+ static void cppi41_dma_callback(void *private_data)
+ {
+       struct dma_channel *channel = private_data;
+@@ -159,6 +209,7 @@ static void cppi41_dma_callback(void *pr
+       unsigned long flags;
+       struct dma_tx_state txstate;
+       u32 transferred;
++      bool empty;
+       spin_lock_irqsave(&musb->lock, flags);
+@@ -177,8 +228,52 @@ static void cppi41_dma_callback(void *pr
+                       transferred < cppi41_channel->packet_sz)
+               cppi41_channel->prog_len = 0;
+-      cppi41_trans_done(channel);
+-
++      empty = musb_is_tx_fifo_empty(hw_ep);
++      if (empty) {
++              cppi41_trans_done(cppi41_channel);
++      } else {
++              struct cppi41_dma_controller *controller;
++              /*
++               * On AM335x it has been observed that the TX interrupt fires
++               * too early that means the TXFIFO is not yet empty but the DMA
++               * engine says that it is done with the transfer. We don't
++               * receive a FIFO empty interrupt so the only thing we can do is
++               * to poll for the bit. On HS it usually takes 2us, on FS around
++               * 110us - 150us depending on the transfer size.
++               * We spin on HS (no longer than than 25us and setup a timer on
++               * FS to check for the bit and complete the transfer.
++               */
++              controller = cppi41_channel->controller;
++
++              if (musb->g.speed == USB_SPEED_HIGH) {
++                      unsigned wait = 25;
++
++                      do {
++                              empty = musb_is_tx_fifo_empty(hw_ep);
++                              if (empty)
++                                      break;
++                              wait--;
++                              if (!wait)
++                                      break;
++                              udelay(1);
++                      } while (1);
++
++                      empty = musb_is_tx_fifo_empty(hw_ep);
++                      if (empty) {
++                              cppi41_trans_done(cppi41_channel);
++                              goto out;
++                      }
++              }
++              list_add_tail(&cppi41_channel->tx_check,
++                              &controller->early_tx_list);
++              if (!hrtimer_active(&controller->early_tx)) {
++                      hrtimer_start_range_ns(&controller->early_tx,
++                              ktime_set(0, 140 * NSEC_PER_USEC),
++                              40 * NSEC_PER_USEC,
++                              HRTIMER_MODE_REL);
++              }
++      }
++out:
+       spin_unlock_irqrestore(&musb->lock, flags);
+ }
+@@ -377,6 +472,8 @@ static int cppi41_is_compatible(struct d
+               WARN_ON(1);
+               return 1;
+       }
++      if (cppi41_channel->hw_ep->ep_in.type != USB_ENDPOINT_XFER_BULK)
++              return 0;
+       if (cppi41_channel->is_tx)
+               return 1;
+       /* AM335x Advisory 1.0.13. No workaround for device RX mode */
+@@ -401,6 +498,7 @@ static int cppi41_dma_channel_abort(stru
+       if (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)
+               return 0;
++      list_del_init(&cppi41_channel->tx_check);
+       if (is_tx) {
+               csr = musb_readw(epio, MUSB_TXCSR);
+               csr &= ~MUSB_TXCSR_DMAENAB;
+@@ -507,6 +605,7 @@ static int cppi41_dma_controller_start(s
+               cppi41_channel->controller = controller;
+               cppi41_channel->port_num = port;
+               cppi41_channel->is_tx = is_tx;
++              INIT_LIST_HEAD(&cppi41_channel->tx_check);
+               musb_dma = &cppi41_channel->channel;
+               musb_dma->private_data = cppi41_channel;
+@@ -531,6 +630,7 @@ void dma_controller_destroy(struct dma_c
+       struct cppi41_dma_controller *controller = container_of(c,
+                       struct cppi41_dma_controller, controller);
++      hrtimer_cancel(&controller->early_tx);
+       cppi41_dma_controller_stop(controller);
+       kfree(controller);
+ }
+@@ -550,6 +650,9 @@ struct dma_controller *dma_controller_cr
+       if (!controller)
+               goto kzalloc_fail;
++      hrtimer_init(&controller->early_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++      controller->early_tx.function = cppi41_recheck_tx_req;
++      INIT_LIST_HEAD(&controller->early_tx_list);
+       controller->musb = musb;
+       controller->controller.channel_alloc = cppi41_dma_channel_allocate;
diff --git a/queue-3.12/usb-option-support-new-huawei-devices.patch b/queue-3.12/usb-option-support-new-huawei-devices.patch
new file mode 100644 (file)
index 0000000..f0f76c2
--- /dev/null
@@ -0,0 +1,87 @@
+From 2bf308d7bc5e8cdd69672199f59532f35339133c Mon Sep 17 00:00:00 2001
+From: "Fangxiaozhi (Franko)" <fangxiaozhi@huawei.com>
+Date: Mon, 2 Dec 2013 09:00:11 +0000
+Subject: USB: option: support new huawei devices
+
+From: "Fangxiaozhi (Franko)" <fangxiaozhi@huawei.com>
+
+commit 2bf308d7bc5e8cdd69672199f59532f35339133c upstream.
+
+Add new supporting declarations to option.c, to support Huawei new
+devices with new bInterfaceProtocol value.
+
+Signed-off-by: fangxiaozhi <huananhu@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |   24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -637,6 +637,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) },
+@@ -691,6 +695,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) },
+@@ -745,6 +753,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x03, 0x7A) },
+@@ -799,6 +811,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x04, 0x7A) },
+@@ -853,6 +869,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x05, 0x7A) },
+@@ -907,6 +927,10 @@ static const struct usb_device_id option
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6D) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6E) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x6F) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x72) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x73) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x74) },
++      { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x75) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x78) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x79) },
+       { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x06, 0x7A) },
diff --git a/queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch b/queue-3.12/usb-serial-option-blacklist-interface-1-for-huawei-e173s-6.patch
new file mode 100644 (file)
index 0000000..a4beba3
--- /dev/null
@@ -0,0 +1,43 @@
+From 8f173e22abf2258ddfa73f46eadbb6a6c29f1631 Mon Sep 17 00:00:00 2001
+From: Gustavo Zacarias <gustavo@zacarias.com.ar>
+Date: Mon, 11 Nov 2013 09:59:15 -0300
+Subject: USB: serial: option: blacklist interface 1 for Huawei E173s-6
+
+From: Gustavo Zacarias <gustavo@zacarias.com.ar>
+
+commit 8f173e22abf2258ddfa73f46eadbb6a6c29f1631 upstream.
+
+Interface 1 on this device isn't for option to bind to otherwise an oops
+on usb_wwan with log flooding will happen when accessing the port:
+
+tty_release: ttyUSB1: read/write wait queue active!
+
+It doesn't seem to respond to QMI if it's added to qmi_wwan so don't add
+it there - it's likely used by the card reader.
+
+Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -85,6 +85,7 @@ static void option_instat_callback(struc
+ #define HUAWEI_PRODUCT_K4505                  0x1464
+ #define HUAWEI_PRODUCT_K3765                  0x1465
+ #define HUAWEI_PRODUCT_K4605                  0x14C6
++#define HUAWEI_PRODUCT_E173S6                 0x1C07
+ #define QUANTA_VENDOR_ID                      0x0408
+ #define QUANTA_PRODUCT_Q101                   0xEA02
+@@ -572,6 +573,8 @@ static const struct usb_device_id option
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
+               .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
++      { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff),
++              .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff),
+               .driver_info = (kernel_ulong_t) &net_intf2_blacklist },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) },
diff --git a/queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch b/queue-3.12/usb-xhci-link-trb-must-not-occur-within-a-usb-payload-burst.patch
new file mode 100644 (file)
index 0000000..696d7c6
--- /dev/null
@@ -0,0 +1,135 @@
+From 35773dac5f862cb1c82ea151eba3e2f6de51ec3e Mon Sep 17 00:00:00 2001
+From: David Laight <David.Laight@ACULAB.COM>
+Date: Mon, 11 Nov 2013 12:26:54 +0000
+Subject: usb: xhci: Link TRB must not occur within a USB payload burst
+
+From: David Laight <David.Laight@ACULAB.COM>
+
+commit 35773dac5f862cb1c82ea151eba3e2f6de51ec3e upstream.
+
+Section 4.11.7.1 of rev 1.0 of the xhci specification states that a link TRB
+can only occur at a boundary between underlying USB frames (512 bytes for
+high speed devices).
+
+If this isn't done the USB frames aren't formatted correctly and, for example,
+the USB3 ethernet ax88179_178a card will stop sending (while still receiving)
+when running a netperf tcp transmit test with (say) and 8k buffer.
+
+This should be a candidate for stable, the ax88179_178a driver defaults to
+gso and tso enabled so it passes a lot of fragmented skb to the USB stack.
+
+Notes from Sarah:
+
+Discussion: http://marc.info/?l=linux-usb&m=138384509604981&w=2
+
+This patch fixes a long-standing xHCI driver bug that was revealed by a
+change in 3.12 in the usb-net driver.  Commit
+638c5115a794981441246fa8fa5d95c1875af5ba "USBNET: support DMA SG" added
+support to use bulk endpoint scatter-gather (urb->sg).  Only the USB
+ethernet drivers trigger this bug, because the mass storage driver sends
+sg list entries in page-sized chunks.
+
+This patch only fixes the issue for bulk endpoint scatter-gather.  The
+problem will still occur for periodic endpoints, because hosts will
+interpret no-op transfers as a request to skip a service interval, which
+is not what we want.
+
+Luckily, the USB core isn't set up for scatter-gather on isochronous
+endpoints, and no USB drivers use scatter-gather for interrupt
+endpoints.  Document this known limitation so that developers won't try
+to use urb->sg for interrupt endpoints until this issue is fixed.  The
+more comprehensive fix would be to allow link TRBs in the middle of the
+endpoint ring and revert this patch, but that fix would touch too much
+code to be allowed in for stable.
+
+This patch should be backported to kernels as old as 3.12, that contain
+the commit 638c5115a794981441246fa8fa5d95c1875af5ba "USBNET: support DMA
+SG".  Without this patch, the USB network device gets wedged, and stops
+sending packets.  Mark Lord confirms this patch fixes the regression:
+
+http://marc.info/?l=linux-netdev&m=138487107625966&w=2
+
+Signed-off-by: David Laight <david.laight@aculab.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Tested-by: Mark Lord <mlord@pobox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   54 +++++++++++++++++++++++++++++++++++++++++--
+ include/linux/usb.h          |    2 +
+ 2 files changed, 54 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -2929,8 +2929,58 @@ static int prepare_ring(struct xhci_hcd
+       }
+       while (1) {
+-              if (room_on_ring(xhci, ep_ring, num_trbs))
+-                      break;
++              if (room_on_ring(xhci, ep_ring, num_trbs)) {
++                      union xhci_trb *trb = ep_ring->enqueue;
++                      unsigned int usable = ep_ring->enq_seg->trbs +
++                                      TRBS_PER_SEGMENT - 1 - trb;
++                      u32 nop_cmd;
++
++                      /*
++                       * Section 4.11.7.1 TD Fragments states that a link
++                       * TRB must only occur at the boundary between
++                       * data bursts (eg 512 bytes for 480M).
++                       * While it is possible to split a large fragment
++                       * we don't know the size yet.
++                       * Simplest solution is to fill the trb before the
++                       * LINK with nop commands.
++                       */
++                      if (num_trbs == 1 || num_trbs <= usable || usable == 0)
++                              break;
++
++                      if (ep_ring->type != TYPE_BULK)
++                              /*
++                               * While isoc transfers might have a buffer that
++                               * crosses a 64k boundary it is unlikely.
++                               * Since we can't add NOPs without generating
++                               * gaps in the traffic just hope it never
++                               * happens at the end of the ring.
++                               * This could be fixed by writing a LINK TRB
++                               * instead of the first NOP - however the
++                               * TRB_TYPE_LINK_LE32() calls would all need
++                               * changing to check the ring length.
++                               */
++                              break;
++
++                      if (num_trbs >= TRBS_PER_SEGMENT) {
++                              xhci_err(xhci, "Too many fragments %d, max %d\n",
++                                              num_trbs, TRBS_PER_SEGMENT - 1);
++                              return -ENOMEM;
++                      }
++
++                      nop_cmd = cpu_to_le32(TRB_TYPE(TRB_TR_NOOP) |
++                                      ep_ring->cycle_state);
++                      ep_ring->num_trbs_free -= usable;
++                      do {
++                              trb->generic.field[0] = 0;
++                              trb->generic.field[1] = 0;
++                              trb->generic.field[2] = 0;
++                              trb->generic.field[3] = nop_cmd;
++                              trb++;
++                      } while (--usable);
++                      ep_ring->enqueue = trb;
++                      if (room_on_ring(xhci, ep_ring, num_trbs))
++                              break;
++              }
+               if (ep_ring == xhci->cmd_ring) {
+                       xhci_err(xhci, "Do not support expand command ring\n");
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1262,6 +1262,8 @@ typedef void (*usb_complete_t)(struct ur
+  * @sg: scatter gather buffer list, the buffer size of each element in
+  *    the list (except the last) must be divisible by the endpoint's
+  *    max packet size if no_sg_constraint isn't set in 'struct usb_bus'
++ *    (FIXME: scatter-gather under xHCI is broken for periodic transfers.
++ *    Do not use urb->sg for interrupt endpoints for now, only bulk.)
+  * @num_mapped_sgs: (internal) number of mapped sg entries
+  * @num_sgs: number of entries in the sg list
+  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may