]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 May 2012 17:39:14 +0000 (02:39 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 May 2012 17:39:14 +0000 (02:39 +0900)
added patches:
ahci-detect-marvell-88se9172-sata-controller.patch
docs-update-howto-for-2.6.x-3.x-versioning.patch
hid-logitech-read-all-32-bits-of-report-type-bitfield.patch
hid-wiimote-fix-ir-data-parser.patch
libata-forbid-port-runtime-pm-by-default-fixing-regression.patch
mtd-sm_ftl-fix-typo-in-major-number.patch
um-fix-__swp_type.patch
um-implement-a-custom-pte_same-function.patch
usbhid-prevent-deadlock-during-timeout.patch

queue-3.3/ahci-detect-marvell-88se9172-sata-controller.patch [new file with mode: 0644]
queue-3.3/docs-update-howto-for-2.6.x-3.x-versioning.patch [new file with mode: 0644]
queue-3.3/hid-logitech-read-all-32-bits-of-report-type-bitfield.patch [new file with mode: 0644]
queue-3.3/hid-wiimote-fix-ir-data-parser.patch [new file with mode: 0644]
queue-3.3/libata-forbid-port-runtime-pm-by-default-fixing-regression.patch [new file with mode: 0644]
queue-3.3/mtd-sm_ftl-fix-typo-in-major-number.patch [new file with mode: 0644]
queue-3.3/series
queue-3.3/um-fix-__swp_type.patch [new file with mode: 0644]
queue-3.3/um-implement-a-custom-pte_same-function.patch [new file with mode: 0644]
queue-3.3/usbhid-prevent-deadlock-during-timeout.patch [new file with mode: 0644]

diff --git a/queue-3.3/ahci-detect-marvell-88se9172-sata-controller.patch b/queue-3.3/ahci-detect-marvell-88se9172-sata-controller.patch
new file mode 100644 (file)
index 0000000..e3d763a
--- /dev/null
@@ -0,0 +1,33 @@
+From 642d89252201c4155fc3946bf9cdea409e5d263e Mon Sep 17 00:00:00 2001
+From: Matt Johnson <johnso87@illinois.edu>
+Date: Fri, 27 Apr 2012 01:42:30 -0500
+Subject: ahci: Detect Marvell 88SE9172 SATA controller
+
+From: Matt Johnson <johnso87@illinois.edu>
+
+commit 642d89252201c4155fc3946bf9cdea409e5d263e upstream.
+
+The Marvell 88SE9172 SATA controller (PCI ID 1b4b 917a) already worked
+once it was detected, but was missing an ahci_pci_tbl entry.
+
+Boot tested on a Gigabyte Z68X-UD3H-B3 motherboard.
+
+Signed-off-by: Matt Johnson <johnso87@illinois.edu>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -386,6 +386,8 @@ static const struct pci_device_id ahci_p
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9128 */
+       { PCI_DEVICE(0x1b4b, 0x9125),
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9125 */
++      { PCI_DEVICE(0x1b4b, 0x917a),
++        .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
+       { PCI_DEVICE(0x1b4b, 0x91a3),
+         .driver_data = board_ahci_yes_fbs },
diff --git a/queue-3.3/docs-update-howto-for-2.6.x-3.x-versioning.patch b/queue-3.3/docs-update-howto-for-2.6.x-3.x-versioning.patch
new file mode 100644 (file)
index 0000000..a8d4817
--- /dev/null
@@ -0,0 +1,97 @@
+From 591bfc6bf9e5e25e464fd4c87d64afd5135667c4 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 18 Apr 2012 23:16:45 -0700
+Subject: docs: update HOWTO for 2.6.x -> 3.x versioning
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 591bfc6bf9e5e25e464fd4c87d64afd5135667c4 upstream.
+
+The HOWTO document needed updating for the new kernel versioning. The
+git URI for -next was updated as well.
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/HOWTO |   32 ++++++++++++++++----------------
+ 1 file changed, 16 insertions(+), 16 deletions(-)
+
+--- a/Documentation/HOWTO
++++ b/Documentation/HOWTO
+@@ -218,16 +218,16 @@ The development process
+ Linux kernel development process currently consists of a few different
+ main kernel "branches" and lots of different subsystem-specific kernel
+ branches.  These different branches are:
+-  - main 2.6.x kernel tree
+-  - 2.6.x.y -stable kernel tree
+-  - 2.6.x -git kernel patches
++  - main 3.x kernel tree
++  - 3.x.y -stable kernel tree
++  - 3.x -git kernel patches
+   - subsystem specific kernel trees and patches
+-  - the 2.6.x -next kernel tree for integration tests
++  - the 3.x -next kernel tree for integration tests
+-2.6.x kernel tree
++3.x kernel tree
+ -----------------
+-2.6.x kernels are maintained by Linus Torvalds, and can be found on
+-kernel.org in the pub/linux/kernel/v2.6/ directory.  Its development
++3.x kernels are maintained by Linus Torvalds, and can be found on
++kernel.org in the pub/linux/kernel/v3.x/ directory.  Its development
+ process is as follows:
+   - As soon as a new kernel is released a two weeks window is open,
+     during this period of time maintainers can submit big diffs to
+@@ -262,20 +262,20 @@ mailing list about kernel releases:
+       released according to perceived bug status, not according to a
+       preconceived timeline."
+-2.6.x.y -stable kernel tree
++3.x.y -stable kernel tree
+ ---------------------------
+-Kernels with 4-part versions are -stable kernels. They contain
++Kernels with 3-part versions are -stable kernels. They contain
+ relatively small and critical fixes for security problems or significant
+-regressions discovered in a given 2.6.x kernel.
++regressions discovered in a given 3.x kernel.
+ This is the recommended branch for users who want the most recent stable
+ kernel and are not interested in helping test development/experimental
+ versions.
+-If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
++If no 3.x.y kernel is available, then the highest numbered 3.x
+ kernel is the current stable kernel.
+-2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
++3.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
+ are released as needs dictate.  The normal release period is approximately
+ two weeks, but it can be longer if there are no pressing problems.  A
+ security-related problem, instead, can cause a release to happen almost
+@@ -285,7 +285,7 @@ The file Documentation/stable_kernel_rul
+ documents what kinds of changes are acceptable for the -stable tree, and
+ how the release process works.
+-2.6.x -git patches
++3.x -git patches
+ ------------------
+ These are daily snapshots of Linus' kernel tree which are managed in a
+ git repository (hence the name.) These patches are usually released
+@@ -317,13 +317,13 @@ revisions to it, and maintainers can mar
+ accepted, or rejected.  Most of these patchwork sites are listed at
+ http://patchwork.kernel.org/.
+-2.6.x -next kernel tree for integration tests
++3.x -next kernel tree for integration tests
+ ---------------------------------------------
+-Before updates from subsystem trees are merged into the mainline 2.6.x
++Before updates from subsystem trees are merged into the mainline 3.x
+ tree, they need to be integration-tested.  For this purpose, a special
+ testing repository exists into which virtually all subsystem trees are
+ pulled on an almost daily basis:
+-      http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
++      http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
+       http://linux.f-seidel.de/linux-next/pmwiki/
+ This way, the -next kernel gives a summary outlook onto what will be
diff --git a/queue-3.3/hid-logitech-read-all-32-bits-of-report-type-bitfield.patch b/queue-3.3/hid-logitech-read-all-32-bits-of-report-type-bitfield.patch
new file mode 100644 (file)
index 0000000..d53b391
--- /dev/null
@@ -0,0 +1,67 @@
+From 44d27f7dfedd9aadc082cda31462f6600f56e4ec Mon Sep 17 00:00:00 2001
+From: Jonathan Nieder <jrnieder@gmail.com>
+Date: Fri, 11 May 2012 16:17:16 +0200
+Subject: HID: logitech: read all 32 bits of report type bitfield
+
+From: Jonathan Nieder <jrnieder@gmail.com>
+
+commit 44d27f7dfedd9aadc082cda31462f6600f56e4ec upstream.
+
+On big-endian systems (e.g., Apple PowerBook), trying to use a
+logitech wireless mouse with the Logitech Unifying Receiver does not
+work with v3.2 and later kernels.  The device doesn't show up in
+/dev/input.  Older kernels work fine.
+
+That is because the new hid-logitech-dj driver claims the device.  The
+device arrival notification appears:
+
+       20 00 41 02 00 00 00 00 00 00 00 00 00 00 00
+
+and we read the report_types bitfield (02 00 00 00) to find out what
+kind of device it is.  Unfortunately the driver only reads the first 8
+bits and treats that value as a 32-bit little-endian number, so on a
+powerpc the report type seems to be 0x02000000 and is not recognized.
+
+Even on little-endian machines, connecting a media center remote
+control (report type 00 01 00 00) with this driver loaded would
+presumably fail for the same reason.
+
+Fix both problems by using get_unaligned_le32() to read all four
+bytes, which is a little clearer anyway.  After this change, the
+wireless mouse works on Hugo's PowerBook again.
+
+Based on a patch by Nestor Lopez Casado.
+Addresses http://bugs.debian.org/671292
+
+Reported-by: Hugo Osvaldo Barrera <hugo@osvaldobarrera.com.ar>
+Inspired-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
+Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
+Signed-off-by: Nestor Lopez Casado <nlopezcasad@logitech.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-logitech-dj.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -26,6 +26,7 @@
+ #include <linux/hid.h>
+ #include <linux/module.h>
+ #include <linux/usb.h>
++#include <asm/unaligned.h>
+ #include "usbhid/usbhid.h"
+ #include "hid-ids.h"
+ #include "hid-logitech-dj.h"
+@@ -265,8 +266,8 @@ static void logi_dj_recv_add_djhid_devic
+               goto dj_device_allocate_fail;
+       }
+-      dj_dev->reports_supported = le32_to_cpu(
+-              dj_report->report_params[DEVICE_PAIRED_RF_REPORT_TYPE]);
++      dj_dev->reports_supported = get_unaligned_le32(
++              dj_report->report_params + DEVICE_PAIRED_RF_REPORT_TYPE);
+       dj_dev->hdev = dj_hiddev;
+       dj_dev->dj_receiver_dev = djrcv_dev;
+       dj_dev->device_index = dj_report->device_index;
diff --git a/queue-3.3/hid-wiimote-fix-ir-data-parser.patch b/queue-3.3/hid-wiimote-fix-ir-data-parser.patch
new file mode 100644 (file)
index 0000000..86eda22
--- /dev/null
@@ -0,0 +1,57 @@
+From 74b89e8a3625c17c7452532dfb997ac4f1a38751 Mon Sep 17 00:00:00 2001
+From: David Herrmann <dh.herrmann@googlemail.com>
+Date: Tue, 8 May 2012 16:52:31 +0200
+Subject: HID: wiimote: Fix IR data parser
+
+From: David Herrmann <dh.herrmann@googlemail.com>
+
+commit 74b89e8a3625c17c7452532dfb997ac4f1a38751 upstream.
+
+We incorrectly parse incoming IR data. The extra byte contains the upper
+bits and not the lower bits of the x/y coordinates. User-space expects
+absolute position data from us so this patch does not break existing
+applications. On the contrary, it extends the virtual view and fixes
+garbage reports for margin areas of the virtual screen.
+
+Reported-by: Peter Bukovsky <bukovsky.peter@gmail.com>
+Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-wiimote-core.c |   16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+--- a/drivers/hid/hid-wiimote-core.c
++++ b/drivers/hid/hid-wiimote-core.c
+@@ -769,7 +769,7 @@ static void __ir_to_input(struct wiimote
+       /*
+        * Basic IR data is encoded into 3 bytes. The first two bytes are the
+-       * upper 8 bit of the X/Y data, the 3rd byte contains the lower 2 bits
++       * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits
+        * of both.
+        * If data is packed, then the 3rd byte is put first and slightly
+        * reordered. This allows to interleave packed and non-packed data to
+@@ -778,17 +778,11 @@ static void __ir_to_input(struct wiimote
+        */
+       if (packed) {
+-              x = ir[1] << 2;
+-              y = ir[2] << 2;
+-
+-              x |= ir[0] & 0x3;
+-              y |= (ir[0] >> 2) & 0x3;
++              x = ir[1] | ((ir[0] & 0x03) << 8);
++              y = ir[2] | ((ir[0] & 0x0c) << 6);
+       } else {
+-              x = ir[0] << 2;
+-              y = ir[1] << 2;
+-
+-              x |= (ir[2] >> 4) & 0x3;
+-              y |= (ir[2] >> 6) & 0x3;
++              x = ir[0] | ((ir[2] & 0x30) << 4);
++              y = ir[1] | ((ir[2] & 0xc0) << 2);
+       }
+       input_report_abs(wdata->ir, xid, x);
diff --git a/queue-3.3/libata-forbid-port-runtime-pm-by-default-fixing-regression.patch b/queue-3.3/libata-forbid-port-runtime-pm-by-default-fixing-regression.patch
new file mode 100644 (file)
index 0000000..df7f78b
--- /dev/null
@@ -0,0 +1,32 @@
+From 0c8d32c27f5cf6e14ca14b4758d1e994eebd50fd Mon Sep 17 00:00:00 2001
+From: Lin Ming <ming.m.lin@intel.com>
+Date: Wed, 18 Apr 2012 09:29:47 +0800
+Subject: libata: forbid port runtime pm by default, fixing regression
+
+From: Lin Ming <ming.m.lin@intel.com>
+
+commit 0c8d32c27f5cf6e14ca14b4758d1e994eebd50fd upstream.
+
+Forbid port runtime pm by default because it has known hotplug issue.
+User can allow it by, for example
+
+echo auto > /sys/devices/pci0000:00/0000:00:1f.2/ata2/power/control
+
+Signed-off-by: Lin Ming <ming.m.lin@intel.com>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/libata-transport.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/ata/libata-transport.c
++++ b/drivers/ata/libata-transport.c
+@@ -294,6 +294,7 @@ int ata_tport_add(struct device *parent,
+       device_enable_async_suspend(dev);
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
++      pm_runtime_forbid(dev);
+       transport_add_device(dev);
+       transport_configure_device(dev);
diff --git a/queue-3.3/mtd-sm_ftl-fix-typo-in-major-number.patch b/queue-3.3/mtd-sm_ftl-fix-typo-in-major-number.patch
new file mode 100644 (file)
index 0000000..3ff1e63
--- /dev/null
@@ -0,0 +1,31 @@
+From 452380efbd72d8d41f53ea64c8a6ea1fedc4394d Mon Sep 17 00:00:00 2001
+From: Maxim Levitsky <maximlevitsky@gmail.com>
+Date: Sat, 17 Mar 2012 20:16:53 +0200
+Subject: mtd: sm_ftl: fix typo in major number.
+
+From: Maxim Levitsky <maximlevitsky@gmail.com>
+
+commit 452380efbd72d8d41f53ea64c8a6ea1fedc4394d upstream.
+
+major == 0 allocates dynamic major, not major == -1
+
+Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/sm_ftl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/sm_ftl.c
++++ b/drivers/mtd/sm_ftl.c
+@@ -1256,7 +1256,7 @@ static void sm_remove_dev(struct mtd_blk
+ static struct mtd_blktrans_ops sm_ftl_ops = {
+       .name           = "smblk",
+-      .major          = -1,
++      .major          = 0,
+       .part_bits      = SM_FTL_PARTN_BITS,
+       .blksize        = SM_SECTOR_SIZE,
+       .getgeo         = sm_getgeo,
index ab3c2c151b5af8b7626544f235ca8ffec94da61d..41da1e25c9c64ff3515040ee8ebf596b124942bd 100644 (file)
@@ -25,3 +25,12 @@ selinux-if-sel_make_bools-errors-don-t-leave-inconsistent-state.patch
 ib-core-fix-mismatch-between-locked-and-pinned-pages.patch
 drivers-staging-comedi-comedi_fops.c-add-missing-vfree.patch
 perf-x86-update-event-scheduling-constraints-for-amd-family-15h-models.patch
+mtd-sm_ftl-fix-typo-in-major-number.patch
+libata-forbid-port-runtime-pm-by-default-fixing-regression.patch
+ahci-detect-marvell-88se9172-sata-controller.patch
+hid-wiimote-fix-ir-data-parser.patch
+usbhid-prevent-deadlock-during-timeout.patch
+hid-logitech-read-all-32-bits-of-report-type-bitfield.patch
+um-fix-__swp_type.patch
+um-implement-a-custom-pte_same-function.patch
+docs-update-howto-for-2.6.x-3.x-versioning.patch
diff --git a/queue-3.3/um-fix-__swp_type.patch b/queue-3.3/um-fix-__swp_type.patch
new file mode 100644 (file)
index 0000000..8533ebc
--- /dev/null
@@ -0,0 +1,37 @@
+From 2b76ebaa728f8a3967c52aa189261c72fe56a6f1 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Sat, 14 Apr 2012 17:46:01 +0200
+Subject: um: Fix __swp_type()
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 2b76ebaa728f8a3967c52aa189261c72fe56a6f1 upstream.
+
+The current __swp_type() function uses a too small bitshift.
+Using more than one swap files causes bad pages because
+the type bits clash with other page flags.
+
+Analyzed-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/um/include/asm/pgtable.h |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/um/include/asm/pgtable.h
++++ b/arch/um/include/asm/pgtable.h
+@@ -346,11 +346,11 @@ extern pte_t *virt_to_pte(struct mm_stru
+ #define update_mmu_cache(vma,address,ptep) do ; while (0)
+ /* Encode and de-code a swap entry */
+-#define __swp_type(x)                 (((x).val >> 4) & 0x3f)
++#define __swp_type(x)                 (((x).val >> 5) & 0x1f)
+ #define __swp_offset(x)                       ((x).val >> 11)
+ #define __swp_entry(type, offset) \
+-      ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
++      ((swp_entry_t) { ((type) << 5) | ((offset) << 11) })
+ #define __pte_to_swp_entry(pte) \
+       ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+ #define __swp_entry_to_pte(x)         ((pte_t) { (x).val })
diff --git a/queue-3.3/um-implement-a-custom-pte_same-function.patch b/queue-3.3/um-implement-a-custom-pte_same-function.patch
new file mode 100644 (file)
index 0000000..1306fad
--- /dev/null
@@ -0,0 +1,39 @@
+From f15b9000eb1d09bbaa4b0a6b2089d7e1f64e84b3 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Sat, 14 Apr 2012 17:29:30 +0200
+Subject: um: Implement a custom pte_same() function
+
+From: Richard Weinberger <richard@nod.at>
+
+commit f15b9000eb1d09bbaa4b0a6b2089d7e1f64e84b3 upstream.
+
+UML uses the _PAGE_NEWPAGE flag to mark pages which are not jet
+installed on the host side using mmap().
+pte_same() has to ignore this flag, otherwise unuse_pte_range()
+is unable to unuse the page because two identical
+page tables entries with different _PAGE_NEWPAGE flags would not
+match and swapoff() would never return.
+
+Analyzed-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/um/include/asm/pgtable.h |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/um/include/asm/pgtable.h
++++ b/arch/um/include/asm/pgtable.h
+@@ -271,6 +271,12 @@ static inline void set_pte(pte_t *pteptr
+ }
+ #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
++#define __HAVE_ARCH_PTE_SAME
++static inline int pte_same(pte_t pte_a, pte_t pte_b)
++{
++      return !((pte_val(pte_a) ^ pte_val(pte_b)) & ~_PAGE_NEWPAGE);
++}
++
+ /*
+  * Conversion functions: convert a page and protection to a page entry,
+  * and a page entry and page directory to the page they refer to.
diff --git a/queue-3.3/usbhid-prevent-deadlock-during-timeout.patch b/queue-3.3/usbhid-prevent-deadlock-during-timeout.patch
new file mode 100644 (file)
index 0000000..29acc43
--- /dev/null
@@ -0,0 +1,187 @@
+From 8815bb09af21316aeb5f8948b24ac62181670db2 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver@neukum.org>
+Date: Mon, 30 Apr 2012 09:13:46 +0200
+Subject: usbhid: prevent deadlock during timeout
+
+From: Oliver Neukum <oliver@neukum.org>
+
+commit 8815bb09af21316aeb5f8948b24ac62181670db2 upstream.
+
+On some HCDs usb_unlink_urb() can directly call the
+completion handler. That limits the spinlocks that can
+be taken in the handler to locks not held while calling
+usb_unlink_urb()
+To prevent a race with resubmission, this patch exposes
+usbcore's infrastructure for blocking submission, uses it
+and so drops the lock without causing a race in usbhid.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Acked-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/usbhid/hid-core.c |   61 +++++++++++++++++++++++++++++++++++++-----
+ drivers/usb/core/urb.c        |   21 ++++++++++++++
+ include/linux/usb.h           |    3 ++
+ 3 files changed, 79 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/usbhid/hid-core.c
++++ b/drivers/hid/usbhid/hid-core.c
+@@ -399,6 +399,16 @@ static int hid_submit_ctrl(struct hid_de
+  * Output interrupt completion handler.
+  */
++static int irq_out_pump_restart(struct hid_device *hid)
++{
++      struct usbhid_device *usbhid = hid->driver_data;
++
++      if (usbhid->outhead != usbhid->outtail)
++              return hid_submit_out(hid);
++      else
++              return -1;
++}
++
+ static void hid_irq_out(struct urb *urb)
+ {
+       struct hid_device *hid = urb->context;
+@@ -428,7 +438,7 @@ static void hid_irq_out(struct urb *urb)
+       else
+               usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
+-      if (usbhid->outhead != usbhid->outtail && !hid_submit_out(hid)) {
++      if (!irq_out_pump_restart(hid)) {
+               /* Successfully submitted next urb in queue */
+               spin_unlock_irqrestore(&usbhid->lock, flags);
+               return;
+@@ -443,6 +453,15 @@ static void hid_irq_out(struct urb *urb)
+ /*
+  * Control pipe completion handler.
+  */
++static int ctrl_pump_restart(struct hid_device *hid)
++{
++      struct usbhid_device *usbhid = hid->driver_data;
++
++      if (usbhid->ctrlhead != usbhid->ctrltail)
++              return hid_submit_ctrl(hid);
++      else
++              return -1;
++}
+ static void hid_ctrl(struct urb *urb)
+ {
+@@ -476,7 +495,7 @@ static void hid_ctrl(struct urb *urb)
+       else
+               usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
+-      if (usbhid->ctrlhead != usbhid->ctrltail && !hid_submit_ctrl(hid)) {
++      if (!ctrl_pump_restart(hid)) {
+               /* Successfully submitted next urb in queue */
+               spin_unlock(&usbhid->lock);
+               return;
+@@ -535,11 +554,27 @@ static void __usbhid_submit_report(struc
+                        * the queue is known to run
+                        * but an earlier request may be stuck
+                        * we may need to time out
+-                       * no race because this is called under
++                       * no race because the URB is blocked under
+                        * spinlock
+                        */
+-                      if (time_after(jiffies, usbhid->last_out + HZ * 5))
++                      if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
++                              usb_block_urb(usbhid->urbout);
++                              /* drop lock to not deadlock if the callback is called */
++                              spin_unlock(&usbhid->lock);
+                               usb_unlink_urb(usbhid->urbout);
++                              spin_lock(&usbhid->lock);
++                              usb_unblock_urb(usbhid->urbout);
++                              /*
++                               * if the unlinking has already completed
++                               * the pump will have been stopped
++                               * it must be restarted now
++                               */
++                              if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
++                                      if (!irq_out_pump_restart(hid))
++                                              set_bit(HID_OUT_RUNNING, &usbhid->iofl);
++
++
++                      }
+               }
+               return;
+       }
+@@ -583,11 +618,25 @@ static void __usbhid_submit_report(struc
+                * the queue is known to run
+                * but an earlier request may be stuck
+                * we may need to time out
+-               * no race because this is called under
++               * no race because the URB is blocked under
+                * spinlock
+                */
+-              if (time_after(jiffies, usbhid->last_ctrl + HZ * 5))
++              if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
++                      usb_block_urb(usbhid->urbctrl);
++                      /* drop lock to not deadlock if the callback is called */
++                      spin_unlock(&usbhid->lock);
+                       usb_unlink_urb(usbhid->urbctrl);
++                      spin_lock(&usbhid->lock);
++                      usb_unblock_urb(usbhid->urbctrl);
++                      /*
++                       * if the unlinking has already completed
++                       * the pump will have been stopped
++                       * it must be restarted now
++                       */
++                      if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
++                              if (!ctrl_pump_restart(hid))
++                                      set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
++              }
+       }
+ }
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -671,6 +671,27 @@ void usb_unpoison_urb(struct urb *urb)
+ EXPORT_SYMBOL_GPL(usb_unpoison_urb);
+ /**
++ * usb_block_urb - reliably prevent further use of an URB
++ * @urb: pointer to URB to be blocked, may be NULL
++ *
++ * After the routine has run, attempts to resubmit the URB will fail
++ * with error -EPERM.  Thus even if the URB's completion handler always
++ * tries to resubmit, it will not succeed and the URB will become idle.
++ *
++ * The URB must not be deallocated while this routine is running.  In
++ * particular, when a driver calls this routine, it must insure that the
++ * completion handler cannot deallocate the URB.
++ */
++void usb_block_urb(struct urb *urb)
++{
++      if (!urb)
++              return;
++
++      atomic_inc(&urb->reject);
++}
++EXPORT_SYMBOL_GPL(usb_block_urb);
++
++/**
+  * usb_kill_anchored_urbs - cancel transfer requests en masse
+  * @anchor: anchor the requests are bound to
+  *
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1371,6 +1371,7 @@ extern int usb_unlink_urb(struct urb *ur
+ extern void usb_kill_urb(struct urb *urb);
+ extern void usb_poison_urb(struct urb *urb);
+ extern void usb_unpoison_urb(struct urb *urb);
++extern void usb_block_urb(struct urb *urb);
+ extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
+ extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
+ extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
+@@ -1383,6 +1384,8 @@ extern struct urb *usb_get_from_anchor(s
+ extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor);
+ extern int usb_anchor_empty(struct usb_anchor *anchor);
++#define usb_unblock_urb       usb_unpoison_urb
++
+ /**
+  * usb_urb_dir_in - check if an URB describes an IN transfer
+  * @urb: URB to be checked