From: Greg Kroah-Hartman Date: Tue, 26 Nov 2013 22:52:50 +0000 (-0800) Subject: 3.12-stable patches X-Git-Tag: v3.11.10~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=40f6d178e9e0d1ece504e9d2c6f29871c868d10f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.12-stable patches 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 --- 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 index 00000000000..da1567edc48 --- /dev/null +++ b/queue-3.12/mei-nfc-fix-memory-leak-in-error-path.patch @@ -0,0 +1,50 @@ +From 4bff7208f332b2b1d7cf1338e50527441283a198 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Mon, 21 Oct 2013 22:05:38 +0300 +Subject: mei: nfc: fix memory leak in error path + +From: Tomas Winkler + +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 +Signed-off-by: Tomas Winkler +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..68ace9ce375 --- /dev/null +++ b/queue-3.12/powerpc-52xx-fix-build-breakage-for-mpc5200-lpbfifo-module.patch @@ -0,0 +1,29 @@ +From 2bf75084f6d9f9a91ba6e30a501ff070d8a1acf6 Mon Sep 17 00:00:00 2001 +From: Anatolij Gustschin +Date: Wed, 16 Oct 2013 13:11:27 +0200 +Subject: powerpc/52xx: fix build breakage for MPC5200 LPBFIFO module + +From: Anatolij Gustschin + +commit 2bf75084f6d9f9a91ba6e30a501ff070d8a1acf6 upstream. + +The MPC5200 LPBFIFO driver requires the bestcomm module to be +enabled, otherwise building will fail. Fix it. + +Reported-by: Wolfgang Denk +Signed-off-by: Anatolij Gustschin +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..74873123e07 --- /dev/null +++ b/queue-3.12/powerpc-eeh-enable-pci_command_master-for-pci-bridges.patch @@ -0,0 +1,41 @@ +From bf898ec5cbd33be11147743bee27b66b10cb2f85 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Tue, 12 Nov 2013 14:49:21 +0800 +Subject: powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges + +From: Gavin Shan + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e18498899b9 --- /dev/null +++ b/queue-3.12/powerpc-fix-__get_user_pages_fast-irq-handling.patch @@ -0,0 +1,49 @@ +From 95f715b08fa4a953771398d20cbe35a6803ea41d Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Thu, 14 Nov 2013 15:01:43 +1100 +Subject: powerpc: Fix __get_user_pages_fast() irq handling + +From: Heiko Carstens + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8aec7270d3f --- /dev/null +++ b/queue-3.12/powerpc-mpc512x-silence-build-warning-upon-disabled-diu.patch @@ -0,0 +1,55 @@ +From 45d20e8348969a165c53cfb91f445e7cc599a9f0 Mon Sep 17 00:00:00 2001 +From: Gerhard Sittig +Date: Fri, 27 Sep 2013 17:28:38 +0200 +Subject: powerpc/mpc512x: silence build warning upon disabled DIU + +From: Gerhard Sittig + +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 +Signed-off-by: Anatolij Gustschin +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1be7cc1a799 --- /dev/null +++ b/queue-3.12/powerpc-powernv-add-pe-to-its-own-peltv.patch @@ -0,0 +1,50 @@ +From 631ad691b5818291d89af9be607d2fe40be0886e Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Mon, 4 Nov 2013 16:32:46 +0800 +Subject: powerpc/powernv: Add PE to its own PELTV + +From: Gavin Shan + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d34c2e6cd32 --- /dev/null +++ b/queue-3.12/powerpc-ppc64-address-space-capped-at-32tb-mmap-randomisation-disabled.patch @@ -0,0 +1,39 @@ +From 5a049f14902982c26538250bdc8d54156d357252 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 18 Nov 2013 14:55:28 +1100 +Subject: powerpc: ppc64 address space capped at 32TB, mmap randomisation disabled + +From: Anton Blanchard + +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 +Acked-by: Michel Lespinasse +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..82b9117afb1 --- /dev/null +++ b/queue-3.12/powerpc-pseries-duplicate-dtl-entries-sometimes-sent-to-userspace.patch @@ -0,0 +1,55 @@ +From 84b073868b9d9e754ae48b828337633d1b386482 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Sun, 17 Nov 2013 11:39:05 +1100 +Subject: powerpc/pseries: Duplicate dtl entries sometimes sent to userspace + +From: Anton Blanchard + +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 +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2364601fbf7 --- /dev/null +++ b/queue-3.12/powerpc-signals-mark-vsx-not-saved-with-small-contexts.patch @@ -0,0 +1,58 @@ +From c13f20ac48328b05cd3b8c19e31ed6c132b44b42 Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Wed, 20 Nov 2013 16:18:54 +1100 +Subject: powerpc/signals: Mark VSX not saved with small contexts + +From: Michael Neuling + +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 +Signed-off-by: Michael Neuling +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..11ae71a73bf --- /dev/null +++ b/queue-3.12/powerpc-vio-use-strcpy-in-modalias_show.patch @@ -0,0 +1,39 @@ +From 411cabf79e684171669ad29a0628c400b4431e95 Mon Sep 17 00:00:00 2001 +From: Prarit Bhargava +Date: Thu, 17 Oct 2013 08:00:11 -0400 +Subject: powerpc/vio: use strcpy in modalias_show + +From: Prarit Bhargava + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..95089a6e93e --- /dev/null +++ b/queue-3.12/rt2800usb-slow-down-tx-status-polling.patch @@ -0,0 +1,71 @@ +From 36165fd5b00bf8163f89c21bb16a3e9834555b10 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Fri, 18 Oct 2013 11:36:54 +0200 +Subject: rt2800usb: slow down TX status polling + +From: Stanislaw Gruszka + +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 +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + diff --git a/queue-3.12/series b/queue-3.12/series index a515c9242e4..2e3d7062c93 100644 --- a/queue-3.12/series +++ b/queue-3.12/series @@ -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 index 00000000000..aed74d48d97 --- /dev/null +++ b/queue-3.12/slub-handle-null-parameter-in-kmem_cache_flags.patch @@ -0,0 +1,92 @@ +From c6f58d9b362b45c52afebe4342c9137d0dabe47f Mon Sep 17 00:00:00 2001 +From: Christoph Lameter +Date: Thu, 7 Nov 2013 16:29:15 +0000 +Subject: slub: Handle NULL parameter in kmem_cache_flags + +From: Christoph Lameter + +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 : [] lr : [] 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 + [] (strncmp+0x1c/0x84) from [] (kmem_cache_flags.isra.46.part.47+0x44/0x60) + [] (kmem_cache_flags.isra.46.part.47+0x44/0x60) from [] (__kmem_cache_create+0x3c/0x410) + [] (__kmem_cache_create+0x3c/0x410) from [] (create_boot_cache+0x50/0x74) + [] (create_boot_cache+0x50/0x74) from [] (create_kmalloc_cache+0x4c/0x88) + [] (create_kmalloc_cache+0x4c/0x88) from [] (create_kmalloc_caches+0x70/0x114) + [] (create_kmalloc_caches+0x70/0x114) from [] (kmem_cache_init+0x80/0xe0) + [] (kmem_cache_init+0x80/0xe0) from [] (start_kernel+0x15c/0x318) + [] (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 +Signed-off-by: Christoph Lameter +Signed-off-by: Pekka Enberg +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f08db98aadd --- /dev/null +++ b/queue-3.12/sunrpc-avoid-deep-recursion-in-rpc_release_client.patch @@ -0,0 +1,102 @@ +From d07ba8422f1e58be94cc98a1f475946dc1b89f1b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 12 Nov 2013 17:24:36 -0500 +Subject: SUNRPC: Avoid deep recursion in rpc_release_client + +From: Trond Myklebust + +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 +Reported-by: Weston Andros Adamson +Reported-by: Bruce Fields +Link: http://lkml.kernel.org/r/2C73011F-0939-434C-9E4D-13A1EB1403D7@netapp.com +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..eb3a9513ac0 --- /dev/null +++ b/queue-3.12/sunrpc-fix-a-data-corruption-issue-when-retransmitting-rpc-calls.patch @@ -0,0 +1,152 @@ +From a6b31d18b02ff9d7915c5898c9b5ca41a798cd73 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 8 Nov 2013 16:03:50 -0500 +Subject: SUNRPC: Fix a data corruption issue when retransmitting RPC calls + +From: Trond Myklebust + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..88dbbade1d7 --- /dev/null +++ b/queue-3.12/sunrpc-gss_alloc_msg-choose-_either_-a-v0-message-or-a-v1-message.patch @@ -0,0 +1,30 @@ +From 5fccc5b52ee07d07a74ce53c6f174bff81e26a16 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +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 + +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 +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d113be19ab0 --- /dev/null +++ b/queue-3.12/usb-disable-usb-2.0-link-pm-before-device-reset.patch @@ -0,0 +1,48 @@ +From dcc01c0864823f91c3bf3ffca6613e2351702b87 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 30 Sep 2013 17:26:29 +0300 +Subject: usb: Disable USB 2.0 Link PM before device reset. + +From: Sarah Sharp + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a29c1ac0648 --- /dev/null +++ b/queue-3.12/usb-don-t-enable-usb-2.0-link-pm-by-default.patch @@ -0,0 +1,366 @@ +From de68bab4fa96014cfaa6fcbcdb9750e32969fb86 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 30 Sep 2013 17:26:28 +0300 +Subject: usb: Don't enable USB 2.0 Link PM by default. + +From: Sarah Sharp + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..bc50beb38b7 --- /dev/null +++ b/queue-3.12/usb-hub-clear-port-reset-change-during-init-resume.patch @@ -0,0 +1,40 @@ +From e92aee330837e4911553761490a8fb843f2053a6 Mon Sep 17 00:00:00 2001 +From: Julius Werner +Date: Tue, 15 Oct 2013 17:45:00 -0700 +Subject: usb: hub: Clear Port Reset Change during init/resume + +From: Julius Werner + +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 +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ffcd181d1a7 --- /dev/null +++ b/queue-3.12/usb-musb-call-musb_start-only-once-in-otg-mode.patch @@ -0,0 +1,67 @@ +From ae44df2e21b50f9fff28ac75c57e399c04df812c Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 15 Oct 2013 18:29:22 +0200 +Subject: usb: musb: call musb_start() only once in OTG mode + +From: Sebastian Andrzej Siewior + +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 +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..93cc70b3618 --- /dev/null +++ b/queue-3.12/usb-musb-cancel-work-on-removal.patch @@ -0,0 +1,57 @@ +From c5340bd14336b902604ab95212a8877de109d9ae Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Thu, 10 Oct 2013 18:26:59 +0200 +Subject: usb: musb: cancel work on removal + +From: Sebastian Andrzej Siewior + +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 +|[] (unwind_backtrace+0x0/0xf4) from [] (show_stack+0x14/0x1c) +|[] (show_stack+0x14/0x1c) from [] (warn_slowpath_common+0x64/0x84) +|[] (warn_slowpath_common+0x64/0x84) from [] (warn_slowpath_fmt+0x30/0x40) +|[] (warn_slowpath_fmt+0x30/0x40) from [] (debug_print_object+0x94/0xc4) +|[] (debug_print_object+0x94/0xc4) from [] (debug_check_no_obj_freed+0x1c0/0x228) +|[] (debug_check_no_obj_freed+0x1c0/0x228) from [] (kfree+0xf8/0x228) +|[] (kfree+0xf8/0x228) from [] (release_nodes+0x1a8/0x248) +|[] (release_nodes+0x1a8/0x248) from [] (__device_release_driver+0x98/0xf0) +|[] (__device_release_driver+0x98/0xf0) from [] (device_release_driver+0x24/0x34) +|[] (device_release_driver+0x24/0x34) from [] (bus_remove_device+0x148/0x15c) +|[] (bus_remove_device+0x148/0x15c) from [] (device_del+0x104/0x1c0) +|[] (device_del+0x104/0x1c0) from [] (platform_device_del+0x18/0xac) +|[] (platform_device_del+0x18/0xac) from [] (platform_device_unregister+0xc/0x18) +|[] (platform_device_unregister+0xc/0x18) from [] (dsps_remove+0x20/0x4c [musb_dsps]) +|[] (dsps_remove+0x20/0x4c [musb_dsps]) from [] (platform_drv_remove+0x1c/0x24) +|[] (platform_drv_remove+0x1c/0x24) from [] (__device_release_driver+0x90/0xf0) +|[] (__device_release_driver+0x90/0xf0) from [] (driver_detach+0xb4/0xb8) +|[] (driver_detach+0xb4/0xb8) from [] (bus_remove_driver+0x98/0xec) +|[] (bus_remove_driver+0x98/0xec) from [] (SyS_delete_module+0x1e0/0x24c) +|[] (SyS_delete_module+0x1e0/0x24c) from [] (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 +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2660105be38 --- /dev/null +++ b/queue-3.12/usb-musb-core-properly-free-host-device-structs-in-err-path.patch @@ -0,0 +1,43 @@ +From 0d2dd7eaed1dac07b266ca2c662ff4a184a3060f Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +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 + +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 +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0c274b9205e --- /dev/null +++ b/queue-3.12/usb-musb-dsps-move-try_idle-to-start-hook.patch @@ -0,0 +1,62 @@ +From 8b9fcce2d88586b9a120ff3e039d8f42413f0bb0 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 15 Oct 2013 18:29:23 +0200 +Subject: usb: musb: dsps: move try_idle to start hook + +From: Sebastian Andrzej Siewior + +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 +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b1df1553e9b --- /dev/null +++ b/queue-3.12/usb-musb-dsps-redo-the-otg-timer.patch @@ -0,0 +1,103 @@ +From 0f901c980110cd69b63670096465b35377e73b1c Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 15 Oct 2013 18:29:25 +0200 +Subject: usb: musb: dsps: redo the otg timer + +From: Sebastian Andrzej Siewior + +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 +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1998daf44ca --- /dev/null +++ b/queue-3.12/usb-wusbcore-set-the-rpipe-wmaxpacketsize-value-correctly.patch @@ -0,0 +1,34 @@ +From 7b6bc07ab554e929c85d51b3d5b26cf7f12c6a3b Mon Sep 17 00:00:00 2001 +From: Thomas Pugliese +Date: Wed, 23 Oct 2013 14:44:26 -0500 +Subject: usb: wusbcore: set the RPIPE wMaxPacketSize value correctly + +From: Thomas Pugliese + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..785b33e2b64 --- /dev/null +++ b/queue-3.12/xhci-enable-lpm-support-only-for-hardwired-or-besl-devices.patch @@ -0,0 +1,75 @@ +From 890dae88672175f1d39f6105444d9bdc71c89258 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Mon, 30 Sep 2013 17:26:31 +0300 +Subject: xhci: Enable LPM support only for hardwired or BESL devices + +From: Mathias Nyman + +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 +Signed-off-by: Sarah Sharp +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..07ac778a20e --- /dev/null +++ b/queue-3.12/xhci-set-l1-device-slot-on-usb2-lpm-enable-disable.patch @@ -0,0 +1,69 @@ +From 58e21f73975ec927119370635bf68b9023831c56 Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Mon, 7 Oct 2013 17:17:20 -0700 +Subject: xhci: Set L1 device slot on USB2 LPM enable/disable. + +From: Sarah Sharp + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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) +