]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Jan 2013 21:25:08 +0000 (13:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Jan 2013 21:25:08 +0000 (13:25 -0800)
added patches:
cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch
freezer-add-missing-mb-s-to-freezer_count-and-freezer_should_skip.patch
genirq-always-force-thread-affinity.patch
input-sentelic-only-report-position-of-first-finger-as-st-coordinates.patch
input-walkera0701-fix-crash-on-startup.patch
usb-host-xhci-stricter-conditional-for-z1-system-models-for-compliance-mode-patch.patch
usb-musb-cppi_dma-export-cppi_interrupt.patch
xhci-add-lynx-point-lp-to-list-of-intel-switchable-hosts.patch
xhci-fix-conditional-check-in-bandwidth-calculation.patch
xhci-fix-null-pointer-dereference-when-destroying-half-built-segment-rings.patch
xhci-fix-td-size-calculation-on-1.0-hosts.patch

12 files changed:
queue-3.4/cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch [new file with mode: 0644]
queue-3.4/freezer-add-missing-mb-s-to-freezer_count-and-freezer_should_skip.patch [new file with mode: 0644]
queue-3.4/genirq-always-force-thread-affinity.patch [new file with mode: 0644]
queue-3.4/input-sentelic-only-report-position-of-first-finger-as-st-coordinates.patch [new file with mode: 0644]
queue-3.4/input-walkera0701-fix-crash-on-startup.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/usb-host-xhci-stricter-conditional-for-z1-system-models-for-compliance-mode-patch.patch [new file with mode: 0644]
queue-3.4/usb-musb-cppi_dma-export-cppi_interrupt.patch [new file with mode: 0644]
queue-3.4/xhci-add-lynx-point-lp-to-list-of-intel-switchable-hosts.patch [new file with mode: 0644]
queue-3.4/xhci-fix-conditional-check-in-bandwidth-calculation.patch [new file with mode: 0644]
queue-3.4/xhci-fix-null-pointer-dereference-when-destroying-half-built-segment-rings.patch [new file with mode: 0644]
queue-3.4/xhci-fix-td-size-calculation-on-1.0-hosts.patch [new file with mode: 0644]

diff --git a/queue-3.4/cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch b/queue-3.4/cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch
new file mode 100644 (file)
index 0000000..d10a632
--- /dev/null
@@ -0,0 +1,69 @@
+From 175431635ec09b1d1bba04979b006b99e8305a83 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 19 Nov 2012 08:13:35 -0800
+Subject: cgroup: remove incorrect dget/dput() pair in cgroup_create_dir()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 175431635ec09b1d1bba04979b006b99e8305a83 upstream.
+
+cgroup_create_dir() does weird dancing with dentry refcnt.  On
+success, it gets and then puts it achieving nothing.  On failure, it
+puts but there isn't no matching get anywhere leading to the following
+oops if cgroup_create_file() fails for whatever reason.
+
+  ------------[ cut here ]------------
+  kernel BUG at /work/os/work/fs/dcache.c:552!
+  invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
+  Modules linked in:
+  CPU 2
+  Pid: 697, comm: mkdir Not tainted 3.7.0-rc4-work+ #3 Bochs Bochs
+  RIP: 0010:[<ffffffff811d9c0c>]  [<ffffffff811d9c0c>] dput+0x1dc/0x1e0
+  RSP: 0018:ffff88001a3ebef8  EFLAGS: 00010246
+  RAX: 0000000000000000 RBX: ffff88000e5b1ef8 RCX: 0000000000000403
+  RDX: 0000000000000303 RSI: 2000000000000000 RDI: ffff88000e5b1f58
+  RBP: ffff88001a3ebf18 R08: ffffffff82c76960 R09: 0000000000000001
+  R10: ffff880015022080 R11: ffd9bed70f48a041 R12: 00000000ffffffea
+  R13: 0000000000000001 R14: ffff88000e5b1f58 R15: 00007fff57656d60
+  FS:  00007ff05fcb3800(0000) GS:ffff88001fd00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00000000004046f0 CR3: 000000001315f000 CR4: 00000000000006e0
+  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+  DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
+  Process mkdir (pid: 697, threadinfo ffff88001a3ea000, task ffff880015022080)
+  Stack:
+   ffff88001a3ebf48 00000000ffffffea 0000000000000001 0000000000000000
+   ffff88001a3ebf38 ffffffff811cc889 0000000000000001 ffff88000e5b1ef8
+   ffff88001a3ebf68 ffffffff811d1fc9 ffff8800198d7f18 ffff880019106ef8
+  Call Trace:
+   [<ffffffff811cc889>] done_path_create+0x19/0x50
+   [<ffffffff811d1fc9>] sys_mkdirat+0x59/0x80
+   [<ffffffff811d2009>] sys_mkdir+0x19/0x20
+   [<ffffffff81be1e02>] system_call_fastpath+0x16/0x1b
+  Code: 00 48 8d 90 18 01 00 00 48 89 93 c0 00 00 00 4c 89 a0 18 01 00 00 48 8b 83 a0 00 00 00 83 80 28 01 00 00 01 e8 e6 6f a0 00 eb 92 <0f> 0b 66 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 49 89 fe 41
+  RIP  [<ffffffff811d9c0c>] dput+0x1dc/0x1e0
+   RSP <ffff88001a3ebef8>
+  ---[ end trace 1277bcfd9561ddb0 ]---
+
+Fix it by dropping the unnecessary dget/dput() pair.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Acked-by: Li Zefan <lizefan@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/cgroup.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -2568,9 +2568,7 @@ static int cgroup_create_dir(struct cgro
+               dentry->d_fsdata = cgrp;
+               inc_nlink(parent->d_inode);
+               rcu_assign_pointer(cgrp->dentry, dentry);
+-              dget(dentry);
+       }
+-      dput(dentry);
+       return error;
+ }
diff --git a/queue-3.4/freezer-add-missing-mb-s-to-freezer_count-and-freezer_should_skip.patch b/queue-3.4/freezer-add-missing-mb-s-to-freezer_count-and-freezer_should_skip.patch
new file mode 100644 (file)
index 0000000..1f867c3
--- /dev/null
@@ -0,0 +1,107 @@
+From dd67d32dbc5de299d70cc9e10c6c1e29ffa56b92 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Tue, 16 Oct 2012 15:03:14 -0700
+Subject: freezer: add missing mb's to freezer_count() and freezer_should_skip()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit dd67d32dbc5de299d70cc9e10c6c1e29ffa56b92 upstream.
+
+A task is considered frozen enough between freezer_do_not_count() and
+freezer_count() and freezers use freezer_should_skip() to test this
+condition.  This supposedly works because freezer_count() always calls
+try_to_freezer() after clearing %PF_FREEZER_SKIP.
+
+However, there currently is nothing which guarantees that
+freezer_count() sees %true freezing() after clearing %PF_FREEZER_SKIP
+when freezing is in progress, and vice-versa.  A task can escape the
+freezing condition in effect by freezer_count() seeing !freezing() and
+freezer_should_skip() seeing %PF_FREEZER_SKIP.
+
+This patch adds smp_mb()'s to freezer_count() and
+freezer_should_skip() such that either %true freezing() is visible to
+freezer_count() or !PF_FREEZER_SKIP is visible to
+freezer_should_skip().
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/freezer.h |   50 ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 42 insertions(+), 8 deletions(-)
+
+--- a/include/linux/freezer.h
++++ b/include/linux/freezer.h
+@@ -75,28 +75,62 @@ static inline bool cgroup_freezing(struc
+  */
+-/* Tell the freezer not to count the current task as freezable. */
++/**
++ * freezer_do_not_count - tell freezer to ignore %current
++ *
++ * Tell freezers to ignore the current task when determining whether the
++ * target frozen state is reached.  IOW, the current task will be
++ * considered frozen enough by freezers.
++ *
++ * The caller shouldn't do anything which isn't allowed for a frozen task
++ * until freezer_cont() is called.  Usually, freezer[_do_not]_count() pair
++ * wrap a scheduling operation and nothing much else.
++ */
+ static inline void freezer_do_not_count(void)
+ {
+       current->flags |= PF_FREEZER_SKIP;
+ }
+-/*
+- * Tell the freezer to count the current task as freezable again and try to
+- * freeze it.
++/**
++ * freezer_count - tell freezer to stop ignoring %current
++ *
++ * Undo freezer_do_not_count().  It tells freezers that %current should be
++ * considered again and tries to freeze if freezing condition is already in
++ * effect.
+  */
+ static inline void freezer_count(void)
+ {
+       current->flags &= ~PF_FREEZER_SKIP;
++      /*
++       * If freezing is in progress, the following paired with smp_mb()
++       * in freezer_should_skip() ensures that either we see %true
++       * freezing() or freezer_should_skip() sees !PF_FREEZER_SKIP.
++       */
++      smp_mb();
+       try_to_freeze();
+ }
+-/*
+- * Check if the task should be counted as freezable by the freezer
++/**
++ * freezer_should_skip - whether to skip a task when determining frozen
++ *                     state is reached
++ * @p: task in quesion
++ *
++ * This function is used by freezers after establishing %true freezing() to
++ * test whether a task should be skipped when determining the target frozen
++ * state is reached.  IOW, if this function returns %true, @p is considered
++ * frozen enough.
+  */
+-static inline int freezer_should_skip(struct task_struct *p)
++static inline bool freezer_should_skip(struct task_struct *p)
+ {
+-      return !!(p->flags & PF_FREEZER_SKIP);
++      /*
++       * The following smp_mb() paired with the one in freezer_count()
++       * ensures that either freezer_count() sees %true freezing() or we
++       * see cleared %PF_FREEZER_SKIP and return %false.  This makes it
++       * impossible for a task to slip frozen state testing after
++       * clearing %PF_FREEZER_SKIP.
++       */
++      smp_mb();
++      return p->flags & PF_FREEZER_SKIP;
+ }
+ /*
diff --git a/queue-3.4/genirq-always-force-thread-affinity.patch b/queue-3.4/genirq-always-force-thread-affinity.patch
new file mode 100644 (file)
index 0000000..2613017
--- /dev/null
@@ -0,0 +1,83 @@
+From 04aa530ec04f61875b99c12721162e2964e3318c Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sat, 3 Nov 2012 11:52:09 +0100
+Subject: genirq: Always force thread affinity
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 04aa530ec04f61875b99c12721162e2964e3318c upstream.
+
+Sankara reported that the genirq core code fails to adjust the
+affinity of an interrupt thread in several cases:
+
+ 1) On request/setup_irq() the call to setup_affinity() happens before
+    the new action is registered, so the new thread is not notified.
+
+ 2) For secondary shared interrupts nothing notifies the new thread to
+    change its affinity.
+
+ 3) Interrupts which have the IRQ_NO_BALANCE flag set are not moving
+    the thread either.
+
+Fix this by setting the thread affinity flag right on thread creation
+time. This ensures that under all circumstances the thread moves to
+the right place. Requires a check in irq_thread_check_affinity for an
+existing affinity mask (CONFIG_CPU_MASK_OFFSTACK=y)
+
+Reported-and-tested-by: Sankara Muthukrishnan <sankara.m@gmail.com>
+Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1209041738200.2754@ionos
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/manage.c |   23 +++++++++++++++++++++--
+ 1 file changed, 21 insertions(+), 2 deletions(-)
+
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -708,6 +708,7 @@ static void
+ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action)
+ {
+       cpumask_var_t mask;
++      bool valid = true;
+       if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags))
+               return;
+@@ -722,10 +723,18 @@ irq_thread_check_affinity(struct irq_des
+       }
+       raw_spin_lock_irq(&desc->lock);
+-      cpumask_copy(mask, desc->irq_data.affinity);
++      /*
++       * This code is triggered unconditionally. Check the affinity
++       * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
++       */
++      if (desc->irq_data.affinity)
++              cpumask_copy(mask, desc->irq_data.affinity);
++      else
++              valid = false;
+       raw_spin_unlock_irq(&desc->lock);
+-      set_cpus_allowed_ptr(current, mask);
++      if (valid)
++              set_cpus_allowed_ptr(current, mask);
+       free_cpumask_var(mask);
+ }
+ #else
+@@ -933,6 +942,16 @@ __setup_irq(unsigned int irq, struct irq
+                */
+               get_task_struct(t);
+               new->thread = t;
++              /*
++               * Tell the thread to set its affinity. This is
++               * important for shared interrupt handlers as we do
++               * not invoke setup_affinity() for the secondary
++               * handlers as everything is already set up. Even for
++               * interrupts marked with IRQF_NO_BALANCE this is
++               * correct as we want the thread to move to the cpu(s)
++               * on which the requesting code placed the interrupt.
++               */
++              set_bit(IRQTF_AFFINITY, &new->thread_flags);
+       }
+       if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
diff --git a/queue-3.4/input-sentelic-only-report-position-of-first-finger-as-st-coordinates.patch b/queue-3.4/input-sentelic-only-report-position-of-first-finger-as-st-coordinates.patch
new file mode 100644 (file)
index 0000000..6fde00f
--- /dev/null
@@ -0,0 +1,34 @@
+From a25461659050b913e114d282bf58823682eb56b6 Mon Sep 17 00:00:00 2001
+From: Christophe TORDEUX <christophe@tordeux.net>
+Date: Mon, 24 Dec 2012 09:20:40 -0800
+Subject: Input: sentelic - only report position of first finger as ST coordinates
+
+From: Christophe TORDEUX <christophe@tordeux.net>
+
+commit a25461659050b913e114d282bf58823682eb56b6 upstream.
+
+Report only the position of the first finger as absolute non-MT coordinates,
+instead of reporting both fingers alternatively. Actual MT events are
+unaffected.
+
+This fixes horizontal and improves vertical scrolling with the touchpad.
+
+Signed-off-by: Christophe TORDEUX <christophe@tordeux.net>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/mouse/sentelic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/input/mouse/sentelic.c
++++ b/drivers/input/mouse/sentelic.c
+@@ -759,7 +759,7 @@ static psmouse_ret_t fsp_process_byte(st
+                       fsp_set_slot(dev, 0, fgrs > 0, abs_x, abs_y);
+                       fsp_set_slot(dev, 1, false, 0, 0);
+               }
+-              if (fgrs > 0) {
++              if (fgrs == 1 || (fgrs == 2 && !(packet[0] & FSP_PB0_MFMC_FGR2))) {
+                       input_report_abs(dev, ABS_X, abs_x);
+                       input_report_abs(dev, ABS_Y, abs_y);
+               }
diff --git a/queue-3.4/input-walkera0701-fix-crash-on-startup.patch b/queue-3.4/input-walkera0701-fix-crash-on-startup.patch
new file mode 100644 (file)
index 0000000..cf56828
--- /dev/null
@@ -0,0 +1,58 @@
+From a455e2985f57e2a71566bb8850094af38b2c932d Mon Sep 17 00:00:00 2001
+From: Peter Popovec <popovec@oko.fei.tuke.sk>
+Date: Fri, 14 Dec 2012 22:57:25 -0800
+Subject: Input: walkera0701 - fix crash on startup
+
+From: Peter Popovec <popovec@oko.fei.tuke.sk>
+
+commit a455e2985f57e2a71566bb8850094af38b2c932d upstream.
+
+The driver's timer must be set up before enabling IRQ handler, otherwise
+bad things may happen.
+
+Reported-and-tested-by: Fengguang Wu <fengguang.wu@intel.com>
+Signed-off-by: Peter Popovec <popovec@fei.tuke.sk>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/joystick/walkera0701.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/input/joystick/walkera0701.c
++++ b/drivers/input/joystick/walkera0701.c
+@@ -196,6 +196,7 @@ static void walkera0701_close(struct inp
+       struct walkera_dev *w = input_get_drvdata(dev);
+       parport_disable_irq(w->parport);
++      hrtimer_cancel(&w->timer);
+ }
+ static int walkera0701_connect(struct walkera_dev *w, int parport)
+@@ -224,6 +225,9 @@ static int walkera0701_connect(struct wa
+       if (parport_claim(w->pardevice))
+               goto init_err1;
++      hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++      w->timer.function = timer_handler;
++
+       w->input_dev = input_allocate_device();
+       if (!w->input_dev)
+               goto init_err2;
+@@ -254,8 +258,6 @@ static int walkera0701_connect(struct wa
+       if (err)
+               goto init_err3;
+-      hrtimer_init(&w->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+-      w->timer.function = timer_handler;
+       return 0;
+  init_err3:
+@@ -271,7 +273,6 @@ static int walkera0701_connect(struct wa
+ static void walkera0701_disconnect(struct walkera_dev *w)
+ {
+-      hrtimer_cancel(&w->timer);
+       input_unregister_device(w->input_dev);
+       parport_release(w->pardevice);
+       parport_unregister_device(w->pardevice);
index 604b53b29d726931990cd3dde2403ddd2a33ddae..fca8f8db9c2fe31503460ac39d1a6357d4ed7e00 100644 (file)
@@ -41,3 +41,14 @@ nfsd-fix-v4-reply-caching.patch
 nfsd4-fix-oops-on-unusual-readlike-compound.patch
 nfsd-avoid-permission-checks-on-exclusive_create-replay.patch
 nfs-fix-null-checking-in-nfs_get_option_str.patch
+input-walkera0701-fix-crash-on-startup.patch
+input-sentelic-only-report-position-of-first-finger-as-st-coordinates.patch
+genirq-always-force-thread-affinity.patch
+usb-musb-cppi_dma-export-cppi_interrupt.patch
+xhci-fix-conditional-check-in-bandwidth-calculation.patch
+xhci-fix-td-size-calculation-on-1.0-hosts.patch
+xhci-fix-null-pointer-dereference-when-destroying-half-built-segment-rings.patch
+usb-host-xhci-stricter-conditional-for-z1-system-models-for-compliance-mode-patch.patch
+xhci-add-lynx-point-lp-to-list-of-intel-switchable-hosts.patch
+cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch
+freezer-add-missing-mb-s-to-freezer_count-and-freezer_should_skip.patch
diff --git a/queue-3.4/usb-host-xhci-stricter-conditional-for-z1-system-models-for-compliance-mode-patch.patch b/queue-3.4/usb-host-xhci-stricter-conditional-for-z1-system-models-for-compliance-mode-patch.patch
new file mode 100644 (file)
index 0000000..21ce753
--- /dev/null
@@ -0,0 +1,36 @@
+From b0e4e606ff6ff26da0f60826e75577b56ba4e463 Mon Sep 17 00:00:00 2001
+From: "Alexis R. Cortes" <alexis.cortes@ti.com>
+Date: Thu, 8 Nov 2012 16:59:27 -0600
+Subject: usb: host: xhci: Stricter conditional for Z1 system models for Compliance Mode Patch
+
+From: "Alexis R. Cortes" <alexis.cortes@ti.com>
+
+commit b0e4e606ff6ff26da0f60826e75577b56ba4e463 upstream.
+
+This minor patch creates a more stricter conditional for the Z1 sytems for applying
+the Compliance Mode Patch, this to avoid the quirk to be applied to models that
+contain a "Z1" in their dmi product string but are different from Z1 systems.
+
+This patch should be backported to stable kernels as old as 3.2, that
+contain the commit 71c731a296f1b08a3724bd1b514b64f1bda87a23 "usb: host:
+xhci: Fix Compliance Mode on SN65LVPE502CP Hardware"
+
+Signed-off-by: Alexis R. Cortes <alexis.cortes@ti.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -480,7 +480,7 @@ static bool compliance_mode_recovery_tim
+       if (strstr(dmi_product_name, "Z420") ||
+                       strstr(dmi_product_name, "Z620") ||
+                       strstr(dmi_product_name, "Z820") ||
+-                      strstr(dmi_product_name, "Z1"))
++                      strstr(dmi_product_name, "Z1 Workstation"))
+               return true;
+       return false;
diff --git a/queue-3.4/usb-musb-cppi_dma-export-cppi_interrupt.patch b/queue-3.4/usb-musb-cppi_dma-export-cppi_interrupt.patch
new file mode 100644 (file)
index 0000000..1f4a32b
--- /dev/null
@@ -0,0 +1,30 @@
+From 8b416b0b25d5d8ddb3a91c1d20e1373582c50405 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Mon, 5 Nov 2012 22:26:40 +0300
+Subject: usb: musb: cppi_dma: export cppi_interrupt()
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+commit 8b416b0b25d5d8ddb3a91c1d20e1373582c50405 upstream.
+
+Now that DaVinci glue layer can be modular, we must export cppi_interrupt()
+that it may call...
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/musb/cppi_dma.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/musb/cppi_dma.c
++++ b/drivers/usb/musb/cppi_dma.c
+@@ -1313,6 +1313,7 @@ irqreturn_t cppi_interrupt(int irq, void
+       return IRQ_HANDLED;
+ }
++EXPORT_SYMBOL_GPL(cppi_interrupt);
+ /* Instantiate a software object representing a DMA controller. */
+ struct dma_controller *__init
diff --git a/queue-3.4/xhci-add-lynx-point-lp-to-list-of-intel-switchable-hosts.patch b/queue-3.4/xhci-add-lynx-point-lp-to-list-of-intel-switchable-hosts.patch
new file mode 100644 (file)
index 0000000..7d89322
--- /dev/null
@@ -0,0 +1,57 @@
+From bb1e5dd7113d2fd178d3af9aca8f480ae0468edf Mon Sep 17 00:00:00 2001
+From: Russell Webb <russell.webb@linux.intel.com>
+Date: Fri, 9 Nov 2012 13:58:49 -0800
+Subject: xhci: Add Lynx Point LP to list of Intel switchable hosts
+
+From: Russell Webb <russell.webb@linux.intel.com>
+
+commit bb1e5dd7113d2fd178d3af9aca8f480ae0468edf upstream.
+
+Like Lynx Point, Lynx Point LP is also switchable.  See
+1c12443ab8eba71a658fae4572147e56d1f84f66 for more details.
+
+This patch should be backported to stable kernels as old as 3.0,
+that contain commit 69e848c2090aebba5698a1620604c7dccb448684
+"Intel xhci: Support EHCI/xHCI port switching."
+
+Signed-off-by: Russell Webb <russell.webb@linux.intel.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-pci.c   |    3 ++-
+ drivers/usb/host/pci-quirks.c |    4 +++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -362,7 +362,8 @@ static bool usb_is_intel_switchable_ehci
+               pdev->vendor == PCI_VENDOR_ID_INTEL &&
+               (pdev->device == 0x1E26 ||
+                pdev->device == 0x8C2D ||
+-               pdev->device == 0x8C26);
++               pdev->device == 0x8C26 ||
++               pdev->device == 0x9C26);
+ }
+ static void ehci_enable_xhci_companion(void)
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -723,6 +723,7 @@ static int handshake(void __iomem *ptr,
+ }
+ #define PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI   0x8C31
++#define PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI        0x9C31
+ bool usb_is_intel_ppt_switchable_xhci(struct pci_dev *pdev)
+ {
+@@ -736,7 +737,8 @@ bool usb_is_intel_lpt_switchable_xhci(st
+ {
+       return pdev->class == PCI_CLASS_SERIAL_USB_XHCI &&
+               pdev->vendor == PCI_VENDOR_ID_INTEL &&
+-              pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI;
++              (pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_XHCI ||
++               pdev->device == PCI_DEVICE_ID_INTEL_LYNX_POINT_LP_XHCI);
+ }
+ bool usb_is_intel_switchable_xhci(struct pci_dev *pdev)
diff --git a/queue-3.4/xhci-fix-conditional-check-in-bandwidth-calculation.patch b/queue-3.4/xhci-fix-conditional-check-in-bandwidth-calculation.patch
new file mode 100644 (file)
index 0000000..752e03b
--- /dev/null
@@ -0,0 +1,52 @@
+From 392a07ae3316f2b90b39ce41e66d6f6b5c95de90 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 25 Oct 2012 13:44:12 -0700
+Subject: xhci: Fix conditional check in bandwidth calculation.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 392a07ae3316f2b90b39ce41e66d6f6b5c95de90 upstream.
+
+David reports that at drivers/usb/host/xhci.c:2257:
+
+static bool xhci_is_sync_in_ep(unsigned int ep_type)
+{
+    return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP);
+}
+
+The static analyser cppcheck says
+
+[linux-3.7-rc2/drivers/usb/host/xhci.c:2257]: (style) Redundant condition: If ep_type == 5, the comparison ep_type != 7 is always true.
+
+Maybe the original programmer intention was something like
+
+static bool xhci_is_sync_in_ep(unsigned int ep_type)
+{
+    return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP);
+}
+
+Fix this.
+
+This patch should be backported to stable kernels as old as 3.2, that
+contain the commit 2b69899934c63b7b9432568584fb4c4a2924f40c "xhci: USB
+3.0 BW checking."
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Reported-by: David Binderman <dcb314@hotmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -2253,7 +2253,7 @@ static bool xhci_is_async_ep(unsigned in
+ static bool xhci_is_sync_in_ep(unsigned int ep_type)
+ {
+-      return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP);
++      return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP);
+ }
+ static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw)
diff --git a/queue-3.4/xhci-fix-null-pointer-dereference-when-destroying-half-built-segment-rings.patch b/queue-3.4/xhci-fix-null-pointer-dereference-when-destroying-half-built-segment-rings.patch
new file mode 100644 (file)
index 0000000..ca4b440
--- /dev/null
@@ -0,0 +1,64 @@
+From 68e5254adb88bede68285f11fb442a4d34fb550c Mon Sep 17 00:00:00 2001
+From: Julius Werner <jwerner@chromium.org>
+Date: Thu, 1 Nov 2012 12:47:59 -0700
+Subject: xhci: fix null-pointer dereference when destroying half-built segment rings
+
+From: Julius Werner <jwerner@chromium.org>
+
+commit 68e5254adb88bede68285f11fb442a4d34fb550c upstream.
+
+xhci_alloc_segments_for_ring() builds a list of xhci_segments and links
+the tail to head at the end (forming a ring). When it bails out for OOM
+reasons half-way through, it tries to destroy its half-built list with
+xhci_free_segments_for_ring(), even though it is not a ring yet. This
+causes a null-pointer dereference upon hitting the last element.
+
+Furthermore, one of its callers (xhci_ring_alloc()) mistakenly believes
+the output parameters to be valid upon this kind of OOM failure, and
+calls xhci_ring_free() on them. Since the (incomplete) list/ring should
+already be destroyed in that case, this would lead to a use after free.
+
+This patch fixes those issues by having xhci_alloc_segments_for_ring()
+destroy its half-built, non-circular list manually and destroying the
+invalid struct xhci_ring in xhci_ring_alloc() with a plain kfree().
+
+This patch should be backported to kernels as old as 2.6.31, that
+contains the commit 0ebbab37422315a5d0cb29792271085bafdf38c0 "USB: xhci:
+Ring allocation and initialization."
+
+A separate patch will need to be developed for kernels older than 3.4,
+since the ring allocation code was refactored in that kernel.
+
+Signed-off-by: Julius Werner <jwerner@chromium.org>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c |    9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(
+               next = xhci_segment_alloc(xhci, cycle_state, flags);
+               if (!next) {
+-                      xhci_free_segments_for_ring(xhci, *first);
++                      prev = *first;
++                      while (prev) {
++                              next = prev->next;
++                              xhci_segment_free(xhci, prev);
++                              prev = next;
++                      }
+                       return -ENOMEM;
+               }
+               xhci_link_segments(xhci, prev, next, type);
+@@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc
+       return ring;
+ fail:
+-      xhci_ring_free(xhci, ring);
++      kfree(ring);
+       return NULL;
+ }
diff --git a/queue-3.4/xhci-fix-td-size-calculation-on-1.0-hosts.patch b/queue-3.4/xhci-fix-td-size-calculation-on-1.0-hosts.patch
new file mode 100644 (file)
index 0000000..8fe9e29
--- /dev/null
@@ -0,0 +1,156 @@
+From 4525c0a10dff7ad3669763c28016c7daffc3900e Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 25 Oct 2012 15:56:40 -0700
+Subject: xHCI: Fix TD Size calculation on 1.0 hosts.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 4525c0a10dff7ad3669763c28016c7daffc3900e upstream.
+
+The xHCI 1.0 specification made a change to the TD Size field in TRBs.
+The value is now the number of packets that remain to be sent in the TD,
+not including this TRB.  The TD Size value for the last TRB in a TD must
+always be zero.
+
+The xHCI function xhci_v1_0_td_remainder() attempts to calculate this,
+but it gets it wrong.  First, it erroneously reuses the old
+xhci_td_remainder function, which will right shift the value by 10.  The
+xHCI 1.0 spec as of June 2011 says nothing about right shifting by 10.
+Second, it does not set the TD size for the last TRB in a TD to zero.
+
+Third, it uses roundup instead of DIV_ROUND_UP.  The total packet count
+is supposed to be the total number of bytes in this TD, divided by the
+max packet size, rounded up.  DIV_ROUND_UP is the right function to use
+in that case.
+
+With the old code, a TD on an endpoint with max packet size 1024 would
+be set up like so:
+TRB 1, TRB length = 600 bytes, TD size = 0
+TRB 1, TRB length = 200 bytes, TD size = 0
+TRB 1, TRB length = 100 bytes, TD size = 0
+
+With the new code, the TD would be set up like this:
+TRB 1, TRB length = 600 bytes, TD size = 1
+TRB 1, TRB length = 200 bytes, TD size = 1
+TRB 1, TRB length = 100 bytes, TD size = 0
+
+This commit should be backported to kernels as old as 3.0, that contain
+the commit 4da6e6f247a2601ab9f1e63424e4d944ed4124f3 "xhci 1.0: Update TD
+size field format."
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Reported-by: Chintan Mehta <chintan.mehta@sibridgetech.com>
+Reported-by: Shimmer Huang <shimmering.h@gmail.com>
+Tested-by: Bhavik Kothari <bhavik.kothari@sibridgetech.com>
+Tested-by: Shimmer Huang <shimmering.h@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-ring.c |   32 +++++++++++++++++++-------------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3069,11 +3069,11 @@ static u32 xhci_td_remainder(unsigned in
+ }
+ /*
+- * For xHCI 1.0 host controllers, TD size is the number of packets remaining in
+- * the TD (*not* including this TRB).
++ * For xHCI 1.0 host controllers, TD size is the number of max packet sized
++ * packets remaining in the TD (*not* including this TRB).
+  *
+  * Total TD packet count = total_packet_count =
+- *     roundup(TD size in bytes / wMaxPacketSize)
++ *     DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
+  *
+  * Packets transferred up to and including this TRB = packets_transferred =
+  *     rounddown(total bytes transferred including this TRB / wMaxPacketSize)
+@@ -3081,15 +3081,16 @@ static u32 xhci_td_remainder(unsigned in
+  * TD size = total_packet_count - packets_transferred
+  *
+  * It must fit in bits 21:17, so it can't be bigger than 31.
++ * The last TRB in a TD must have the TD size set to zero.
+  */
+-
+ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
+-              unsigned int total_packet_count, struct urb *urb)
++              unsigned int total_packet_count, struct urb *urb,
++              unsigned int num_trbs_left)
+ {
+       int packets_transferred;
+       /* One TRB with a zero-length data packet. */
+-      if (running_total == 0 && trb_buff_len == 0)
++      if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
+               return 0;
+       /* All the TRB queueing functions don't count the current TRB in
+@@ -3098,7 +3099,9 @@ static u32 xhci_v1_0_td_remainder(int ru
+       packets_transferred = (running_total + trb_buff_len) /
+               usb_endpoint_maxp(&urb->ep->desc);
+-      return xhci_td_remainder(total_packet_count - packets_transferred);
++      if ((total_packet_count - packets_transferred) > 31)
++              return 31 << 17;
++      return (total_packet_count - packets_transferred) << 17;
+ }
+ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+@@ -3125,7 +3128,7 @@ static int queue_bulk_sg_tx(struct xhci_
+       num_trbs = count_sg_trbs_needed(xhci, urb);
+       num_sgs = urb->num_mapped_sgs;
+-      total_packet_count = roundup(urb->transfer_buffer_length,
++      total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
+                       usb_endpoint_maxp(&urb->ep->desc));
+       trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id],
+@@ -3208,7 +3211,8 @@ static int queue_bulk_sg_tx(struct xhci_
+                                       running_total);
+               } else {
+                       remainder = xhci_v1_0_td_remainder(running_total,
+-                                      trb_buff_len, total_packet_count, urb);
++                                      trb_buff_len, total_packet_count, urb,
++                                      num_trbs - 1);
+               }
+               length_field = TRB_LEN(trb_buff_len) |
+                       remainder |
+@@ -3316,7 +3320,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+       start_cycle = ep_ring->cycle_state;
+       running_total = 0;
+-      total_packet_count = roundup(urb->transfer_buffer_length,
++      total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length,
+                       usb_endpoint_maxp(&urb->ep->desc));
+       /* How much data is in the first TRB? */
+       addr = (u64) urb->transfer_dma;
+@@ -3362,7 +3366,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+                                       running_total);
+               } else {
+                       remainder = xhci_v1_0_td_remainder(running_total,
+-                                      trb_buff_len, total_packet_count, urb);
++                                      trb_buff_len, total_packet_count, urb,
++                                      num_trbs - 1);
+               }
+               length_field = TRB_LEN(trb_buff_len) |
+                       remainder |
+@@ -3625,7 +3630,7 @@ static int xhci_queue_isoc_tx(struct xhc
+               addr = start_addr + urb->iso_frame_desc[i].offset;
+               td_len = urb->iso_frame_desc[i].length;
+               td_remain_len = td_len;
+-              total_packet_count = roundup(td_len,
++              total_packet_count = DIV_ROUND_UP(td_len,
+                               usb_endpoint_maxp(&urb->ep->desc));
+               /* A zero-length transfer still involves at least one packet. */
+               if (total_packet_count == 0)
+@@ -3704,7 +3709,8 @@ static int xhci_queue_isoc_tx(struct xhc
+                       } else {
+                               remainder = xhci_v1_0_td_remainder(
+                                               running_total, trb_buff_len,
+-                                              total_packet_count, urb);
++                                              total_packet_count, urb,
++                                              (trbs_per_td - j - 1));
+                       }
+                       length_field = TRB_LEN(trb_buff_len) |
+                               remainder |