]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2013 22:52:50 +0000 (14:52 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Nov 2013 22:52:50 +0000 (14:52 -0800)
added patches:
mei-nfc-fix-memory-leak-in-error-path.patch
powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch
powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch
powerpc-fix-__get_user_pages_fast-irq-handling.patch
powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch
powerpc-powernv-add-pe-to-its-own-peltv.patch
powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch
powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch
powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch
powerpc-vio-use-strcpy-in-modalias_show.patch
rt2800usb-slow-down-tx-status-polling.patch
slub-handle-null-parameter-in-kmem_cache_flags.patch
sunrpc-avoid-deep-recursion-in-rpc_release_client.patch
sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch
sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch
usb-disable-usb-2.0-link-pm-before-device-reset.patch
usb-don-t-enable-usb-2.0-link-pm-by-default.patch
usb-hub-clear-port-reset-change-during-init-resume.patch
usb-musb-call-musb_start-only-once-in-otg-mode.patch
usb-musb-cancel-work-on-removal.patch
usb-musb-core-properly-free-host-device-structs-in-err-path.patch
usb-musb-dsps-move-try_idle-to-start-hook.patch
usb-musb-dsps-redo-the-otg-timer.patch
usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch
xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch
xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch

27 files changed:
queue-3.12/mei-nfc-fix-memory-leak-in-error-path.patch [new file with mode: 0644]
queue-3.12/powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch [new file with mode: 0644]
queue-3.12/powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch [new file with mode: 0644]
queue-3.12/powerpc-fix-__get_user_pages_fast-irq-handling.patch [new file with mode: 0644]
queue-3.12/powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch [new file with mode: 0644]
queue-3.12/powerpc-powernv-add-pe-to-its-own-peltv.patch [new file with mode: 0644]
queue-3.12/powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch [new file with mode: 0644]
queue-3.12/powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch [new file with mode: 0644]
queue-3.12/powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch [new file with mode: 0644]
queue-3.12/powerpc-vio-use-strcpy-in-modalias_show.patch [new file with mode: 0644]
queue-3.12/rt2800usb-slow-down-tx-status-polling.patch [new file with mode: 0644]
queue-3.12/series
queue-3.12/slub-handle-null-parameter-in-kmem_cache_flags.patch [new file with mode: 0644]
queue-3.12/sunrpc-avoid-deep-recursion-in-rpc_release_client.patch [new file with mode: 0644]
queue-3.12/sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch [new file with mode: 0644]
queue-3.12/sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch [new file with mode: 0644]
queue-3.12/usb-disable-usb-2.0-link-pm-before-device-reset.patch [new file with mode: 0644]
queue-3.12/usb-don-t-enable-usb-2.0-link-pm-by-default.patch [new file with mode: 0644]
queue-3.12/usb-hub-clear-port-reset-change-during-init-resume.patch [new file with mode: 0644]
queue-3.12/usb-musb-call-musb_start-only-once-in-otg-mode.patch [new file with mode: 0644]
queue-3.12/usb-musb-cancel-work-on-removal.patch [new file with mode: 0644]
queue-3.12/usb-musb-core-properly-free-host-device-structs-in-err-path.patch [new file with mode: 0644]
queue-3.12/usb-musb-dsps-move-try_idle-to-start-hook.patch [new file with mode: 0644]
queue-3.12/usb-musb-dsps-redo-the-otg-timer.patch [new file with mode: 0644]
queue-3.12/usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch [new file with mode: 0644]
queue-3.12/xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch [new file with mode: 0644]
queue-3.12/xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch [new file with mode: 0644]

diff --git a/queue-3.12/mei-nfc-fix-memory-leak-in-error-path.patch b/queue-3.12/mei-nfc-fix-memory-leak-in-error-path.patch
new file mode 100644 (file)
index 0000000..da1567e
--- /dev/null
@@ -0,0 +1,50 @@
+From 4bff7208f332b2b1d7cf1338e50527441283a198 Mon Sep 17 00:00:00 2001
+From: Tomas Winkler <tomas.winkler@intel.com>
+Date: Mon, 21 Oct 2013 22:05:38 +0300
+Subject: mei: nfc: fix memory leak in error path
+
+From: Tomas Winkler <tomas.winkler@intel.com>
+
+commit 4bff7208f332b2b1d7cf1338e50527441283a198 upstream.
+
+The flow may reach the err label without freeing cl and cl_info
+
+cl and cl_info weren't assigned to ndev->cl and cl_info
+so they weren't freed in mei_nfc_free called on error path
+
+Cc: Samuel Ortiz <sameo@linux.intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/misc/mei/nfc.c |   10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/misc/mei/nfc.c
++++ b/drivers/misc/mei/nfc.c
+@@ -485,8 +485,11 @@ int mei_nfc_host_init(struct mei_device
+       if (ndev->cl_info)
+               return 0;
+-      cl_info = mei_cl_allocate(dev);
+-      cl = mei_cl_allocate(dev);
++      ndev->cl_info = mei_cl_allocate(dev);
++      ndev->cl = mei_cl_allocate(dev);
++
++      cl = ndev->cl;
++      cl_info = ndev->cl_info;
+       if (!cl || !cl_info) {
+               ret = -ENOMEM;
+@@ -527,10 +530,9 @@ int mei_nfc_host_init(struct mei_device
+       cl->device_uuid = mei_nfc_guid;
++
+       list_add_tail(&cl->device_link, &dev->device_list);
+-      ndev->cl_info = cl_info;
+-      ndev->cl = cl;
+       ndev->req_id = 1;
+       INIT_WORK(&ndev->init_work, mei_nfc_init);
diff --git a/queue-3.12/powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch b/queue-3.12/powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch
new file mode 100644 (file)
index 0000000..68ace9c
--- /dev/null
@@ -0,0 +1,29 @@
+From 2bf75084f6d9f9a91ba6e30a501ff070d8a1acf6 Mon Sep 17 00:00:00 2001
+From: Anatolij Gustschin <agust@denx.de>
+Date: Wed, 16 Oct 2013 13:11:27 +0200
+Subject: powerpc/52xx: fix build breakage for MPC5200 LPBFIFO module
+
+From: Anatolij Gustschin <agust@denx.de>
+
+commit 2bf75084f6d9f9a91ba6e30a501ff070d8a1acf6 upstream.
+
+The MPC5200 LPBFIFO driver requires the bestcomm module to be
+enabled, otherwise building will fail. Fix it.
+
+Reported-by: Wolfgang Denk <wd@denx.de>
+Signed-off-by: Anatolij Gustschin <agust@denx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/52xx/Kconfig |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/52xx/Kconfig
++++ b/arch/powerpc/platforms/52xx/Kconfig
+@@ -57,5 +57,5 @@ config PPC_MPC5200_BUGFIX
+ config PPC_MPC5200_LPBFIFO
+       tristate "MPC5200 LocalPlus bus FIFO driver"
+-      depends on PPC_MPC52xx
++      depends on PPC_MPC52xx && PPC_BESTCOMM
+       select PPC_BESTCOMM_GEN_BD
diff --git a/queue-3.12/powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch b/queue-3.12/powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch
new file mode 100644 (file)
index 0000000..7487312
--- /dev/null
@@ -0,0 +1,41 @@
+From bf898ec5cbd33be11147743bee27b66b10cb2f85 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+Date: Tue, 12 Nov 2013 14:49:21 +0800
+Subject: powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges
+
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+
+commit bf898ec5cbd33be11147743bee27b66b10cb2f85 upstream.
+
+On PHB3, we will fail to fetch IODA tables without PCI_COMMAND_MASTER
+on PCI bridges. According to one experiment I had, the MSIx interrupts
+didn't raise from the adapter without the bit applied to all upstream
+PCI bridges including root port of the adapter. The patch forces to
+have that bit enabled accordingly.
+
+Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/eeh.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/arch/powerpc/kernel/eeh.c
++++ b/arch/powerpc/kernel/eeh.c
+@@ -687,6 +687,15 @@ void eeh_save_bars(struct eeh_dev *edev)
+       for (i = 0; i < 16; i++)
+               eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
++
++      /*
++       * For PCI bridges including root port, we need enable bus
++       * master explicitly. Otherwise, it can't fetch IODA table
++       * entries correctly. So we cache the bit in advance so that
++       * we can restore it after reset, either PHB range or PE range.
++       */
++      if (edev->mode & EEH_DEV_BRIDGE)
++              edev->config_space[1] |= PCI_COMMAND_MASTER;
+ }
+ /**
diff --git a/queue-3.12/powerpc-fix-__get_user_pages_fast-irq-handling.patch b/queue-3.12/powerpc-fix-__get_user_pages_fast-irq-handling.patch
new file mode 100644 (file)
index 0000000..e184988
--- /dev/null
@@ -0,0 +1,49 @@
+From 95f715b08fa4a953771398d20cbe35a6803ea41d Mon Sep 17 00:00:00 2001
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+Date: Thu, 14 Nov 2013 15:01:43 +1100
+Subject: powerpc: Fix __get_user_pages_fast() irq handling
+
+From: Heiko Carstens <heiko.carstens@de.ibm.com>
+
+commit 95f715b08fa4a953771398d20cbe35a6803ea41d upstream.
+
+__get_user_pages_fast() may be called with interrupts disabled (see e.g.
+get_futex_key() in kernel/futex.c) and therefore should use local_irq_save()
+and local_irq_restore() instead of local_irq_disable()/enable().
+
+Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/gup.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/mm/gup.c
++++ b/arch/powerpc/mm/gup.c
+@@ -123,6 +123,7 @@ int __get_user_pages_fast(unsigned long
+       struct mm_struct *mm = current->mm;
+       unsigned long addr, len, end;
+       unsigned long next;
++      unsigned long flags;
+       pgd_t *pgdp;
+       int nr = 0;
+@@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long
+        * So long as we atomically load page table pointers versus teardown,
+        * we can follow the address down to the the page and take a ref on it.
+        */
+-      local_irq_disable();
++      local_irq_save(flags);
+       pgdp = pgd_offset(mm, addr);
+       do {
+@@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long
+                       break;
+       } while (pgdp++, addr = next, addr != end);
+-      local_irq_enable();
++      local_irq_restore(flags);
+       return nr;
+ }
diff --git a/queue-3.12/powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch b/queue-3.12/powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch
new file mode 100644 (file)
index 0000000..8aec727
--- /dev/null
@@ -0,0 +1,55 @@
+From 45d20e8348969a165c53cfb91f445e7cc599a9f0 Mon Sep 17 00:00:00 2001
+From: Gerhard Sittig <gsi@denx.de>
+Date: Fri, 27 Sep 2013 17:28:38 +0200
+Subject: powerpc/mpc512x: silence build warning upon disabled DIU
+
+From: Gerhard Sittig <gsi@denx.de>
+
+commit 45d20e8348969a165c53cfb91f445e7cc599a9f0 upstream.
+
+a disabled Kconfig option results in a reference to a not implemented
+routine when the IS_ENABLED() macro is used for both conditional
+implementation of the routine as well as a C language source code test
+at the call site -- the "if (0) func();" construct only gets eliminated
+later by the optimizer, while the compiler already has emitted its
+warning about "func()" being undeclared
+
+provide an empty implementation for the mpc512x_setup_diu() and
+mpc512x_init_diu() routines in case of the disabled option, to avoid the
+compiler warning which is considered fatal and breaks compilation
+
+the bug appeared with commit 2abbbb63c90ab55ca3f054772c2e5ba7df810c48
+"powerpc/mpc512x: move common code to shared.c file", how to reproduce:
+
+  make mpc512x_defconfig
+  echo CONFIG_FB_FSL_DIU=n >> .config && make olddefconfig
+  make
+
+    CC      arch/powerpc/platforms/512x/mpc512x_shared.o
+  .../arch/powerpc/platforms/512x/mpc512x_shared.c: In function 'mpc512x_init_early':
+  .../arch/powerpc/platforms/512x/mpc512x_shared.c:456:3: error: implicit declaration of function 'mpc512x_init_diu' [-Werror=implicit-function-declaration]
+  .../arch/powerpc/platforms/512x/mpc512x_shared.c: In function 'mpc512x_setup_arch':
+  .../arch/powerpc/platforms/512x/mpc512x_shared.c:469:3: error: implicit declaration of function 'mpc512x_setup_diu' [-Werror=implicit-function-declaration]
+  cc1: all warnings being treated as errors
+  make[4]: *** [arch/powerpc/platforms/512x/mpc512x_shared.o] Error 1
+
+Signed-off-by: Gerhard Sittig <gsi@denx.de>
+Signed-off-by: Anatolij Gustschin <agust@denx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/512x/mpc512x_shared.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/powerpc/platforms/512x/mpc512x_shared.c
++++ b/arch/powerpc/platforms/512x/mpc512x_shared.c
+@@ -303,6 +303,9 @@ void __init mpc512x_setup_diu(void)
+       diu_ops.release_bootmem         = mpc512x_release_bootmem;
+ }
++#else
++void __init mpc512x_setup_diu(void) { /* EMPTY */ }
++void __init mpc512x_init_diu(void) { /* EMPTY */ }
+ #endif
+ void __init mpc512x_init_IRQ(void)
diff --git a/queue-3.12/powerpc-powernv-add-pe-to-its-own-peltv.patch b/queue-3.12/powerpc-powernv-add-pe-to-its-own-peltv.patch
new file mode 100644 (file)
index 0000000..1be7cc1
--- /dev/null
@@ -0,0 +1,50 @@
+From 631ad691b5818291d89af9be607d2fe40be0886e Mon Sep 17 00:00:00 2001
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+Date: Mon, 4 Nov 2013 16:32:46 +0800
+Subject: powerpc/powernv: Add PE to its own PELTV
+
+From: Gavin Shan <shangw@linux.vnet.ibm.com>
+
+commit 631ad691b5818291d89af9be607d2fe40be0886e upstream.
+
+We need add PE to its own PELTV. Otherwise, the errors originated
+from the PE might contribute to other PEs. In the result, we can't
+clear up the error successfully even we're checking and clearing
+errors during access to PCI config space.
+
+Reported-by: kalshett@in.ibm.com
+Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/pci-ioda.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/powernv/pci-ioda.c
++++ b/arch/powerpc/platforms/powernv/pci-ioda.c
+@@ -153,13 +153,23 @@ static int pnv_ioda_configure_pe(struct
+               rid_end = pe->rid + 1;
+       }
+-      /* Associate PE in PELT */
++      /*
++       * Associate PE in PELT. We need add the PE into the
++       * corresponding PELT-V as well. Otherwise, the error
++       * originated from the PE might contribute to other
++       * PEs.
++       */
+       rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid,
+                            bcomp, dcomp, fcomp, OPAL_MAP_PE);
+       if (rc) {
+               pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc);
+               return -ENXIO;
+       }
++
++      rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number,
++                              pe->pe_number, OPAL_ADD_PE_TO_DOMAIN);
++      if (rc)
++              pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc);
+       opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
+                                 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
diff --git a/queue-3.12/powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch b/queue-3.12/powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch
new file mode 100644 (file)
index 0000000..d34c2e6
--- /dev/null
@@ -0,0 +1,39 @@
+From 5a049f14902982c26538250bdc8d54156d357252 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Mon, 18 Nov 2013 14:55:28 +1100
+Subject: powerpc: ppc64 address space capped at 32TB, mmap randomisation disabled
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 5a049f14902982c26538250bdc8d54156d357252 upstream.
+
+Commit fba2369e6ceb (mm: use vm_unmapped_area() on powerpc architecture)
+has a bug in slice_scan_available() where we compare an unsigned long
+(high_slices) against a shifted int. As a result, comparisons against
+the top 32 bits of high_slices (representing the top 32TB) always
+returns 0 and the top of our mmap region is clamped at 32TB
+
+This also breaks mmap randomisation since the randomised address is
+always up near the top of the address space and it gets clamped down
+to 32TB.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Acked-by: Michel Lespinasse <walken@google.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/slice.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/mm/slice.c
++++ b/arch/powerpc/mm/slice.c
+@@ -258,7 +258,7 @@ static bool slice_scan_available(unsigne
+               slice = GET_HIGH_SLICE_INDEX(addr);
+               *boundary_addr = (slice + end) ?
+                       ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP;
+-              return !!(available.high_slices & (1u << slice));
++              return !!(available.high_slices & (1ul << slice));
+       }
+ }
diff --git a/queue-3.12/powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch b/queue-3.12/powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch
new file mode 100644 (file)
index 0000000..82b9117
--- /dev/null
@@ -0,0 +1,55 @@
+From 84b073868b9d9e754ae48b828337633d1b386482 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Sun, 17 Nov 2013 11:39:05 +1100
+Subject: powerpc/pseries: Duplicate dtl entries sometimes sent to userspace
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 84b073868b9d9e754ae48b828337633d1b386482 upstream.
+
+When reading from the dispatch trace log (dtl) userspace interface, I
+sometimes see duplicate entries. One example:
+
+# hexdump -C dtl.out
+
+00000000  07 04 00 0c 00 00 48 44  00 00 00 00 00 00 00 00
+00000010  00 0c a0 b4 16 83 6d 68  00 00 00 00 00 00 00 00
+00000020  00 00 00 00 10 00 13 50  80 00 00 00 00 00 d0 32
+
+00000030  07 04 00 0c 00 00 48 44  00 00 00 00 00 00 00 00
+00000040  00 0c a0 b4 16 83 6d 68  00 00 00 00 00 00 00 00
+00000050  00 00 00 00 10 00 13 50  80 00 00 00 00 00 d0 32
+
+The problem is in scan_dispatch_log() where we call dtl_consumer()
+but bail out before incrementing the index.
+
+To fix this I moved dtl_consumer() after the timebase comparison.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/time.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -213,8 +213,6 @@ static u64 scan_dispatch_log(u64 stop_tb
+       if (i == be64_to_cpu(vpa->dtl_idx))
+               return 0;
+       while (i < be64_to_cpu(vpa->dtl_idx)) {
+-              if (dtl_consumer)
+-                      dtl_consumer(dtl, i);
+               dtb = be64_to_cpu(dtl->timebase);
+               tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
+                       be32_to_cpu(dtl->ready_to_enqueue_time);
+@@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb
+               }
+               if (dtb > stop_tb)
+                       break;
++              if (dtl_consumer)
++                      dtl_consumer(dtl, i);
+               stolen += tb_delta;
+               ++i;
+               ++dtl;
diff --git a/queue-3.12/powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch b/queue-3.12/powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch
new file mode 100644 (file)
index 0000000..2364601
--- /dev/null
@@ -0,0 +1,58 @@
+From c13f20ac48328b05cd3b8c19e31ed6c132b44b42 Mon Sep 17 00:00:00 2001
+From: Michael Neuling <mikey@neuling.org>
+Date: Wed, 20 Nov 2013 16:18:54 +1100
+Subject: powerpc/signals: Mark VSX not saved with small contexts
+
+From: Michael Neuling <mikey@neuling.org>
+
+commit c13f20ac48328b05cd3b8c19e31ed6c132b44b42 upstream.
+
+The VSX MSR bit in the user context indicates if the context contains VSX
+state.  Currently we set this when the process has touched VSX at any stage.
+
+Unfortunately, if the user has not provided enough space to save the VSX state,
+we can't save it but we currently still set the MSR VSX bit.
+
+This patch changes this to clear the MSR VSX bit when the user doesn't provide
+enough space.  This indicates that there is no valid VSX state in the user
+context.
+
+This is needed to support get/set/make/swapcontext for applications that use
+VSX but only provide a small context.  For example, getcontext in glibc
+provides a smaller context since the VSX registers don't need to be saved over
+the glibc function call.  But since the program calling getcontext may have
+used VSX, the kernel currently says the VSX state is valid when it's not.  If
+the returned context is then used in setcontext (ie. a small context without
+VSX but with MSR VSX set), the kernel will refuse the context.  This situation
+has been reported by the glibc community.
+
+Based on patch from Carlos O'Donell.
+
+Tested-by: Haren Myneni <haren@linux.vnet.ibm.com>
+Signed-off-by: Michael Neuling <mikey@neuling.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/signal_32.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs
+               if (copy_vsx_to_user(&frame->mc_vsregs, current))
+                       return 1;
+               msr |= MSR_VSX;
+-      }
++      } else if (!ctx_has_vsx_region)
++              /*
++               * With a small context structure we can't hold the VSX
++               * registers, hence clear the MSR value to indicate the state
++               * was not saved.
++               */
++              msr &= ~MSR_VSX;
++
++
+ #endif /* CONFIG_VSX */
+ #ifdef CONFIG_SPE
+       /* save spe registers */
diff --git a/queue-3.12/powerpc-vio-use-strcpy-in-modalias_show.patch b/queue-3.12/powerpc-vio-use-strcpy-in-modalias_show.patch
new file mode 100644 (file)
index 0000000..11ae71a
--- /dev/null
@@ -0,0 +1,39 @@
+From 411cabf79e684171669ad29a0628c400b4431e95 Mon Sep 17 00:00:00 2001
+From: Prarit Bhargava <prarit@redhat.com>
+Date: Thu, 17 Oct 2013 08:00:11 -0400
+Subject: powerpc/vio: use strcpy in modalias_show
+
+From: Prarit Bhargava <prarit@redhat.com>
+
+commit 411cabf79e684171669ad29a0628c400b4431e95 upstream.
+
+Commit e82b89a6f19bae73fb064d1b3dd91fcefbb478f4 used strcat instead of
+strcpy which can result in an overflow of newlines on the buffer.
+
+Signed-off-by: Prarit Bhargava
+Cc: benh@kernel.crashing.org
+Cc: ben@decadent.org.uk
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/vio.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/vio.c
++++ b/arch/powerpc/kernel/vio.c
+@@ -1531,12 +1531,12 @@ static ssize_t modalias_show(struct devi
+       dn = dev->of_node;
+       if (!dn) {
+-              strcat(buf, "\n");
++              strcpy(buf, "\n");
+               return strlen(buf);
+       }
+       cp = of_get_property(dn, "compatible", NULL);
+       if (!cp) {
+-              strcat(buf, "\n");
++              strcpy(buf, "\n");
+               return strlen(buf);
+       }
diff --git a/queue-3.12/rt2800usb-slow-down-tx-status-polling.patch b/queue-3.12/rt2800usb-slow-down-tx-status-polling.patch
new file mode 100644 (file)
index 0000000..95089a6
--- /dev/null
@@ -0,0 +1,71 @@
+From 36165fd5b00bf8163f89c21bb16a3e9834555b10 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Fri, 18 Oct 2013 11:36:54 +0200
+Subject: rt2800usb: slow down TX status polling
+
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+
+commit 36165fd5b00bf8163f89c21bb16a3e9834555b10 upstream.
+
+Polling TX statuses too frequently has two negative effects. First is
+randomly peek CPU usage, causing overall system functioning delays.
+Second bad effect is that device is not able to fill TX statuses in
+H/W register on some workloads and we get lot of timeouts like below:
+
+ieee80211 phy4: rt2800usb_entry_txstatus_timeout: Warning - TX status timeout for entry 7 in queue 2
+ieee80211 phy4: rt2800usb_entry_txstatus_timeout: Warning - TX status timeout for entry 7 in queue 2
+ieee80211 phy4: rt2800usb_txdone: Warning - Got TX status for an empty queue 2, dropping
+
+This not only cause flood of messages in dmesg, but also bad throughput,
+since rate scaling algorithm can not work optimally.
+
+In the future, we should probably make polling interval be adjusted
+automatically, but for now just increase values, this make mentioned
+problems gone.
+
+Resolve:
+https://bugzilla.kernel.org/show_bug.cgi?id=62781
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rt2x00/rt2800usb.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
+@@ -148,6 +148,8 @@ static bool rt2800usb_txstatus_timeout(s
+       return false;
+ }
++#define TXSTATUS_READ_INTERVAL 1000000
++
+ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+                                                int urb_status, u32 tx_status)
+ {
+@@ -176,8 +178,9 @@ static bool rt2800usb_tx_sta_fifo_read_c
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+       if (rt2800usb_txstatus_pending(rt2x00dev)) {
+-              /* Read register after 250 us */
+-              hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000),
++              /* Read register after 1 ms */
++              hrtimer_start(&rt2x00dev->txstatus_timer,
++                            ktime_set(0, TXSTATUS_READ_INTERVAL),
+                             HRTIMER_MODE_REL);
+               return false;
+       }
+@@ -202,8 +205,9 @@ static void rt2800usb_async_read_tx_stat
+       if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
+               return;
+-      /* Read TX_STA_FIFO register after 500 us */
+-      hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000),
++      /* Read TX_STA_FIFO register after 2 ms */
++      hrtimer_start(&rt2x00dev->txstatus_timer,
++                    ktime_set(0, 2*TXSTATUS_READ_INTERVAL),
+                     HRTIMER_MODE_REL);
+ }
index a515c9242e42ce79add9cfa61c99d88f2c02e2a4..2e3d7062c93bd283690b69dca252b306ae9aba02 100644 (file)
@@ -82,3 +82,29 @@ drivers-memstick-core-ms_block.c-fix-unreachable-state-in-h_msb_read_page.patch
 block-fix-race-between-request-completion-and-timeout-handling.patch
 block-fix-a-probe-argument-to-blk_register_region.patch
 block-properly-stack-underlying-max_segment_size-to-dm-device.patch
+powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch
+powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch
+powerpc-vio-use-strcpy-in-modalias_show.patch
+powerpc-powernv-add-pe-to-its-own-peltv.patch
+powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch
+powerpc-fix-__get_user_pages_fast-irq-handling.patch
+powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch
+powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch
+powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch
+slub-handle-null-parameter-in-kmem_cache_flags.patch
+sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch
+sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch
+sunrpc-avoid-deep-recursion-in-rpc_release_client.patch
+mei-nfc-fix-memory-leak-in-error-path.patch
+usb-don-t-enable-usb-2.0-link-pm-by-default.patch
+xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch
+xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch
+usb-disable-usb-2.0-link-pm-before-device-reset.patch
+usb-hub-clear-port-reset-change-during-init-resume.patch
+usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch
+rt2800usb-slow-down-tx-status-polling.patch
+usb-musb-cancel-work-on-removal.patch
+usb-musb-call-musb_start-only-once-in-otg-mode.patch
+usb-musb-dsps-move-try_idle-to-start-hook.patch
+usb-musb-dsps-redo-the-otg-timer.patch
+usb-musb-core-properly-free-host-device-structs-in-err-path.patch
diff --git a/queue-3.12/slub-handle-null-parameter-in-kmem_cache_flags.patch b/queue-3.12/slub-handle-null-parameter-in-kmem_cache_flags.patch
new file mode 100644 (file)
index 0000000..aed74d4
--- /dev/null
@@ -0,0 +1,92 @@
+From c6f58d9b362b45c52afebe4342c9137d0dabe47f Mon Sep 17 00:00:00 2001
+From: Christoph Lameter <cl@linux.com>
+Date: Thu, 7 Nov 2013 16:29:15 +0000
+Subject: slub: Handle NULL parameter in kmem_cache_flags
+
+From: Christoph Lameter <cl@linux.com>
+
+commit c6f58d9b362b45c52afebe4342c9137d0dabe47f upstream.
+
+Andreas Herrmann writes:
+
+  When I've used slub_debug kernel option (e.g.
+  "slub_debug=,skbuff_fclone_cache" or similar) on a debug session I've
+  seen a panic like:
+
+    Highbank #setenv bootargs console=ttyAMA0 root=/dev/sda2 kgdboc.kgdboc=ttyAMA0,115200 slub_debug=,kmalloc-4096 earlyprintk=ttyAMA0
+    ...
+    Unable to handle kernel NULL pointer dereference at virtual address 00000000
+    pgd = c0004000
+    [00000000] *pgd=00000000
+    Internal error: Oops: 5 [#1] SMP ARM
+    Modules linked in:
+    CPU: 0 PID: 0 Comm: swapper Tainted: G        W    3.12.0-00048-gbe408cd #314
+    task: c0898360 ti: c088a000 task.ti: c088a000
+    PC is at strncmp+0x1c/0x84
+    LR is at kmem_cache_flags.isra.46.part.47+0x44/0x60
+    pc : [<c02c6da0>]    lr : [<c0110a3c>]    psr: 200001d3
+    sp : c088bea8  ip : c088beb8  fp : c088beb4
+    r10: 00000000  r9 : 413fc090  r8 : 00000001
+    r7 : 00000000  r6 : c2984a08  r5 : c0966e78  r4 : 00000000
+    r3 : 0000006b  r2 : 0000000c  r1 : 00000000  r0 : c2984a08
+    Flags: nzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
+    Control: 10c5387d  Table: 0000404a  DAC: 00000015
+    Process swapper (pid: 0, stack limit = 0xc088a248)
+    Stack: (0xc088bea8 to 0xc088c000)
+    bea0:                   c088bed4 c088beb8 c0110a3c c02c6d90 c0966e78 00000040
+    bec0: ef001f00 00000040 c088bf14 c088bed8 c0112070 c0110a04 00000005 c010fac8
+    bee0: c088bf5c c088bef0 c010fac8 ef001f00 00000040 00000000 00000040 00000001
+    bf00: 413fc090 00000000 c088bf34 c088bf18 c0839190 c0112040 00000000 ef001f00
+    bf20: 00000000 00000000 c088bf54 c088bf38 c0839200 c083914c 00000006 c0961c4c
+    bf40: c0961c28 00000000 c088bf7c c088bf58 c08392ac c08391c0 c08a2ed8 c0966e78
+    bf60: c086b874 c08a3f50 c0961c28 00000001 c088bfb4 c088bf80 c083b258 c0839248
+    bf80: 2f800000 0f000000 c08935b4 ffffffff c08cd400 ffffffff c08cd400 c0868408
+    bfa0: c29849c0 00000000 c088bff4 c088bfb8 c0824974 c083b1e4 ffffffff ffffffff
+    bfc0: c08245c0 00000000 00000000 c0868408 00000000 10c5387d c0892bcc c0868404
+    bfe0: c0899440 0000406a 00000000 c088bff8 00008074 c0824824 00000000 00000000
+    [<c02c6da0>] (strncmp+0x1c/0x84) from [<c0110a3c>] (kmem_cache_flags.isra.46.part.47+0x44/0x60)
+    [<c0110a3c>] (kmem_cache_flags.isra.46.part.47+0x44/0x60) from [<c0112070>] (__kmem_cache_create+0x3c/0x410)
+    [<c0112070>] (__kmem_cache_create+0x3c/0x410) from [<c0839190>] (create_boot_cache+0x50/0x74)
+    [<c0839190>] (create_boot_cache+0x50/0x74) from [<c0839200>] (create_kmalloc_cache+0x4c/0x88)
+    [<c0839200>] (create_kmalloc_cache+0x4c/0x88) from [<c08392ac>] (create_kmalloc_caches+0x70/0x114)
+    [<c08392ac>] (create_kmalloc_caches+0x70/0x114) from [<c083b258>] (kmem_cache_init+0x80/0xe0)
+    [<c083b258>] (kmem_cache_init+0x80/0xe0) from [<c0824974>] (start_kernel+0x15c/0x318)
+    [<c0824974>] (start_kernel+0x15c/0x318) from [<00008074>] (0x8074)
+    Code: e3520000 01a00002 089da800 e5d03000 (e5d1c000)
+    ---[ end trace 1b75b31a2719ed1d ]---
+    Kernel panic - not syncing: Fatal exception
+
+  Problem is that slub_debug option is not parsed before
+  create_boot_cache is called. Solve this by changing slub_debug to
+  early_param.
+
+  Kernels 3.11, 3.10 are also affected.  I am not sure about older
+  kernels.
+
+Christoph Lameter explains:
+
+  kmem_cache_flags may be called with NULL parameter during early boot.
+  Skip the test in that case.
+
+Reported-by: Andreas Herrmann <andreas.herrmann@calxeda.com>
+Signed-off-by: Christoph Lameter <cl@linux.com>
+Signed-off-by: Pekka Enberg <penberg@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/slub.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/mm/slub.c
++++ b/mm/slub.c
+@@ -1217,8 +1217,8 @@ static unsigned long kmem_cache_flags(un
+       /*
+        * Enable debugging if selected on the kernel commandline.
+        */
+-      if (slub_debug && (!slub_debug_slabs ||
+-              !strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs))))
++      if (slub_debug && (!slub_debug_slabs || (name &&
++              !strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)))))
+               flags |= slub_debug;
+       return flags;
diff --git a/queue-3.12/sunrpc-avoid-deep-recursion-in-rpc_release_client.patch b/queue-3.12/sunrpc-avoid-deep-recursion-in-rpc_release_client.patch
new file mode 100644 (file)
index 0000000..f08db98
--- /dev/null
@@ -0,0 +1,102 @@
+From d07ba8422f1e58be94cc98a1f475946dc1b89f1b Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Tue, 12 Nov 2013 17:24:36 -0500
+Subject: SUNRPC: Avoid deep recursion in rpc_release_client
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit d07ba8422f1e58be94cc98a1f475946dc1b89f1b upstream.
+
+In cases where an rpc client has a parent hierarchy, then
+rpc_free_client may end up calling rpc_release_client() on the
+parent, thus recursing back into rpc_free_client. If the hierarchy
+is deep enough, then we can get into situations where the stack
+simply overflows.
+
+The fix is to have rpc_release_client() loop so that it can take
+care of the parent rpc client hierarchy without needing to
+recurse.
+
+Reported-by: Jeff Layton <jlayton@redhat.com>
+Reported-by: Weston Andros Adamson <dros@netapp.com>
+Reported-by: Bruce Fields <bfields@fieldses.org>
+Link: http://lkml.kernel.org/r/2C73011F-0939-434C-9E4D-13A1EB1403D7@netapp.com
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/clnt.c |   29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -656,14 +656,16 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client);
+ /*
+  * Free an RPC client
+  */
+-static void
++static struct rpc_clnt *
+ rpc_free_client(struct rpc_clnt *clnt)
+ {
++      struct rpc_clnt *parent = NULL;
++
+       dprintk_rcu("RPC:       destroying %s client for %s\n",
+                       clnt->cl_program->name,
+                       rcu_dereference(clnt->cl_xprt)->servername);
+       if (clnt->cl_parent != clnt)
+-              rpc_release_client(clnt->cl_parent);
++              parent = clnt->cl_parent;
+       rpc_clnt_remove_pipedir(clnt);
+       rpc_unregister_client(clnt);
+       rpc_free_iostats(clnt->cl_metrics);
+@@ -672,18 +674,17 @@ rpc_free_client(struct rpc_clnt *clnt)
+       rpciod_down();
+       rpc_free_clid(clnt);
+       kfree(clnt);
++      return parent;
+ }
+ /*
+  * Free an RPC client
+  */
+-static void
++static struct rpc_clnt *
+ rpc_free_auth(struct rpc_clnt *clnt)
+ {
+-      if (clnt->cl_auth == NULL) {
+-              rpc_free_client(clnt);
+-              return;
+-      }
++      if (clnt->cl_auth == NULL)
++              return rpc_free_client(clnt);
+       /*
+        * Note: RPCSEC_GSS may need to send NULL RPC calls in order to
+@@ -694,7 +695,8 @@ rpc_free_auth(struct rpc_clnt *clnt)
+       rpcauth_release(clnt->cl_auth);
+       clnt->cl_auth = NULL;
+       if (atomic_dec_and_test(&clnt->cl_count))
+-              rpc_free_client(clnt);
++              return rpc_free_client(clnt);
++      return NULL;
+ }
+ /*
+@@ -705,10 +707,13 @@ rpc_release_client(struct rpc_clnt *clnt
+ {
+       dprintk("RPC:       rpc_release_client(%p)\n", clnt);
+-      if (list_empty(&clnt->cl_tasks))
+-              wake_up(&destroy_wait);
+-      if (atomic_dec_and_test(&clnt->cl_count))
+-              rpc_free_auth(clnt);
++      do {
++              if (list_empty(&clnt->cl_tasks))
++                      wake_up(&destroy_wait);
++              if (!atomic_dec_and_test(&clnt->cl_count))
++                      break;
++              clnt = rpc_free_auth(clnt);
++      } while (clnt != NULL);
+ }
+ EXPORT_SYMBOL_GPL(rpc_release_client);
diff --git a/queue-3.12/sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch b/queue-3.12/sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch
new file mode 100644 (file)
index 0000000..eb3a951
--- /dev/null
@@ -0,0 +1,152 @@
+From a6b31d18b02ff9d7915c5898c9b5ca41a798cd73 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 8 Nov 2013 16:03:50 -0500
+Subject: SUNRPC: Fix a data corruption issue when retransmitting RPC calls
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit a6b31d18b02ff9d7915c5898c9b5ca41a798cd73 upstream.
+
+The following scenario can cause silent data corruption when doing
+NFS writes. It has mainly been observed when doing database writes
+using O_DIRECT.
+
+1) The RPC client uses sendpage() to do zero-copy of the page data.
+2) Due to networking issues, the reply from the server is delayed,
+   and so the RPC client times out.
+
+3) The client issues a second sendpage of the page data as part of
+   an RPC call retransmission.
+
+4) The reply to the first transmission arrives from the server
+   _before_ the client hardware has emptied the TCP socket send
+   buffer.
+5) After processing the reply, the RPC state machine rules that
+   the call to be done, and triggers the completion callbacks.
+6) The application notices the RPC call is done, and reuses the
+   pages to store something else (e.g. a new write).
+
+7) The client NIC drains the TCP socket send buffer. Since the
+   page data has now changed, it reads a corrupted version of the
+   initial RPC call, and puts it on the wire.
+
+This patch fixes the problem in the following manner:
+
+The ordering guarantees of TCP ensure that when the server sends a
+reply, then we know that the _first_ transmission has completed. Using
+zero-copy in that situation is therefore safe.
+If a time out occurs, we then send the retransmission using sendmsg()
+(i.e. no zero-copy), We then know that the socket contains a full copy of
+the data, and so it will retransmit a faithful reproduction even if the
+RPC call completes, and the application reuses the O_DIRECT buffer in
+the meantime.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/xprtsock.c |   28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -393,8 +393,10 @@ static int xs_send_kvec(struct socket *s
+       return kernel_sendmsg(sock, &msg, NULL, 0, 0);
+ }
+-static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more)
++static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more, bool zerocopy)
+ {
++      ssize_t (*do_sendpage)(struct socket *sock, struct page *page,
++                      int offset, size_t size, int flags);
+       struct page **ppage;
+       unsigned int remainder;
+       int err, sent = 0;
+@@ -403,6 +405,9 @@ static int xs_send_pagedata(struct socke
+       base += xdr->page_base;
+       ppage = xdr->pages + (base >> PAGE_SHIFT);
+       base &= ~PAGE_MASK;
++      do_sendpage = sock->ops->sendpage;
++      if (!zerocopy)
++              do_sendpage = sock_no_sendpage;
+       for(;;) {
+               unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
+               int flags = XS_SENDMSG_FLAGS;
+@@ -410,7 +415,7 @@ static int xs_send_pagedata(struct socke
+               remainder -= len;
+               if (remainder != 0 || more)
+                       flags |= MSG_MORE;
+-              err = sock->ops->sendpage(sock, *ppage, base, len, flags);
++              err = do_sendpage(sock, *ppage, base, len, flags);
+               if (remainder == 0 || err != len)
+                       break;
+               sent += err;
+@@ -431,9 +436,10 @@ static int xs_send_pagedata(struct socke
+  * @addrlen: UDP only -- length of destination address
+  * @xdr: buffer containing this request
+  * @base: starting position in the buffer
++ * @zerocopy: true if it is safe to use sendpage()
+  *
+  */
+-static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
++static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, bool zerocopy)
+ {
+       unsigned int remainder = xdr->len - base;
+       int err, sent = 0;
+@@ -461,7 +467,7 @@ static int xs_sendpages(struct socket *s
+       if (base < xdr->page_len) {
+               unsigned int len = xdr->page_len - base;
+               remainder -= len;
+-              err = xs_send_pagedata(sock, xdr, base, remainder != 0);
++              err = xs_send_pagedata(sock, xdr, base, remainder != 0, zerocopy);
+               if (remainder == 0 || err != len)
+                       goto out;
+               sent += err;
+@@ -564,7 +570,7 @@ static int xs_local_send_request(struct
+                       req->rq_svec->iov_base, req->rq_svec->iov_len);
+       status = xs_sendpages(transport->sock, NULL, 0,
+-                                              xdr, req->rq_bytes_sent);
++                                              xdr, req->rq_bytes_sent, true);
+       dprintk("RPC:       %s(%u) = %d\n",
+                       __func__, xdr->len - req->rq_bytes_sent, status);
+       if (likely(status >= 0)) {
+@@ -620,7 +626,7 @@ static int xs_udp_send_request(struct rp
+       status = xs_sendpages(transport->sock,
+                             xs_addr(xprt),
+                             xprt->addrlen, xdr,
+-                            req->rq_bytes_sent);
++                            req->rq_bytes_sent, true);
+       dprintk("RPC:       xs_udp_send_request(%u) = %d\n",
+                       xdr->len - req->rq_bytes_sent, status);
+@@ -693,6 +699,7 @@ static int xs_tcp_send_request(struct rp
+       struct rpc_xprt *xprt = req->rq_xprt;
+       struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+       struct xdr_buf *xdr = &req->rq_snd_buf;
++      bool zerocopy = true;
+       int status;
+       xs_encode_stream_record_marker(&req->rq_snd_buf);
+@@ -700,13 +707,20 @@ static int xs_tcp_send_request(struct rp
+       xs_pktdump("packet data:",
+                               req->rq_svec->iov_base,
+                               req->rq_svec->iov_len);
++      /* Don't use zero copy if this is a resend. If the RPC call
++       * completes while the socket holds a reference to the pages,
++       * then we may end up resending corrupted data.
++       */
++      if (task->tk_flags & RPC_TASK_SENT)
++              zerocopy = false;
+       /* Continue transmitting the packet/record. We must be careful
+        * to cope with writespace callbacks arriving _after_ we have
+        * called sendmsg(). */
+       while (1) {
+               status = xs_sendpages(transport->sock,
+-                                      NULL, 0, xdr, req->rq_bytes_sent);
++                                      NULL, 0, xdr, req->rq_bytes_sent,
++                                      zerocopy);
+               dprintk("RPC:       xs_tcp_send_request(%u) = %d\n",
+                               xdr->len - req->rq_bytes_sent, status);
diff --git a/queue-3.12/sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch b/queue-3.12/sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch
new file mode 100644 (file)
index 0000000..88dbbad
--- /dev/null
@@ -0,0 +1,30 @@
+From 5fccc5b52ee07d07a74ce53c6f174bff81e26a16 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 28 Oct 2013 18:41:44 -0400
+Subject: SUNRPC: gss_alloc_msg - choose _either_ a v0 message or a v1 message
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 5fccc5b52ee07d07a74ce53c6f174bff81e26a16 upstream.
+
+Add the missing 'break' to ensure that we don't corrupt a legacy 'v0' type
+message by appending the 'v1'.
+
+Cc: Bruce Fields <bfields@fieldses.org>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/auth_gss/auth_gss.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -482,6 +482,7 @@ gss_alloc_msg(struct gss_auth *gss_auth,
+       switch (vers) {
+       case 0:
+               gss_encode_v0_msg(gss_msg);
++              break;
+       default:
+               gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
+       };
diff --git a/queue-3.12/usb-disable-usb-2.0-link-pm-before-device-reset.patch b/queue-3.12/usb-disable-usb-2.0-link-pm-before-device-reset.patch
new file mode 100644 (file)
index 0000000..d113be1
--- /dev/null
@@ -0,0 +1,48 @@
+From dcc01c0864823f91c3bf3ffca6613e2351702b87 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Mon, 30 Sep 2013 17:26:29 +0300
+Subject: usb: Disable USB 2.0 Link PM before device reset.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit dcc01c0864823f91c3bf3ffca6613e2351702b87 upstream.
+
+Before the USB core resets a device, we need to disable the L1 timeout
+for the roothub, if USB 2.0 Link PM is enabled.  Otherwise the port may
+transition into L1 in between descriptor fetches, before we know if the
+USB device descriptors changed.  LPM will be re-enabled after the
+full device descriptors are fetched, and we can confirm the device still
+supports USB 2.0 LPM after the reset.
+
+We don't need to wait for the USB device to exit L1 before resetting the
+device, since the xHCI roothub port diagrams show a transition to the
+Reset state from any of the Ux states (see Figure 34 in the 2012-08-14
+xHCI specification update).
+
+This patch should be backported to kernels as old as 3.2, that contain
+the commit 65580b4321eb36f16ae8b5987bfa1bb948fc5112 "xHCI: set USB2
+hardware LPM".  That was the first commit to enable USB 2.0
+hardware-driven Link Power Management.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5118,6 +5118,12 @@ static int usb_reset_and_verify_device(s
+       }
+       parent_hub = usb_hub_to_struct_hub(parent_hdev);
++      /* Disable USB2 hardware LPM.
++       * It will be re-enabled by the enumeration process.
++       */
++      if (udev->usb2_hw_lpm_enabled == 1)
++              usb_set_usb2_hardware_lpm(udev, 0);
++
+       bos = udev->bos;
+       udev->bos = NULL;
diff --git a/queue-3.12/usb-don-t-enable-usb-2.0-link-pm-by-default.patch b/queue-3.12/usb-don-t-enable-usb-2.0-link-pm-by-default.patch
new file mode 100644 (file)
index 0000000..a29c1ac
--- /dev/null
@@ -0,0 +1,366 @@
+From de68bab4fa96014cfaa6fcbcdb9750e32969fb86 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Mon, 30 Sep 2013 17:26:28 +0300
+Subject: usb: Don't enable USB 2.0 Link PM by default.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit de68bab4fa96014cfaa6fcbcdb9750e32969fb86 upstream.
+
+How it's supposed to work:
+--------------------------
+
+USB 2.0 Link PM is a lower power state that some newer USB 2.0 devices
+support.  USB 3.0 devices certified by the USB-IF are required to
+support it if they are plugged into a USB 2.0 only port, or a USB 2.0
+cable is used.  USB 2.0 Link PM requires both a USB device and a host
+controller that supports USB 2.0 hardware-enabled LPM.
+
+USB 2.0 Link PM is designed to be enabled once by software, and the host
+hardware handles transitions to the L1 state automatically.  The premise
+of USB 2.0 Link PM is to be able to put the device into a lower power
+link state when the bus is idle or the device NAKs USB IN transfers for
+a specified amount of time.
+
+...but hardware is broken:
+--------------------------
+
+It turns out many USB 3.0 devices claim to support USB 2.0 Link PM (by
+setting the LPM bit in their USB 2.0 BOS descriptor), but they don't
+actually implement it correctly.  This manifests as the USB device
+refusing to respond to transfers when it is plugged into a USB 2.0 only
+port under the Haswell-ULT/Lynx Point LP xHCI host.
+
+These devices pass the xHCI driver's simple test to enable USB 2.0 Link
+PM, wait for the port to enter L1, and then bring it back into L0.  They
+only start to break when L1 entry is interleaved with transfers.
+
+Some devices then fail to respond to the next control transfer (usually
+a Set Configuration).  This results in devices never enumerating.
+
+Other mass storage devices (such as a later model Western Digital My
+Passport USB 3.0 hard drive) respond fine to going into L1 between
+control transfers.  They ACK the entry, come out of L1 when the host
+needs to send a control transfer, and respond properly to those control
+transfers.  However, when the first READ10 SCSI command is sent, the
+device NAKs the data phase while it's reading from the spinning disk.
+Eventually, the host requests to put the link into L1, and the device
+ACKs that request.  Then it never responds to the data phase of the
+READ10 command.  This results in not being able to read from the drive.
+
+Some mass storage devices (like the Corsair Survivor USB 3.0 flash
+drive) are well behaved.  They ACK the entry into L1 during control
+transfers, and when SCSI commands start coming in, they NAK the requests
+to go into L1, because they need to be at full power.
+
+Not all USB 3.0 devices advertise USB 2.0 link PM support.  My Point
+Grey USB 3.0 webcam advertises itself as a USB 2.1 device, but doesn't
+have a USB 2.0 BOS descriptor, so we don't enable USB 2.0 Link PM.  I
+suspect that means the device isn't certified.
+
+What do we do about it?
+-----------------------
+
+There's really no good way for the kernel to test these devices.
+Therefore, the kernel needs to disable USB 2.0 Link PM by default, and
+distros will have to enable it by writing 1 to the sysfs file
+/sys/bus/usb/devices/../power/usb2_hardware_lpm.  Rip out the xHCI Link
+PM test, since it's not sufficient to detect these buggy devices, and
+don't automatically enable LPM after the device is addressed.
+
+This patch should be backported to kernels as old as 3.11, that
+contain the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci:
+add USB2 Link power management BESL support".  Without this fix, some
+USB 3.0 devices will not enumerate or work properly under USB 2.0 ports
+on Haswell-ULT systems.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/driver.c   |    3 
+ drivers/usb/core/hub.c      |    1 
+ drivers/usb/core/sysfs.c    |    6 +
+ drivers/usb/host/xhci-mem.c |   10 --
+ drivers/usb/host/xhci.c     |  161 ++++----------------------------------------
+ include/linux/usb.h         |    4 -
+ 6 files changed, 29 insertions(+), 156 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1790,6 +1790,9 @@ int usb_set_usb2_hardware_lpm(struct usb
+       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+       int ret = -EPERM;
++      if (enable && !udev->usb2_hw_lpm_allowed)
++              return 0;
++
+       if (hcd->driver->set_usb2_hw_lpm) {
+               ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable);
+               if (!ret)
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -5198,6 +5198,7 @@ static int usb_reset_and_verify_device(s
+ done:
+       /* Now that the alt settings are re-installed, enable LTM and LPM. */
++      usb_set_usb2_hardware_lpm(udev, 1);
+       usb_unlocked_enable_lpm(udev);
+       usb_enable_ltm(udev);
+       usb_release_bos_descriptor(udev);
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -449,7 +449,7 @@ static ssize_t usb2_hardware_lpm_show(st
+       struct usb_device *udev = to_usb_device(dev);
+       const char *p;
+-      if (udev->usb2_hw_lpm_enabled == 1)
++      if (udev->usb2_hw_lpm_allowed == 1)
+               p = "enabled";
+       else
+               p = "disabled";
+@@ -469,8 +469,10 @@ static ssize_t usb2_hardware_lpm_store(s
+       ret = strtobool(buf, &value);
+-      if (!ret)
++      if (!ret) {
++              udev->usb2_hw_lpm_allowed = value;
+               ret = usb_set_usb2_hardware_lpm(udev, value);
++      }
+       usb_unlock_device(udev);
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1693,9 +1693,7 @@ void xhci_free_command(struct xhci_hcd *
+ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+ {
+       struct pci_dev  *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+-      struct dev_info *dev_info, *next;
+       struct xhci_cd  *cur_cd, *next_cd;
+-      unsigned long   flags;
+       int size;
+       int i, j, num_ports;
+@@ -1756,13 +1754,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x
+       scratchpad_free(xhci);
+-      spin_lock_irqsave(&xhci->lock, flags);
+-      list_for_each_entry_safe(dev_info, next, &xhci->lpm_failed_devs, list) {
+-              list_del(&dev_info->list);
+-              kfree(dev_info);
+-      }
+-      spin_unlock_irqrestore(&xhci->lock, flags);
+-
+       if (!xhci->rh_bw)
+               goto no_bw;
+@@ -2231,7 +2222,6 @@ int xhci_mem_init(struct xhci_hcd *xhci,
+       u32 page_size, temp;
+       int i;
+-      INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
+       page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4025,133 +4025,6 @@ static int xhci_calculate_usb2_hw_lpm_pa
+       return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm);
+ }
+-static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
+-                                      struct usb_device *udev)
+-{
+-      struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+-      struct dev_info *dev_info;
+-      __le32 __iomem  **port_array;
+-      __le32 __iomem  *addr, *pm_addr;
+-      u32             temp, dev_id;
+-      unsigned int    port_num;
+-      unsigned long   flags;
+-      int             hird;
+-      int             ret;
+-
+-      if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
+-                      !udev->lpm_capable)
+-              return -EINVAL;
+-
+-      /* we only support lpm for non-hub device connected to root hub yet */
+-      if (!udev->parent || udev->parent->parent ||
+-                      udev->descriptor.bDeviceClass == USB_CLASS_HUB)
+-              return -EINVAL;
+-
+-      spin_lock_irqsave(&xhci->lock, flags);
+-
+-      /* Look for devices in lpm_failed_devs list */
+-      dev_id = le16_to_cpu(udev->descriptor.idVendor) << 16 |
+-                      le16_to_cpu(udev->descriptor.idProduct);
+-      list_for_each_entry(dev_info, &xhci->lpm_failed_devs, list) {
+-              if (dev_info->dev_id == dev_id) {
+-                      ret = -EINVAL;
+-                      goto finish;
+-              }
+-      }
+-
+-      port_array = xhci->usb2_ports;
+-      port_num = udev->portnum - 1;
+-
+-      if (port_num > HCS_MAX_PORTS(xhci->hcs_params1)) {
+-              xhci_dbg(xhci, "invalid port number %d\n", udev->portnum);
+-              ret = -EINVAL;
+-              goto finish;
+-      }
+-
+-      /*
+-       * Test USB 2.0 software LPM.
+-       * FIXME: some xHCI 1.0 hosts may implement a new register to set up
+-       * hardware-controlled USB 2.0 LPM. See section 5.4.11 and 4.23.5.1.1.1
+-       * in the June 2011 errata release.
+-       */
+-      xhci_dbg(xhci, "test port %d software LPM\n", port_num);
+-      /*
+-       * Set L1 Device Slot and HIRD/BESL.
+-       * Check device's USB 2.0 extension descriptor to determine whether
+-       * HIRD or BESL shoule be used. See USB2.0 LPM errata.
+-       */
+-      pm_addr = port_array[port_num] + PORTPMSC;
+-      hird = xhci_calculate_hird_besl(xhci, udev);
+-      temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird);
+-      xhci_writel(xhci, temp, pm_addr);
+-
+-      /* Set port link state to U2(L1) */
+-      addr = port_array[port_num];
+-      xhci_set_link_state(xhci, port_array, port_num, XDEV_U2);
+-
+-      /* wait for ACK */
+-      spin_unlock_irqrestore(&xhci->lock, flags);
+-      msleep(10);
+-      spin_lock_irqsave(&xhci->lock, flags);
+-
+-      /* Check L1 Status */
+-      ret = xhci_handshake(xhci, pm_addr,
+-                      PORT_L1S_MASK, PORT_L1S_SUCCESS, 125);
+-      if (ret != -ETIMEDOUT) {
+-              /* enter L1 successfully */
+-              temp = xhci_readl(xhci, addr);
+-              xhci_dbg(xhci, "port %d entered L1 state, port status 0x%x\n",
+-                              port_num, temp);
+-              ret = 0;
+-      } else {
+-              temp = xhci_readl(xhci, pm_addr);
+-              xhci_dbg(xhci, "port %d software lpm failed, L1 status %d\n",
+-                              port_num, temp & PORT_L1S_MASK);
+-              ret = -EINVAL;
+-      }
+-
+-      /* Resume the port */
+-      xhci_set_link_state(xhci, port_array, port_num, XDEV_U0);
+-
+-      spin_unlock_irqrestore(&xhci->lock, flags);
+-      msleep(10);
+-      spin_lock_irqsave(&xhci->lock, flags);
+-
+-      /* Clear PLC */
+-      xhci_test_and_clear_bit(xhci, port_array, port_num, PORT_PLC);
+-
+-      /* Check PORTSC to make sure the device is in the right state */
+-      if (!ret) {
+-              temp = xhci_readl(xhci, addr);
+-              xhci_dbg(xhci, "resumed port %d status 0x%x\n", port_num, temp);
+-              if (!(temp & PORT_CONNECT) || !(temp & PORT_PE) ||
+-                              (temp & PORT_PLS_MASK) != XDEV_U0) {
+-                      xhci_dbg(xhci, "port L1 resume fail\n");
+-                      ret = -EINVAL;
+-              }
+-      }
+-
+-      if (ret) {
+-              /* Insert dev to lpm_failed_devs list */
+-              xhci_warn(xhci, "device LPM test failed, may disconnect and "
+-                              "re-enumerate\n");
+-              dev_info = kzalloc(sizeof(struct dev_info), GFP_ATOMIC);
+-              if (!dev_info) {
+-                      ret = -ENOMEM;
+-                      goto finish;
+-              }
+-              dev_info->dev_id = dev_id;
+-              INIT_LIST_HEAD(&dev_info->list);
+-              list_add(&dev_info->list, &xhci->lpm_failed_devs);
+-      } else {
+-              xhci_ring_device(xhci, udev->slot_id);
+-      }
+-
+-finish:
+-      spin_unlock_irqrestore(&xhci->lock, flags);
+-      return ret;
+-}
+-
+ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
+                       struct usb_device *udev, int enable)
+ {
+@@ -4279,24 +4152,26 @@ static int xhci_check_usb2_port_capabili
+ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+-      int             ret;
+       int             portnum = udev->portnum - 1;
+-      ret = xhci_usb2_software_lpm_test(hcd, udev);
+-      if (!ret) {
+-              xhci_dbg(xhci, "software LPM test succeed\n");
+-              if (xhci->hw_lpm_support == 1 &&
+-                  xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) {
+-                      udev->usb2_hw_lpm_capable = 1;
+-                      udev->l1_params.timeout = XHCI_L1_TIMEOUT;
+-                      udev->l1_params.besl = XHCI_DEFAULT_BESL;
+-                      if (xhci_check_usb2_port_capability(xhci, portnum,
+-                                                          XHCI_BLC))
+-                              udev->usb2_hw_lpm_besl_capable = 1;
+-                      ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1);
+-                      if (!ret)
+-                              udev->usb2_hw_lpm_enabled = 1;
+-              }
++      if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support ||
++                      !udev->lpm_capable)
++              return 0;
++
++      /* we only support lpm for non-hub device connected to root hub yet */
++      if (!udev->parent || udev->parent->parent ||
++                      udev->descriptor.bDeviceClass == USB_CLASS_HUB)
++              return 0;
++
++      if (xhci->hw_lpm_support == 1 &&
++                      xhci_check_usb2_port_capability(
++                              xhci, portnum, XHCI_HLC)) {
++              udev->usb2_hw_lpm_capable = 1;
++              udev->l1_params.timeout = XHCI_L1_TIMEOUT;
++              udev->l1_params.besl = XHCI_DEFAULT_BESL;
++              if (xhci_check_usb2_port_capability(xhci, portnum,
++                                      XHCI_BLC))
++                      udev->usb2_hw_lpm_besl_capable = 1;
+       }
+       return 0;
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -475,7 +475,8 @@ struct usb3_lpm_parameters {
+  * @lpm_capable: device supports LPM
+  * @usb2_hw_lpm_capable: device can perform USB2 hardware LPM
+  * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM
+- * @usb2_hw_lpm_enabled: USB2 hardware LPM enabled
++ * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled
++ * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled
+  * @usb3_lpm_enabled: USB3 hardware LPM enabled
+  * @string_langid: language ID for strings
+  * @product: iProduct string, if present (static)
+@@ -548,6 +549,7 @@ struct usb_device {
+       unsigned usb2_hw_lpm_capable:1;
+       unsigned usb2_hw_lpm_besl_capable:1;
+       unsigned usb2_hw_lpm_enabled:1;
++      unsigned usb2_hw_lpm_allowed:1;
+       unsigned usb3_lpm_enabled:1;
+       int string_langid;
diff --git a/queue-3.12/usb-hub-clear-port-reset-change-during-init-resume.patch b/queue-3.12/usb-hub-clear-port-reset-change-during-init-resume.patch
new file mode 100644 (file)
index 0000000..bc50beb
--- /dev/null
@@ -0,0 +1,40 @@
+From e92aee330837e4911553761490a8fb843f2053a6 Mon Sep 17 00:00:00 2001
+From: Julius Werner <jwerner@chromium.org>
+Date: Tue, 15 Oct 2013 17:45:00 -0700
+Subject: usb: hub: Clear Port Reset Change during init/resume
+
+From: Julius Werner <jwerner@chromium.org>
+
+commit e92aee330837e4911553761490a8fb843f2053a6 upstream.
+
+This patch adds the Port Reset Change flag to the set of bits that are
+preemptively cleared on init/resume of a hub. In theory this bit should
+never be set unexpectedly... in practice it can still happen if BIOS,
+SMM or ACPI code plays around with USB devices without cleaning up
+correctly. This is especially dangerous for XHCI root hubs, which don't
+generate any more Port Status Change Events until all change bits are
+cleared, so this is a good precaution to have (similar to how it's
+already done for the Warm Port Reset Change flag).
+
+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, 5 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -1135,6 +1135,11 @@ static void hub_activate(struct usb_hub
+                       usb_clear_port_feature(hub->hdev, port1,
+                                       USB_PORT_FEAT_C_ENABLE);
+               }
++              if (portchange & USB_PORT_STAT_C_RESET) {
++                      need_debounce_delay = true;
++                      usb_clear_port_feature(hub->hdev, port1,
++                                      USB_PORT_FEAT_C_RESET);
++              }
+               if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
+                               hub_is_superspeed(hub->hdev)) {
+                       need_debounce_delay = true;
diff --git a/queue-3.12/usb-musb-call-musb_start-only-once-in-otg-mode.patch b/queue-3.12/usb-musb-call-musb_start-only-once-in-otg-mode.patch
new file mode 100644 (file)
index 0000000..ffcd181
--- /dev/null
@@ -0,0 +1,67 @@
+From ae44df2e21b50f9fff28ac75c57e399c04df812c Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 15 Oct 2013 18:29:22 +0200
+Subject: usb: musb: call musb_start() only once in OTG mode
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit ae44df2e21b50f9fff28ac75c57e399c04df812c upstream.
+
+In commit 001dd84 ("usb: musb: start musb on the udc side, too") it was
+ensured that the state engine is started also in OTG mode after a
+removal / insertion of the gadget.
+Unfortunately this change also introduced a bug: If the device is
+configured as OTG and it connected with a remote host _without_ loading
+a gadget then we bug() later (because musb->otg->gadget is not
+initialized).
+Initially I assumed it might be nice to have the host part of musb in
+OTG mode working without having a gadget loaded. This bug and fact that
+it wasn't working like this before the host/gadget split made me realize
+that this was a silly idea.
+This patch now introduces back the old behavior where in OTG mode the
+host mode is only working after the gadget has been loaded.
+
+Cc: Daniel Mack <zonque@gmail.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_virthub.c |   19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_virthub.c
++++ b/drivers/usb/musb/musb_virthub.c
+@@ -220,6 +220,23 @@ int musb_hub_status_data(struct usb_hcd
+       return retval;
+ }
++static int musb_has_gadget(struct musb *musb)
++{
++      /*
++       * In host-only mode we start a connection right away. In OTG mode
++       * we have to wait until we loaded a gadget. We don't really need a
++       * gadget if we operate as a host but we should not start a session
++       * as a device without a gadget or else we explode.
++       */
++#ifdef CONFIG_USB_MUSB_HOST
++      return 1;
++#else
++      if (musb->port_mode == MUSB_PORT_MODE_HOST)
++              return 1;
++      return musb->g.dev.driver != NULL;
++#endif
++}
++
+ int musb_hub_control(
+       struct usb_hcd  *hcd,
+       u16             typeReq,
+@@ -362,7 +379,7 @@ int musb_hub_control(
+                        * initialization logic, e.g. for OTG, or change any
+                        * logic relating to VBUS power-up.
+                        */
+-                      if (!hcd->self.is_b_host)
++                      if (!hcd->self.is_b_host && musb_has_gadget(musb))
+                               musb_start(musb);
+                       break;
+               case USB_PORT_FEAT_RESET:
diff --git a/queue-3.12/usb-musb-cancel-work-on-removal.patch b/queue-3.12/usb-musb-cancel-work-on-removal.patch
new file mode 100644 (file)
index 0000000..93cc70b
--- /dev/null
@@ -0,0 +1,57 @@
+From c5340bd14336b902604ab95212a8877de109d9ae Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Thu, 10 Oct 2013 18:26:59 +0200
+Subject: usb: musb: cancel work on removal
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit c5340bd14336b902604ab95212a8877de109d9ae upstream.
+
+So I captured this:
+
+|WARNING: CPU: 0 PID: 2078 at /home/bigeasy/work/new/TI/linux/lib/debugobjects.c:260 debug_print_object+0x94/0xc4()
+|ODEBUG: free active (active state 0) object type: work_struct hint: musb_irq_work+0x0/0x38 [musb_hdrc]
+|CPU: 0 PID: 2078 Comm: rmmod Not tainted 3.12.0-rc4+ #338
+|[<c0014d38>] (unwind_backtrace+0x0/0xf4) from [<c001249c>] (show_stack+0x14/0x1c)
+|[<c001249c>] (show_stack+0x14/0x1c) from [<c0037720>] (warn_slowpath_common+0x64/0x84)
+|[<c0037720>] (warn_slowpath_common+0x64/0x84) from [<c00377d4>] (warn_slowpath_fmt+0x30/0x40)
+|[<c00377d4>] (warn_slowpath_fmt+0x30/0x40) from [<c022ae90>] (debug_print_object+0x94/0xc4)
+|[<c022ae90>] (debug_print_object+0x94/0xc4) from [<c022b7e0>] (debug_check_no_obj_freed+0x1c0/0x228)
+|[<c022b7e0>] (debug_check_no_obj_freed+0x1c0/0x228) from [<c00f1f38>] (kfree+0xf8/0x228)
+|[<c00f1f38>] (kfree+0xf8/0x228) from [<c02921c4>] (release_nodes+0x1a8/0x248)
+|[<c02921c4>] (release_nodes+0x1a8/0x248) from [<c028f70c>] (__device_release_driver+0x98/0xf0)
+|[<c028f70c>] (__device_release_driver+0x98/0xf0) from [<c028f840>] (device_release_driver+0x24/0x34)
+|[<c028f840>] (device_release_driver+0x24/0x34) from [<c028ebe8>] (bus_remove_device+0x148/0x15c)
+|[<c028ebe8>] (bus_remove_device+0x148/0x15c) from [<c028d120>] (device_del+0x104/0x1c0)
+|[<c028d120>] (device_del+0x104/0x1c0) from [<c02911e4>] (platform_device_del+0x18/0xac)
+|[<c02911e4>] (platform_device_del+0x18/0xac) from [<c029179c>] (platform_device_unregister+0xc/0x18)
+|[<c029179c>] (platform_device_unregister+0xc/0x18) from [<bf1902fc>] (dsps_remove+0x20/0x4c [musb_dsps])
+|[<bf1902fc>] (dsps_remove+0x20/0x4c [musb_dsps]) from [<c0290d7c>] (platform_drv_remove+0x1c/0x24)
+|[<c0290d7c>] (platform_drv_remove+0x1c/0x24) from [<c028f704>] (__device_release_driver+0x90/0xf0)
+|[<c028f704>] (__device_release_driver+0x90/0xf0) from [<c028f818>] (driver_detach+0xb4/0xb8)
+|[<c028f818>] (driver_detach+0xb4/0xb8) from [<c028e6e8>] (bus_remove_driver+0x98/0xec)
+|[<c028e6e8>] (bus_remove_driver+0x98/0xec) from [<c008fc70>] (SyS_delete_module+0x1e0/0x24c)
+|[<c008fc70>] (SyS_delete_module+0x1e0/0x24c) from [<c000e680>] (ret_fast_syscall+0x0/0x48)
+|---[ end trace d79045419a3e51ec ]---
+
+The workqueue is only scheduled from the ep0 and never canceled in case
+the musb is removed before the work has a chance to run.
+
+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_core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -1809,6 +1809,7 @@ static void musb_free(struct musb *musb)
+                       disable_irq_wake(musb->nIrq);
+               free_irq(musb->nIrq, musb);
+       }
++      cancel_work_sync(&musb->irq_work);
+       if (musb->dma_controller)
+               dma_controller_destroy(musb->dma_controller);
diff --git a/queue-3.12/usb-musb-core-properly-free-host-device-structs-in-err-path.patch b/queue-3.12/usb-musb-core-properly-free-host-device-structs-in-err-path.patch
new file mode 100644 (file)
index 0000000..2660105
--- /dev/null
@@ -0,0 +1,43 @@
+From 0d2dd7eaed1dac07b266ca2c662ff4a184a3060f Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 16 Oct 2013 12:50:06 +0200
+Subject: usb: musb: core: properly free host / device structs in err path
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit 0d2dd7eaed1dac07b266ca2c662ff4a184a3060f upstream.
+
+The patch fixes two issues in the error path cleanup:
+- in MUSB_PORT_MODE_DUAL_ROLE mode, if musb_gadget_setup() fails we
+  never cleanup the host struct earlier allocated.
+- if musb_init_debugfs() or sysfs_create_group() fails, then we never
+  free the host part initialization, only device part.
+
+Cc: Daniel Mack <zonque@gmail.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_core.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -1947,6 +1947,8 @@ musb_init_controller(struct device *dev,
+               if (status < 0)
+                       goto fail3;
+               status = musb_gadget_setup(musb);
++              if (status)
++                      musb_host_cleanup(musb);
+               break;
+       default:
+               dev_err(dev, "unsupported port mode %d\n", musb->port_mode);
+@@ -1973,6 +1975,7 @@ fail5:
+ fail4:
+       musb_gadget_cleanup(musb);
++      musb_host_cleanup(musb);
+ fail3:
+       if (musb->dma_controller)
diff --git a/queue-3.12/usb-musb-dsps-move-try_idle-to-start-hook.patch b/queue-3.12/usb-musb-dsps-move-try_idle-to-start-hook.patch
new file mode 100644 (file)
index 0000000..0c274b9
--- /dev/null
@@ -0,0 +1,62 @@
+From 8b9fcce2d88586b9a120ff3e039d8f42413f0bb0 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 15 Oct 2013 18:29:23 +0200
+Subject: usb: musb: dsps: move try_idle to start hook
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit 8b9fcce2d88586b9a120ff3e039d8f42413f0bb0 upstream.
+
+The timer is initialized right after musb is probed. There is actually
+no need to have this timer running because _nothing_ will happen until
+we have the gadget loaded. Also we need this timer only if we run in OTG
+mode _and_ we need it also after the gadget has been replaced with
+another one.
+
+I've been looking at am35x.c, da8xx.c, omap2430.c, tusb6010.c. da8xx
+seem to have the same problem as dsps and doing mostly the same thing.
+tusb6010 seem to do something different and do some actual "idle / power
+saving" work so I am not too comfortable to remove
+musb_platform_try_idle() from musb_gadget_setup().
+
+Therefore this patch does not start the timer if there is no gadget
+active (which is at musb_gadget_setup() at time). In order to have the
+timer active after the gadget is loaded it will be triggered from
+dsps_musb_enable().
+
+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_dsps.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/musb/musb_dsps.c
++++ b/drivers/usb/musb/musb_dsps.c
+@@ -121,6 +121,7 @@ struct dsps_glue {
+       unsigned long last_timer;    /* last timer data for each instance */
+ };
++static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout);
+ /**
+  * dsps_musb_enable - enable interrupts
+  */
+@@ -143,6 +144,7 @@ static void dsps_musb_enable(struct musb
+       /* Force the DRVVBUS IRQ so we can start polling for ID change. */
+       dsps_writel(reg_base, wrp->coreintr_set,
+                   (1 << wrp->drvvbus) << wrp->usb_shift);
++      dsps_musb_try_idle(musb, 0);
+ }
+ /**
+@@ -234,6 +236,9 @@ static void dsps_musb_try_idle(struct mu
+       if (musb->port_mode == MUSB_PORT_MODE_HOST)
+               return;
++      if (!musb->g.dev.driver)
++              return;
++
+       if (time_after(glue->last_timer, timeout) &&
+                               timer_pending(&glue->timer)) {
+               dev_dbg(musb->controller,
diff --git a/queue-3.12/usb-musb-dsps-redo-the-otg-timer.patch b/queue-3.12/usb-musb-dsps-redo-the-otg-timer.patch
new file mode 100644 (file)
index 0000000..b1df155
--- /dev/null
@@ -0,0 +1,103 @@
+From 0f901c980110cd69b63670096465b35377e73b1c Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 15 Oct 2013 18:29:25 +0200
+Subject: usb: musb: dsps: redo the otg timer
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+commit 0f901c980110cd69b63670096465b35377e73b1c upstream.
+
+According to the comments, we rely on the OTG timer because the core
+does not expose some important OTG details. So far this is all I
+know. After playing with OTG I stumbled over a problem:
+musb is recognized as a B-device without a problem. Whenever a cable is
+plugged, the VBUS rises, musb recognizes this as a starting session,
+sets the MUSB_DEVCTL_SESSION bit by itself and a RESET interrupt occurs,
+the session starts. Good.
+After a disconnect, the timer is started and re-starts itself because
+it remains in B_IDLE with the BDEVICE set. I didn't figure the the
+reason or the need for it. Nothing changes here except for OTG state
+from B to A device if the BDEVICE bit disappears. This doesn't make much
+sense to me because nothing happens after this. _IF_ we receive an
+interrupt before the state change then we may act on wrong condition.
+Plugging a B-device (and letting MUSB act as host) doesn't work here.
+The reason seems to be that the MUSB tries to start a session, it fails
+and then it removes the bit. So we never start as a host.
+
+This patch sets the MUSB_DEVCTL_SESSION bit in the IDLE state so musb
+can try to establish a session as host. After the bit is set, musb tries
+to start a session and if it fails it clears the bit. Therefore it will
+try over and over again until a session either as host or as device is
+established.
+
+The readout of the MUSB_DEVCTL register after the removal the
+MUSB_DEVCTL_SESSION (in A_WAIT_BCON) has been removed because it did not
+contain the BDEVICE bit set (in the second read) leading to A_IDLE. After
+plugging a host musb assumed that it is also a host and complained about
+a missing reset. However a third read of the register has has the BDEVICE
+bit set so it seems that it is not stable.
+This mostly what da8xx.c is doing except that we set the timer also
+after A_WAIT_BCON so the session bit can be triggered.
+
+Whit this change I was able to keep am335x-evm in OTG mode and plug in
+either a HOST or a DEVICE and in a random order and the device was
+recognized.
+
+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_dsps.c |   20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/musb/musb_dsps.c
++++ b/drivers/usb/musb/musb_dsps.c
+@@ -173,6 +173,7 @@ static void otg_timer(unsigned long _mus
+       const struct dsps_musb_wrapper *wrp = glue->wrp;
+       u8 devctl;
+       unsigned long flags;
++      int skip_session = 0;
+       /*
+        * We poll because DSPS IP's won't expose several OTG-critical
+@@ -185,10 +186,12 @@ static void otg_timer(unsigned long _mus
+       spin_lock_irqsave(&musb->lock, flags);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_WAIT_BCON:
+-              devctl &= ~MUSB_DEVCTL_SESSION;
+-              dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
++              dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
++              skip_session = 1;
++              /* fall */
+-              devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
++      case OTG_STATE_A_IDLE:
++      case OTG_STATE_B_IDLE:
+               if (devctl & MUSB_DEVCTL_BDEVICE) {
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
+                       MUSB_DEV_MODE(musb);
+@@ -196,20 +199,15 @@ static void otg_timer(unsigned long _mus
+                       musb->xceiv->state = OTG_STATE_A_IDLE;
+                       MUSB_HST_MODE(musb);
+               }
++              if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
++                      dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
++              mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
+               break;
+       case OTG_STATE_A_WAIT_VFALL:
+               musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
+               dsps_writel(musb->ctrl_base, wrp->coreintr_set,
+                           MUSB_INTR_VBUSERROR << wrp->usb_shift);
+               break;
+-      case OTG_STATE_B_IDLE:
+-              devctl = dsps_readb(mregs, MUSB_DEVCTL);
+-              if (devctl & MUSB_DEVCTL_BDEVICE)
+-                      mod_timer(&glue->timer,
+-                                      jiffies + wrp->poll_seconds * HZ);
+-              else
+-                      musb->xceiv->state = OTG_STATE_A_IDLE;
+-              break;
+       default:
+               break;
+       }
diff --git a/queue-3.12/usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch b/queue-3.12/usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch
new file mode 100644 (file)
index 0000000..1998daf
--- /dev/null
@@ -0,0 +1,34 @@
+From 7b6bc07ab554e929c85d51b3d5b26cf7f12c6a3b Mon Sep 17 00:00:00 2001
+From: Thomas Pugliese <thomas.pugliese@gmail.com>
+Date: Wed, 23 Oct 2013 14:44:26 -0500
+Subject: usb: wusbcore: set the RPIPE wMaxPacketSize value correctly
+
+From: Thomas Pugliese <thomas.pugliese@gmail.com>
+
+commit 7b6bc07ab554e929c85d51b3d5b26cf7f12c6a3b upstream.
+
+For isochronous endpoints, set the RPIPE wMaxPacketSize value using
+wOverTheAirPacketSize from the endpoint companion descriptor instead of
+wMaxPacketSize from the normal endpoint descriptor.
+
+Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/wusbcore/wa-rpipe.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/wusbcore/wa-rpipe.c
++++ b/drivers/usb/wusbcore/wa-rpipe.c
+@@ -333,7 +333,10 @@ static int rpipe_aim(struct wa_rpipe *rp
+       /* FIXME: compute so seg_size > ep->maxpktsize */
+       rpipe->descr.wBlocks = cpu_to_le16(16);         /* given */
+       /* ep0 maxpktsize is 0x200 (WUSB1.0[4.8.1]) */
+-      rpipe->descr.wMaxPacketSize = cpu_to_le16(ep->desc.wMaxPacketSize);
++      if (usb_endpoint_xfer_isoc(&ep->desc))
++              rpipe->descr.wMaxPacketSize = epcd->wOverTheAirPacketSize;
++      else
++              rpipe->descr.wMaxPacketSize = ep->desc.wMaxPacketSize;
+       rpipe->descr.hwa_bMaxBurst = max(min_t(unsigned int,
+                               epcd->bMaxBurst, 16U), 1U);
diff --git a/queue-3.12/xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch b/queue-3.12/xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch
new file mode 100644 (file)
index 0000000..785b33e
--- /dev/null
@@ -0,0 +1,75 @@
+From 890dae88672175f1d39f6105444d9bdc71c89258 Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+Date: Mon, 30 Sep 2013 17:26:31 +0300
+Subject: xhci: Enable LPM support only for hardwired or BESL devices
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+commit 890dae88672175f1d39f6105444d9bdc71c89258 upstream.
+
+Some usb3 devices falsely claim they support usb2 hardware Link PM
+when connected to a usb2 port. We only trust hardwired devices
+or devices with the later BESL LPM support to be LPM enabled as default.
+
+[Note: Sarah re-worked the original patch to move the code into the USB
+core, and updated it to check whether the USB device supports BESL,
+instead of checking if the xHCI port it's connected to supports BESL
+encoding.]
+
+This patch should be backported to kernels as old as 3.11, that
+contain the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci:
+add USB2 Link power management BESL support".  Without this fix, some
+USB 3.0 devices will not enumerate or work properly under USB 2.0 ports
+on Haswell-ULT systems.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c |   27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3954,6 +3954,32 @@ static int hub_set_address(struct usb_de
+       return retval;
+ }
++/*
++ * There are reports of USB 3.0 devices that say they support USB 2.0 Link PM
++ * when they're plugged into a USB 2.0 port, but they don't work when LPM is
++ * enabled.
++ *
++ * Only enable USB 2.0 Link PM if the port is internal (hardwired), or the
++ * device says it supports the new USB 2.0 Link PM errata by setting the BESL
++ * support bit in the BOS descriptor.
++ */
++static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
++{
++      int connect_type;
++
++      if (!udev->usb2_hw_lpm_capable)
++              return;
++
++      connect_type = usb_get_hub_port_connect_type(udev->parent,
++                      udev->portnum);
++
++      if ((udev->bos->ext_cap->bmAttributes & USB_BESL_SUPPORT) ||
++                      connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
++              udev->usb2_hw_lpm_allowed = 1;
++              usb_set_usb2_hardware_lpm(udev, 1);
++      }
++}
++
+ /* Reset device, (re)assign address, get device descriptor.
+  * Device connection must be stable, no more debouncing needed.
+  * Returns device in USB_STATE_ADDRESS, except on error.
+@@ -4247,6 +4273,7 @@ hub_port_init (struct usb_hub *hub, stru
+       /* notify HCD that we have a device connected and addressed */
+       if (hcd->driver->update_device)
+               hcd->driver->update_device(hcd, udev);
++      hub_set_initial_usb2_lpm_policy(udev);
+ fail:
+       if (retval) {
+               hub_port_disable(hub, port1, 0);
diff --git a/queue-3.12/xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch b/queue-3.12/xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch
new file mode 100644 (file)
index 0000000..07ac778
--- /dev/null
@@ -0,0 +1,69 @@
+From 58e21f73975ec927119370635bf68b9023831c56 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Mon, 7 Oct 2013 17:17:20 -0700
+Subject: xhci: Set L1 device slot on USB2 LPM enable/disable.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 58e21f73975ec927119370635bf68b9023831c56 upstream.
+
+To enable USB 2.0 Link Power Management (LPM), the xHCI host controller
+needs the device slot ID to generate the device address used in L1 entry
+tokens.  That information is set in the L1 device slot ID field of the
+USB 2.0 LPM registers.
+
+Currently, the L1 device slot ID is overwritten when the xHCI driver
+initiates the software test of USB 2.0 Link PM in
+xhci_usb2_software_lpm_test.  It is never cleared when USB 2.0 Link PM
+is disabled for the device.  That should be harmless, because the
+Hardware LPM Enable (HLE) bit is cleared when USB 2.0 Link PM is
+disabled, so the host should not pay attention to the slot ID.
+
+This patch should have no effect on host behavior, but since
+xhci_usb2_software_lpm_test is going away in an upcoming bug fix patch,
+we need to move that code to the function that enables and disables USB
+2.0 Link PM.
+
+This patch should be backported to kernels as old as 3.11, that contain
+the commit a558ccdcc71c7770c5e80c926a31cfe8a3892a09 "usb: xhci: add USB2
+Link power management BESL support".  The upcoming bug fix patch is also
+marked for that stable kernel.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    4 ++--
+ drivers/usb/host/xhci.h |    1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -4101,7 +4101,7 @@ int xhci_set_usb2_hardware_lpm(struct us
+               }
+               pm_val &= ~PORT_HIRD_MASK;
+-              pm_val |= PORT_HIRD(hird) | PORT_RWE;
++              pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
+               xhci_writel(xhci, pm_val, pm_addr);
+               pm_val = xhci_readl(xhci, pm_addr);
+               pm_val |= PORT_HLE;
+@@ -4109,7 +4109,7 @@ int xhci_set_usb2_hardware_lpm(struct us
+               /* flush write */
+               xhci_readl(xhci, pm_addr);
+       } else {
+-              pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK);
++              pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
+               xhci_writel(xhci, pm_val, pm_addr);
+               /* flush write */
+               xhci_readl(xhci, pm_addr);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -383,6 +383,7 @@ struct xhci_op_regs {
+ #define       PORT_RWE                (1 << 3)
+ #define       PORT_HIRD(p)            (((p) & 0xf) << 4)
+ #define       PORT_HIRD_MASK          (0xf << 4)
++#define       PORT_L1DS_MASK          (0xff << 8)
+ #define       PORT_L1DS(p)            (((p) & 0xff) << 8)
+ #define       PORT_HLE                (1 << 16)