From: Greg Kroah-Hartman Date: Thu, 24 May 2012 17:39:14 +0000 (+0900) Subject: 3.3-stable patches X-Git-Tag: v3.0.33~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=898f26e7f5b166847e3157ceb7907580e2035e80;p=thirdparty%2Fkernel%2Fstable-queue.git 3.3-stable patches 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 --- 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 index 00000000000..e3d763a765e --- /dev/null +++ b/queue-3.3/ahci-detect-marvell-88se9172-sata-controller.patch @@ -0,0 +1,33 @@ +From 642d89252201c4155fc3946bf9cdea409e5d263e Mon Sep 17 00:00:00 2001 +From: Matt Johnson +Date: Fri, 27 Apr 2012 01:42:30 -0500 +Subject: ahci: Detect Marvell 88SE9172 SATA controller + +From: Matt Johnson + +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 +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a8d4817ee6a --- /dev/null +++ b/queue-3.3/docs-update-howto-for-2.6.x-3.x-versioning.patch @@ -0,0 +1,97 @@ +From 591bfc6bf9e5e25e464fd4c87d64afd5135667c4 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Wed, 18 Apr 2012 23:16:45 -0700 +Subject: docs: update HOWTO for 2.6.x -> 3.x versioning + +From: Kees Cook + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 , and ++3.x.y are maintained by the "stable" team , 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 index 00000000000..d53b391e7bc --- /dev/null +++ b/queue-3.3/hid-logitech-read-all-32-bits-of-report-type-bitfield.patch @@ -0,0 +1,67 @@ +From 44d27f7dfedd9aadc082cda31462f6600f56e4ec Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder +Date: Fri, 11 May 2012 16:17:16 +0200 +Subject: HID: logitech: read all 32 bits of report type bitfield + +From: Jonathan Nieder + +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 +Inspired-by: Nestor Lopez Casado +Signed-off-by: Jonathan Nieder +Signed-off-by: Nestor Lopez Casado +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #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 index 00000000000..86eda227b4b --- /dev/null +++ b/queue-3.3/hid-wiimote-fix-ir-data-parser.patch @@ -0,0 +1,57 @@ +From 74b89e8a3625c17c7452532dfb997ac4f1a38751 Mon Sep 17 00:00:00 2001 +From: David Herrmann +Date: Tue, 8 May 2012 16:52:31 +0200 +Subject: HID: wiimote: Fix IR data parser + +From: David Herrmann + +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 +Signed-off-by: David Herrmann +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..df7f78b8869 --- /dev/null +++ b/queue-3.3/libata-forbid-port-runtime-pm-by-default-fixing-regression.patch @@ -0,0 +1,32 @@ +From 0c8d32c27f5cf6e14ca14b4758d1e994eebd50fd Mon Sep 17 00:00:00 2001 +From: Lin Ming +Date: Wed, 18 Apr 2012 09:29:47 +0800 +Subject: libata: forbid port runtime pm by default, fixing regression + +From: Lin Ming + +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 +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3ff1e638c0d --- /dev/null +++ b/queue-3.3/mtd-sm_ftl-fix-typo-in-major-number.patch @@ -0,0 +1,31 @@ +From 452380efbd72d8d41f53ea64c8a6ea1fedc4394d Mon Sep 17 00:00:00 2001 +From: Maxim Levitsky +Date: Sat, 17 Mar 2012 20:16:53 +0200 +Subject: mtd: sm_ftl: fix typo in major number. + +From: Maxim Levitsky + +commit 452380efbd72d8d41f53ea64c8a6ea1fedc4394d upstream. + +major == 0 allocates dynamic major, not major == -1 + +Signed-off-by: Maxim Levitsky +Signed-off-by: Artem Bityutskiy +Signed-off-by: David Woodhouse +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-3.3/series b/queue-3.3/series index ab3c2c151b5..41da1e25c9c 100644 --- a/queue-3.3/series +++ b/queue-3.3/series @@ -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 index 00000000000..8533ebcaa93 --- /dev/null +++ b/queue-3.3/um-fix-__swp_type.patch @@ -0,0 +1,37 @@ +From 2b76ebaa728f8a3967c52aa189261c72fe56a6f1 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Sat, 14 Apr 2012 17:46:01 +0200 +Subject: um: Fix __swp_type() + +From: Richard Weinberger + +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 +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1306fad4c34 --- /dev/null +++ b/queue-3.3/um-implement-a-custom-pte_same-function.patch @@ -0,0 +1,39 @@ +From f15b9000eb1d09bbaa4b0a6b2089d7e1f64e84b3 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Sat, 14 Apr 2012 17:29:30 +0200 +Subject: um: Implement a custom pte_same() function + +From: Richard Weinberger + +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 +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..29acc43d10f --- /dev/null +++ b/queue-3.3/usbhid-prevent-deadlock-during-timeout.patch @@ -0,0 +1,187 @@ +From 8815bb09af21316aeb5f8948b24ac62181670db2 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Mon, 30 Apr 2012 09:13:46 +0200 +Subject: usbhid: prevent deadlock during timeout + +From: Oliver Neukum + +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 +Acked-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + 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