]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2012 00:29:57 +0000 (17:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2012 00:29:57 +0000 (17:29 -0700)
added patches:
irq_remap-disable-irq-remapping-if-any-ioapic-lacks-an-iommu.patch
kthread_worker-reimplement-flush_kthread_work-to-allow-freeing-the-work-item-being-executed.patch
kthread_worker-reorganize-to-prepare-for-flush_kthread_work-reimplementation.patch
net-qmi_wwan-add-sierra-wireless-devices.patch
net-qmi_wwan-new-devices-uml290-and-k5006-z.patch
nfsd-introduce-nfsd_destroy-helper.patch
nfsd-set-nfsd_serv-to-null-after-service-destruction.patch
usb-chipidea-cleanup-dma_pool-if-udc_start-fails.patch
usb-chipidea-udc-fix-error-path-in-udc_start.patch

queue-3.5/irq_remap-disable-irq-remapping-if-any-ioapic-lacks-an-iommu.patch [new file with mode: 0644]
queue-3.5/kthread_worker-reimplement-flush_kthread_work-to-allow-freeing-the-work-item-being-executed.patch [new file with mode: 0644]
queue-3.5/kthread_worker-reorganize-to-prepare-for-flush_kthread_work-reimplementation.patch [new file with mode: 0644]
queue-3.5/net-qmi_wwan-add-sierra-wireless-devices.patch [new file with mode: 0644]
queue-3.5/net-qmi_wwan-new-devices-uml290-and-k5006-z.patch [new file with mode: 0644]
queue-3.5/nfsd-introduce-nfsd_destroy-helper.patch [new file with mode: 0644]
queue-3.5/nfsd-set-nfsd_serv-to-null-after-service-destruction.patch [new file with mode: 0644]
queue-3.5/series
queue-3.5/usb-chipidea-cleanup-dma_pool-if-udc_start-fails.patch [new file with mode: 0644]
queue-3.5/usb-chipidea-udc-fix-error-path-in-udc_start.patch [new file with mode: 0644]

diff --git a/queue-3.5/irq_remap-disable-irq-remapping-if-any-ioapic-lacks-an-iommu.patch b/queue-3.5/irq_remap-disable-irq-remapping-if-any-ioapic-lacks-an-iommu.patch
new file mode 100644 (file)
index 0000000..fef97ff
--- /dev/null
@@ -0,0 +1,69 @@
+From 32ab31e01e2def6f48294d872d9bb42573aae00f Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee@canonical.com>
+Date: Wed, 8 Aug 2012 08:27:03 -0500
+Subject: irq_remap: disable IRQ remapping if any IOAPIC lacks an IOMMU
+
+From: Seth Forshee <seth.forshee@canonical.com>
+
+commit 32ab31e01e2def6f48294d872d9bb42573aae00f upstream.
+
+The ACPI tables in the Macbook Air 5,1 define a single IOAPIC with id 2,
+but the only remapping unit described in the DMAR table matches id 0.
+Interrupt remapping fails as a result, and the kernel panics with the
+message "timer doesn't work through Interrupt-remapped IO-APIC."
+
+To fix this, check each IOAPIC for a corresponding IOMMU. If an IOMMU is
+not found, do not allow IRQ remapping to be enabled.
+
+v2: Move check to parse_ioapics_under_ir(), raise log level to KERN_ERR,
+    and add FW_BUG to the log message
+v3: Skip check if IOMMU doesn't support interrupt remapping and remove
+    existing check that the IOMMU count equals the IOAPIC count
+
+Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+Acked-by: Yinghai Lu <yinghai@kernel.org>
+Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
+Acked-by: Cho, Yu-Chen <acho@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iommu/intel_irq_remapping.c |   18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/iommu/intel_irq_remapping.c
++++ b/drivers/iommu/intel_irq_remapping.c
+@@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void)
+ {
+       struct dmar_drhd_unit *drhd;
+       int ir_supported = 0;
++      int ioapic_idx;
+       for_each_drhd_unit(drhd) {
+               struct intel_iommu *iommu = drhd->iommu;
+@@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void)
+               }
+       }
+-      if (ir_supported && ir_ioapic_num != nr_ioapics) {
+-              printk(KERN_WARNING
+-                     "Not all IO-APIC's listed under remapping hardware\n");
+-              return -1;
++      if (!ir_supported)
++              return 0;
++
++      for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {
++              int ioapic_id = mpc_ioapic_id(ioapic_idx);
++              if (!map_ioapic_to_ir(ioapic_id)) {
++                      pr_err(FW_BUG "ioapic %d has no mapping iommu, "
++                             "interrupt remapping will be disabled\n",
++                             ioapic_id);
++                      return -1;
++              }
+       }
+-      return ir_supported;
++      return 1;
+ }
+ int __init ir_dev_scope_init(void)
diff --git a/queue-3.5/kthread_worker-reimplement-flush_kthread_work-to-allow-freeing-the-work-item-being-executed.patch b/queue-3.5/kthread_worker-reimplement-flush_kthread_work-to-allow-freeing-the-work-item-being-executed.patch
new file mode 100644 (file)
index 0000000..b055db3
--- /dev/null
@@ -0,0 +1,152 @@
+From 46f3d976213452350f9d10b0c2780c2681f7075b Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Thu, 19 Jul 2012 13:52:53 -0700
+Subject: kthread_worker: reimplement flush_kthread_work() to allow freeing the work item being executed
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 46f3d976213452350f9d10b0c2780c2681f7075b upstream.
+
+kthread_worker provides minimalistic workqueue-like interface for
+users which need a dedicated worker thread (e.g. for realtime
+priority).  It has basic queue, flush_work, flush_worker operations
+which mostly match the workqueue counterparts; however, due to the way
+flush_work() is implemented, it has a noticeable difference of not
+allowing work items to be freed while being executed.
+
+While the current users of kthread_worker are okay with the current
+behavior, the restriction does impede some valid use cases.  Also,
+removing this difference isn't difficult and actually makes the code
+easier to understand.
+
+This patch reimplements flush_kthread_work() such that it uses a
+flush_work item instead of queue/done sequence numbers.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Colin Cross <ccross@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/kthread.h |    8 +------
+ kernel/kthread.c        |   52 ++++++++++++++++++++++++++----------------------
+ 2 files changed, 31 insertions(+), 29 deletions(-)
+
+--- a/include/linux/kthread.h
++++ b/include/linux/kthread.h
+@@ -49,8 +49,6 @@ extern int tsk_fork_get_node(struct task
+  * can be queued and flushed using queue/flush_kthread_work()
+  * respectively.  Queued kthread_works are processed by a kthread
+  * running kthread_worker_fn().
+- *
+- * A kthread_work can't be freed while it is executing.
+  */
+ struct kthread_work;
+ typedef void (*kthread_work_func_t)(struct kthread_work *work);
+@@ -59,15 +57,14 @@ struct kthread_worker {
+       spinlock_t              lock;
+       struct list_head        work_list;
+       struct task_struct      *task;
++      struct kthread_work     *current_work;
+ };
+ struct kthread_work {
+       struct list_head        node;
+       kthread_work_func_t     func;
+       wait_queue_head_t       done;
+-      atomic_t                flushing;
+-      int                     queue_seq;
+-      int                     done_seq;
++      struct kthread_worker   *worker;
+ };
+ #define KTHREAD_WORKER_INIT(worker)   {                               \
+@@ -79,7 +76,6 @@ struct kthread_work {
+       .node = LIST_HEAD_INIT((work).node),                            \
+       .func = (fn),                                                   \
+       .done = __WAIT_QUEUE_HEAD_INITIALIZER((work).done),             \
+-      .flushing = ATOMIC_INIT(0),                                     \
+       }
+ #define DEFINE_KTHREAD_WORKER(worker)                                 \
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -360,16 +360,12 @@ repeat:
+                                       struct kthread_work, node);
+               list_del_init(&work->node);
+       }
++      worker->current_work = work;
+       spin_unlock_irq(&worker->lock);
+       if (work) {
+               __set_current_state(TASK_RUNNING);
+               work->func(work);
+-              smp_wmb();      /* wmb worker-b0 paired with flush-b1 */
+-              work->done_seq = work->queue_seq;
+-              smp_mb();       /* mb worker-b1 paired with flush-b0 */
+-              if (atomic_read(&work->flushing))
+-                      wake_up_all(&work->done);
+       } else if (!freezing(current))
+               schedule();
+@@ -386,7 +382,7 @@ static void insert_kthread_work(struct k
+       lockdep_assert_held(&worker->lock);
+       list_add_tail(&work->node, pos);
+-      work->queue_seq++;
++      work->worker = worker;
+       if (likely(worker->task))
+               wake_up_process(worker->task);
+ }
+@@ -436,25 +432,35 @@ static void kthread_flush_work_fn(struct
+  */
+ void flush_kthread_work(struct kthread_work *work)
+ {
+-      int seq = work->queue_seq;
++      struct kthread_flush_work fwork = {
++              KTHREAD_WORK_INIT(fwork.work, kthread_flush_work_fn),
++              COMPLETION_INITIALIZER_ONSTACK(fwork.done),
++      };
++      struct kthread_worker *worker;
++      bool noop = false;
++
++retry:
++      worker = work->worker;
++      if (!worker)
++              return;
++
++      spin_lock_irq(&worker->lock);
++      if (work->worker != worker) {
++              spin_unlock_irq(&worker->lock);
++              goto retry;
++      }
++
++      if (!list_empty(&work->node))
++              insert_kthread_work(worker, &fwork.work, work->node.next);
++      else if (worker->current_work == work)
++              insert_kthread_work(worker, &fwork.work, worker->work_list.next);
++      else
++              noop = true;
+-      atomic_inc(&work->flushing);
++      spin_unlock_irq(&worker->lock);
+-      /*
+-       * mb flush-b0 paired with worker-b1, to make sure either
+-       * worker sees the above increment or we see done_seq update.
+-       */
+-      smp_mb__after_atomic_inc();
+-
+-      /* A - B <= 0 tests whether B is in front of A regardless of overflow */
+-      wait_event(work->done, seq - work->done_seq <= 0);
+-      atomic_dec(&work->flushing);
+-
+-      /*
+-       * rmb flush-b1 paired with worker-b0, to make sure our caller
+-       * sees every change made by work->func().
+-       */
+-      smp_mb__after_atomic_dec();
++      if (!noop)
++              wait_for_completion(&fwork.done);
+ }
+ EXPORT_SYMBOL_GPL(flush_kthread_work);
diff --git a/queue-3.5/kthread_worker-reorganize-to-prepare-for-flush_kthread_work-reimplementation.patch b/queue-3.5/kthread_worker-reorganize-to-prepare-for-flush_kthread_work-reimplementation.patch
new file mode 100644 (file)
index 0000000..1e6c38b
--- /dev/null
@@ -0,0 +1,100 @@
+From 9a2e03d8ed518a61154f18d83d6466628e519f94 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Thu, 19 Jul 2012 13:52:53 -0700
+Subject: kthread_worker: reorganize to prepare for flush_kthread_work() reimplementation
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 9a2e03d8ed518a61154f18d83d6466628e519f94 upstream.
+
+Make the following two non-functional changes.
+
+* Separate out insert_kthread_work() from queue_kthread_work().
+
+* Relocate struct kthread_flush_work and kthread_flush_work_fn()
+  definitions above flush_kthread_work().
+
+v2: Added lockdep_assert_held() in insert_kthread_work() as suggested
+    by Andy Walls.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Acked-by: Andy Walls <awalls@md.metrocast.net>
+Cc: Colin Cross <ccross@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/kthread.c |   42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+--- a/kernel/kthread.c
++++ b/kernel/kthread.c
+@@ -378,6 +378,19 @@ repeat:
+ }
+ EXPORT_SYMBOL_GPL(kthread_worker_fn);
++/* insert @work before @pos in @worker */
++static void insert_kthread_work(struct kthread_worker *worker,
++                             struct kthread_work *work,
++                             struct list_head *pos)
++{
++      lockdep_assert_held(&worker->lock);
++
++      list_add_tail(&work->node, pos);
++      work->queue_seq++;
++      if (likely(worker->task))
++              wake_up_process(worker->task);
++}
++
+ /**
+  * queue_kthread_work - queue a kthread_work
+  * @worker: target kthread_worker
+@@ -395,10 +408,7 @@ bool queue_kthread_work(struct kthread_w
+       spin_lock_irqsave(&worker->lock, flags);
+       if (list_empty(&work->node)) {
+-              list_add_tail(&work->node, &worker->work_list);
+-              work->queue_seq++;
+-              if (likely(worker->task))
+-                      wake_up_process(worker->task);
++              insert_kthread_work(worker, work, &worker->work_list);
+               ret = true;
+       }
+       spin_unlock_irqrestore(&worker->lock, flags);
+@@ -406,6 +416,18 @@ bool queue_kthread_work(struct kthread_w
+ }
+ EXPORT_SYMBOL_GPL(queue_kthread_work);
++struct kthread_flush_work {
++      struct kthread_work     work;
++      struct completion       done;
++};
++
++static void kthread_flush_work_fn(struct kthread_work *work)
++{
++      struct kthread_flush_work *fwork =
++              container_of(work, struct kthread_flush_work, work);
++      complete(&fwork->done);
++}
++
+ /**
+  * flush_kthread_work - flush a kthread_work
+  * @work: work to flush
+@@ -436,18 +458,6 @@ void flush_kthread_work(struct kthread_w
+ }
+ EXPORT_SYMBOL_GPL(flush_kthread_work);
+-struct kthread_flush_work {
+-      struct kthread_work     work;
+-      struct completion       done;
+-};
+-
+-static void kthread_flush_work_fn(struct kthread_work *work)
+-{
+-      struct kthread_flush_work *fwork =
+-              container_of(work, struct kthread_flush_work, work);
+-      complete(&fwork->done);
+-}
+-
+ /**
+  * flush_kthread_worker - flush all current works on a kthread_worker
+  * @worker: worker to flush
diff --git a/queue-3.5/net-qmi_wwan-add-sierra-wireless-devices.patch b/queue-3.5/net-qmi_wwan-add-sierra-wireless-devices.patch
new file mode 100644 (file)
index 0000000..4e58e88
--- /dev/null
@@ -0,0 +1,107 @@
+From bjorn@mork.no  Thu Sep 27 16:54:06 2012
+From: Bjørn Mork <bjorn@mork.no>
+Date: Thu, 23 Aug 2012 12:13:57 +0200
+Subject: net: qmi_wwan: add Sierra Wireless devices
+To: stable@vger.kernel.org
+Cc: Bjørn Mork <bjorn@mork.no>, David Miller <davem@davemloft.net>
+Message-ID: <1345716838-24023-7-git-send-email-bjorn@mork.no>
+
+From: Bjørn Mork <bjorn@mork.no>
+
+commit 9b469a60d68b13c288d5c3fc23de29d9d482dbe6 upstream.
+
+Add 6 new devices and one modified device, based on
+information from laptop vendor Windows drivers.
+
+Sony provides a driver with two new devices using
+a Gobi 2k+ layout (1199:68a5 and 1199:68a9).  The
+Sony driver also adds a non-standard QMI/net
+interface to the already supported 1199:9011
+Gobi device. We do not know whether this is an
+alternate interface number or an additional
+interface which might be present, but that doesn't
+really matter.
+
+Lenovo provides a driver supporting 4 new devices:
+ - MC7770 (1199:901b) with standard Gobi 2k+ layout
+ - MC7700 (0f3d:68a2) with layout similar to MC7710
+ - MC7750 (114f:68a2) with layout similar to MC7710
+ - EM7700 (1199:901c) with layout similar to MC7710
+
+Note regaring the three devices similar to MC7710:
+
+The Windows drivers only support interface #8 on these
+devices.  The MC7710 can support QMI/net functions on
+interface #19 and #20 as well, and this driver is
+verified to work on interface #19 (a firmware bug is
+suspected to prevent #20 from working).
+
+We do not enable these additional interfaces until they
+either show up in a Windows driver or are verified to
+work in some other way.  Therefore limiting the new
+devices to interface #8 for now.
+
+[bmork: backported to 3.4: use driver whitelisting]
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+for stable: v3.4 and v3.5
+
+ drivers/net/usb/qmi_wwan.c |   31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -534,6 +534,33 @@ static const struct usb_device_id produc
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_sierra,
+       },
++      {       /* Sierra Wireless MC7700 */
++              .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
++              .idVendor           = 0x0f3d,
++              .idProduct          = 0x68a2,
++              .bInterfaceClass    = 0xff,
++              .bInterfaceSubClass = 0xff,
++              .bInterfaceProtocol = 0xff,
++              .driver_info        = (unsigned long)&qmi_wwan_sierra,
++      },
++      {       /* Sierra Wireless MC7750 */
++              .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
++              .idVendor           = 0x114f,
++              .idProduct          = 0x68a2,
++              .bInterfaceClass    = 0xff,
++              .bInterfaceSubClass = 0xff,
++              .bInterfaceProtocol = 0xff,
++              .driver_info        = (unsigned long)&qmi_wwan_sierra,
++      },
++      {       /* Sierra Wireless EM7700 */
++              .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
++              .idVendor           = 0x1199,
++              .idProduct          = 0x901c,
++              .bInterfaceClass    = 0xff,
++              .bInterfaceSubClass = 0xff,
++              .bInterfaceProtocol = 0xff,
++              .driver_info        = (unsigned long)&qmi_wwan_sierra,
++      },
+       /* Gobi 1000 devices */
+       {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
+@@ -561,6 +588,8 @@ static const struct usb_device_id produc
+       {QMI_GOBI_DEVICE(0x05c6, 0x9265)},      /* Asus Gobi 2000 Modem device (VR305) */
+       {QMI_GOBI_DEVICE(0x05c6, 0x9235)},      /* Top Global Gobi 2000 Modem device (VR306) */
+       {QMI_GOBI_DEVICE(0x05c6, 0x9275)},      /* iRex Technologies Gobi 2000 Modem device (VR307) */
++      {QMI_GOBI_DEVICE(0x1199, 0x68a5)},      /* Sierra Wireless Modem */
++      {QMI_GOBI_DEVICE(0x1199, 0x68a9)},      /* Sierra Wireless Modem */
+       {QMI_GOBI_DEVICE(0x1199, 0x9001)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {QMI_GOBI_DEVICE(0x1199, 0x9002)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+       {QMI_GOBI_DEVICE(0x1199, 0x9003)},      /* Sierra Wireless Gobi 2000 Modem device (VT773) */
+@@ -577,6 +606,8 @@ static const struct usb_device_id produc
+       {QMI_GOBI_DEVICE(0x1199, 0x9013)},      /* Sierra Wireless Gobi 3000 Modem device (MC8355) */
+       {QMI_GOBI_DEVICE(0x1199, 0x9015)},      /* Sierra Wireless Gobi 3000 Modem device */
+       {QMI_GOBI_DEVICE(0x1199, 0x9019)},      /* Sierra Wireless Gobi 3000 Modem device */
++      {QMI_GOBI_DEVICE(0x1199, 0x901b)},      /* Sierra Wireless MC7770 */
++
+       { }                                     /* END */
+ };
+ MODULE_DEVICE_TABLE(usb, products);
diff --git a/queue-3.5/net-qmi_wwan-new-devices-uml290-and-k5006-z.patch b/queue-3.5/net-qmi_wwan-new-devices-uml290-and-k5006-z.patch
new file mode 100644 (file)
index 0000000..8ad97e9
--- /dev/null
@@ -0,0 +1,64 @@
+From bjorn@mork.no  Thu Sep 27 16:55:03 2012
+From: Bjørn Mork <bjorn@mork.no>
+Date: Thu, 23 Aug 2012 12:13:58 +0200
+Subject: net: qmi_wwan: new devices: UML290 and K5006-Z
+To: stable@vger.kernel.org
+Cc: Bjørn Mork <bjorn@mork.no>, David Miller <davem@davemloft.net>, Dan Williams <dcbw@redhat.com>, Thomas Schäfer <tschaefer@t-online.de>
+Message-ID: <1345716838-24023-8-git-send-email-bjorn@mork.no>
+
+From: Bjørn Mork <bjorn@mork.no>
+
+commit 10cbc1d97a7c7f9ae862fffe27b771ef0da9c461 upstream.
+
+Newer firmware versions for the Pantech UML290 use a different
+subclass ID.  The Windows driver match on both IDs, so we do
+that as well.
+
+The ZTE (Vodafone) K5006-Z is a new device.
+
+Cc: Dan Williams <dcbw@redhat.com>
+Cc: Thomas Schäfer <tschaefer@t-online.de>
+[bmork: backported to 3.4: use driver whitelisting]
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+for stable: v3.4 and v3.5
+
+ drivers/net/usb/qmi_wwan.c |   18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -444,6 +444,15 @@ static const struct usb_device_id produc
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_shared,
+       },
++      {       /* Pantech UML290 - newer firmware */
++              .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
++              .idVendor           = 0x106c,
++              .idProduct          = 0x3718,
++              .bInterfaceClass    = 0xff,
++              .bInterfaceSubClass = 0xf1,
++              .bInterfaceProtocol = 0xff,
++              .driver_info        = (unsigned long)&qmi_wwan_shared,
++      },
+       {       /* ZTE MF820D */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
+@@ -516,6 +525,15 @@ static const struct usb_device_id produc
+               .bInterfaceProtocol = 0xff,
+               .driver_info        = (unsigned long)&qmi_wwan_force_int4,
+       },
++      {       /* ZTE (Vodafone) K5006-Z */
++              .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
++              .idVendor           = 0x19d2,
++              .idProduct          = 0x1018,
++              .bInterfaceClass    = 0xff,
++              .bInterfaceSubClass = 0xff,
++              .bInterfaceProtocol = 0xff,
++              .driver_info        = (unsigned long)&qmi_wwan_force_int3,
++      },
+       {       /* ZTE MF60 */
+               .match_flags        = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+               .idVendor           = 0x19d2,
diff --git a/queue-3.5/nfsd-introduce-nfsd_destroy-helper.patch b/queue-3.5/nfsd-introduce-nfsd_destroy-helper.patch
new file mode 100644 (file)
index 0000000..4bc151e
--- /dev/null
@@ -0,0 +1,98 @@
+From 19f7e2ca44dfc3c1b3f499fc46801f98d403500f Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Tue, 3 Jul 2012 16:46:41 +0400
+Subject: NFSd: introduce nfsd_destroy() helper
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 19f7e2ca44dfc3c1b3f499fc46801f98d403500f upstream.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfsctl.c |    8 ++------
+ fs/nfsd/nfsd.h   |    9 +++++++++
+ fs/nfsd/nfssvc.c |   14 +++-----------
+ 3 files changed, 14 insertions(+), 17 deletions(-)
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -673,9 +673,7 @@ static ssize_t __write_ports_addfd(char
+       err = svc_addsock(nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT);
+       if (err < 0) {
+-              if (nfsd_serv->sv_nrthreads == 1)
+-                      svc_shutdown_net(nfsd_serv, net);
+-              svc_destroy(nfsd_serv);
++              nfsd_destroy(net);
+               return err;
+       }
+@@ -744,9 +742,7 @@ out_close:
+               svc_xprt_put(xprt);
+       }
+ out_err:
+-      if (nfsd_serv->sv_nrthreads == 1)
+-              svc_shutdown_net(nfsd_serv, net);
+-      svc_destroy(nfsd_serv);
++      nfsd_destroy(net);
+       return err;
+ }
+--- a/fs/nfsd/nfsd.h
++++ b/fs/nfsd/nfsd.h
+@@ -73,6 +73,15 @@ int         nfsd_nrpools(void);
+ int           nfsd_get_nrthreads(int n, int *);
+ int           nfsd_set_nrthreads(int n, int *);
++static inline void nfsd_destroy(struct net *net)
++{
++      int destroy = (nfsd_serv->sv_nrthreads == 1);
++
++      if (destroy)
++              svc_shutdown_net(nfsd_serv, net);
++      svc_destroy(nfsd_serv);
++}
++
+ #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+ #ifdef CONFIG_NFSD_V2_ACL
+ extern struct svc_version nfsd_acl_version2;
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -427,11 +427,7 @@ int nfsd_set_nrthreads(int n, int *nthre
+               if (err)
+                       break;
+       }
+-
+-      if (nfsd_serv->sv_nrthreads == 1)
+-              svc_shutdown_net(nfsd_serv, net);
+-      svc_destroy(nfsd_serv);
+-
++      nfsd_destroy(net);
+       return err;
+ }
+@@ -478,9 +474,7 @@ out_shutdown:
+       if (error < 0 && !nfsd_up_before)
+               nfsd_shutdown();
+ out_destroy:
+-      if (nfsd_serv->sv_nrthreads == 1)
+-              svc_shutdown_net(nfsd_serv, net);
+-      svc_destroy(nfsd_serv);         /* Release server */
++      nfsd_destroy(net);              /* Release server */
+ out:
+       mutex_unlock(&nfsd_mutex);
+       return error;
+@@ -682,9 +676,7 @@ int nfsd_pool_stats_release(struct inode
+       mutex_lock(&nfsd_mutex);
+       /* this function really, really should have been called svc_put() */
+-      if (nfsd_serv->sv_nrthreads == 1)
+-              svc_shutdown_net(nfsd_serv, net);
+-      svc_destroy(nfsd_serv);
++      nfsd_destroy(net);
+       mutex_unlock(&nfsd_mutex);
+       return ret;
+ }
diff --git a/queue-3.5/nfsd-set-nfsd_serv-to-null-after-service-destruction.patch b/queue-3.5/nfsd-set-nfsd_serv-to-null-after-service-destruction.patch
new file mode 100644 (file)
index 0000000..e16ce37
--- /dev/null
@@ -0,0 +1,82 @@
+From 57c8b13e3cd0f94944c9691ce7f58e5fcef8a12d Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Date: Tue, 3 Jul 2012 16:46:41 +0400
+Subject: NFSd: set nfsd_serv to NULL after service destruction
+
+From: Stanislav Kinsbursky <skinsbursky@parallels.com>
+
+commit 57c8b13e3cd0f94944c9691ce7f58e5fcef8a12d upstream.
+
+In nfsd_destroy():
+
+       if (destroy)
+               svc_shutdown_net(nfsd_serv, net);
+       svc_destroy(nfsd_server);
+
+svc_shutdown_net(nfsd_serv, net) calls nfsd_last_thread(), which sets
+nfsd_serv to NULL, causing a NULL dereference on the following line.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfsd.h   |    2 ++
+ fs/nfsd/nfssvc.c |   10 +++++-----
+ 2 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/fs/nfsd/nfsd.h
++++ b/fs/nfsd/nfsd.h
+@@ -80,6 +80,8 @@ static inline void nfsd_destroy(struct n
+       if (destroy)
+               svc_shutdown_net(nfsd_serv, net);
+       svc_destroy(nfsd_serv);
++      if (destroy)
++              nfsd_serv = NULL;
+ }
+ #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -254,8 +254,6 @@ static void nfsd_shutdown(void)
+ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
+ {
+-      /* When last nfsd thread exits we need to do some clean-up */
+-      nfsd_serv = NULL;
+       nfsd_shutdown();
+       svc_rpcb_cleanup(serv, net);
+@@ -332,6 +330,7 @@ static int nfsd_get_default_max_blksize(
+ int nfsd_create_serv(void)
+ {
+       int error;
++      struct net *net = current->nsproxy->net_ns;
+       WARN_ON(!mutex_is_locked(&nfsd_mutex));
+       if (nfsd_serv) {
+@@ -346,7 +345,7 @@ int nfsd_create_serv(void)
+       if (nfsd_serv == NULL)
+               return -ENOMEM;
+-      error = svc_bind(nfsd_serv, current->nsproxy->net_ns);
++      error = svc_bind(nfsd_serv, net);
+       if (error < 0) {
+               svc_destroy(nfsd_serv);
+               return error;
+@@ -557,12 +556,13 @@ nfsd(void *vrqstp)
+       nfsdstats.th_cnt --;
+ out:
+-      if (rqstp->rq_server->sv_nrthreads == 1)
+-              svc_shutdown_net(rqstp->rq_server, &init_net);
++      rqstp->rq_server = NULL;
+       /* Release the thread */
+       svc_exit_thread(rqstp);
++      nfsd_destroy(&init_net);
++
+       /* Release module */
+       mutex_unlock(&nfsd_mutex);
+       module_put_and_exit(0);
index d776b31098a73638789d0463ce5d418b7ed256b5..76ad686c1b3ac38f86d034a8d7bea51856833c9a 100644 (file)
@@ -242,3 +242,12 @@ i2c-powermac-improve-detection-of-devices-from-device-tree.patch
 sound-aoa-adapt-to-new-i2c-probing-scheme.patch
 nfs-fix-oopses-in-nfs_lookup_revalidate-and-nfs4_lookup_revalidate.patch
 net-qmi_wwan-add-zte-mf821d.patch
+net-qmi_wwan-add-sierra-wireless-devices.patch
+net-qmi_wwan-new-devices-uml290-and-k5006-z.patch
+irq_remap-disable-irq-remapping-if-any-ioapic-lacks-an-iommu.patch
+nfsd-introduce-nfsd_destroy-helper.patch
+nfsd-set-nfsd_serv-to-null-after-service-destruction.patch
+kthread_worker-reorganize-to-prepare-for-flush_kthread_work-reimplementation.patch
+kthread_worker-reimplement-flush_kthread_work-to-allow-freeing-the-work-item-being-executed.patch
+usb-chipidea-udc-fix-error-path-in-udc_start.patch
+usb-chipidea-cleanup-dma_pool-if-udc_start-fails.patch
diff --git a/queue-3.5/usb-chipidea-cleanup-dma_pool-if-udc_start-fails.patch b/queue-3.5/usb-chipidea-cleanup-dma_pool-if-udc_start-fails.patch
new file mode 100644 (file)
index 0000000..446c077
--- /dev/null
@@ -0,0 +1,83 @@
+From ad6b1b97fe8504957d017cd6e4168cac8903d3f3 Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 12 Sep 2012 14:58:03 +0300
+Subject: usb: chipidea: cleanup dma_pool if udc_start() fails
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit ad6b1b97fe8504957d017cd6e4168cac8903d3f3 upstream.
+
+If udc_start() fails the qh_pool dma-pool cannot be closed because
+it's still in use. This patch factors out the dma_pool_free() loop
+into destroy_eps() and calls it in the error path of udc_start(),
+too.
+
+Reviewed-by: Richard Zhao <richard.zhao@freescale.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[mkl: backport to v3.5]
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+
+---
+ drivers/usb/chipidea/udc.c |   23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -1500,6 +1500,17 @@ static int init_eps(struct ci13xxx *udc)
+       return retval;
+ }
++static void destroy_eps(struct ci13xxx *udc)
++{
++      int i;
++
++      for (i = 0; i < udc->hw_ep_max; i++) {
++              struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
++
++              dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
++      }
++}
++
+ /**
+  * ci13xxx_start: register a gadget driver
+  * @gadget: our gadget
+@@ -1709,7 +1720,7 @@ static int udc_start(struct ci13xxx *udc
+       if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
+               if (udc->transceiver == NULL) {
+                       retval = -ENODEV;
+-                      goto free_pools;
++                      goto destroy_eps;
+               }
+       }
+@@ -1759,6 +1770,8 @@ unreg_device:
+ put_transceiver:
+       if (udc->transceiver)
+               usb_put_transceiver(udc->transceiver);
++destroy_eps:
++      destroy_eps(udc);
+ free_pools:
+       dma_pool_destroy(udc->td_pool);
+ free_qh_pool:
+@@ -1773,18 +1786,12 @@ free_qh_pool:
+  */
+ static void udc_stop(struct ci13xxx *udc)
+ {
+-      int i;
+-
+       if (udc == NULL)
+               return;
+       usb_del_gadget_udc(&udc->gadget);
+-      for (i = 0; i < udc->hw_ep_max; i++) {
+-              struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
+-
+-              dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
+-      }
++      destroy_eps(udc);
+       dma_pool_destroy(udc->td_pool);
+       dma_pool_destroy(udc->qh_pool);
diff --git a/queue-3.5/usb-chipidea-udc-fix-error-path-in-udc_start.patch b/queue-3.5/usb-chipidea-udc-fix-error-path-in-udc_start.patch
new file mode 100644 (file)
index 0000000..6796f70
--- /dev/null
@@ -0,0 +1,33 @@
+From c9d1f947a85e38b6dded469470c95ed62430cb3f Mon Sep 17 00:00:00 2001
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Wed, 12 Sep 2012 14:58:02 +0300
+Subject: usb: chipidea: udc: fix error path in udc_start()
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+commit c9d1f947a85e38b6dded469470c95ed62430cb3f upstream.
+
+This patch fixes the error path of udc_start(). Now NULL is used to
+unset the peripheral with otg_set_peripheral().
+
+Cc: stable <stable@vger.kernel.org>
+Reviewed-by: Richard Zhao <richard.zhao@freescale.com>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/chipidea/udc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -1747,7 +1747,7 @@ static int udc_start(struct ci13xxx *udc
+ remove_trans:
+       if (udc->transceiver) {
+-              otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
++              otg_set_peripheral(udc->transceiver->otg, NULL);
+               usb_put_transceiver(udc->transceiver);
+       }