]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2012 21:15:11 +0000 (14:15 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 Mar 2012 21:15:11 +0000 (14:15 -0700)
added patches:
ath9k-fix-going-to-full-sleep-on-ps-idle.patch
genirq-fix-incorrect-check-for-forced-irq-thread-handler.patch
genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch
ib-iser-post-initial-receive-buffers-before-sending-the-final-login-request.patch
ima-fix-kconfig-dependencies.patch
iwlwifi-always-monitor-for-stuck-queues.patch
math-introduce-div64_long.patch
mlx4_core-fix-one-more-static-exported-function.patch
mm-thp-fix-pmd_bad-triggering-in-code-paths-holding-mmap_sem-read-mode.patch
ntp-fix-integer-overflow-when-setting-time.patch
p54spi-release-gpio-lines-and-irq-on-error-in-p54spi_probe.patch
rt2x00-add-support-for-d-link-dwa-127-to-rt2800usb.patch
rtc-disable-the-alarm-in-the-hardware-v2.patch
rtlwifi-handle-previous-allocation-failures-when-freeing-device-memory.patch
rtlwifi-rtl8192c_common-rtl8192de-check-for-allocation-failures.patch
rtlwifi-rtl8192ce-fix-loss-of-receive-performance.patch
rtlwifi-rtl8192c-prevent-sleeping-from-invalid-context-in-rtl8192cu.patch
rtnetlink-fix-vf-ifla-policy.patch
serial-pl011-clear-pending-interrupts.patch
uevent-send-events-in-correct-order-according-to-seqnum-v3.patch
usb-cp210x-update-to-support-cp2105-and-multiple-interface-devices.patch
usb-qcserial-don-t-grab-qmi-port-on-gobi-1000-devices.patch
usb-serial-add-support-for-the-sealevel-sealink-8-2038-rohs-device.patch
usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch
x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch

26 files changed:
queue-3.3/ath9k-fix-going-to-full-sleep-on-ps-idle.patch [new file with mode: 0644]
queue-3.3/genirq-fix-incorrect-check-for-forced-irq-thread-handler.patch [new file with mode: 0644]
queue-3.3/genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch [new file with mode: 0644]
queue-3.3/ib-iser-post-initial-receive-buffers-before-sending-the-final-login-request.patch [new file with mode: 0644]
queue-3.3/ima-fix-kconfig-dependencies.patch [new file with mode: 0644]
queue-3.3/iwlwifi-always-monitor-for-stuck-queues.patch [new file with mode: 0644]
queue-3.3/math-introduce-div64_long.patch [new file with mode: 0644]
queue-3.3/mlx4_core-fix-one-more-static-exported-function.patch [new file with mode: 0644]
queue-3.3/mm-thp-fix-pmd_bad-triggering-in-code-paths-holding-mmap_sem-read-mode.patch [new file with mode: 0644]
queue-3.3/ntp-fix-integer-overflow-when-setting-time.patch [new file with mode: 0644]
queue-3.3/p54spi-release-gpio-lines-and-irq-on-error-in-p54spi_probe.patch [new file with mode: 0644]
queue-3.3/rt2x00-add-support-for-d-link-dwa-127-to-rt2800usb.patch [new file with mode: 0644]
queue-3.3/rtc-disable-the-alarm-in-the-hardware-v2.patch [new file with mode: 0644]
queue-3.3/rtlwifi-handle-previous-allocation-failures-when-freeing-device-memory.patch [new file with mode: 0644]
queue-3.3/rtlwifi-rtl8192c-prevent-sleeping-from-invalid-context-in-rtl8192cu.patch [new file with mode: 0644]
queue-3.3/rtlwifi-rtl8192c_common-rtl8192de-check-for-allocation-failures.patch [new file with mode: 0644]
queue-3.3/rtlwifi-rtl8192ce-fix-loss-of-receive-performance.patch [new file with mode: 0644]
queue-3.3/rtnetlink-fix-vf-ifla-policy.patch [new file with mode: 0644]
queue-3.3/serial-pl011-clear-pending-interrupts.patch [new file with mode: 0644]
queue-3.3/series
queue-3.3/uevent-send-events-in-correct-order-according-to-seqnum-v3.patch [new file with mode: 0644]
queue-3.3/usb-cp210x-update-to-support-cp2105-and-multiple-interface-devices.patch [new file with mode: 0644]
queue-3.3/usb-qcserial-don-t-grab-qmi-port-on-gobi-1000-devices.patch [new file with mode: 0644]
queue-3.3/usb-serial-add-support-for-the-sealevel-sealink-8-2038-rohs-device.patch [new file with mode: 0644]
queue-3.3/usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch [new file with mode: 0644]
queue-3.3/x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch [new file with mode: 0644]

diff --git a/queue-3.3/ath9k-fix-going-to-full-sleep-on-ps-idle.patch b/queue-3.3/ath9k-fix-going-to-full-sleep-on-ps-idle.patch
new file mode 100644 (file)
index 0000000..5521d98
--- /dev/null
@@ -0,0 +1,42 @@
+From c1afdaff90538ef085b756454f12b29575411214 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sat, 10 Mar 2012 13:57:04 +0100
+Subject: ath9k: fix going to full-sleep on PS idle
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit c1afdaff90538ef085b756454f12b29575411214 upstream.
+
+The check for PS_WAIT_FOR_TX_ACK was inverted, the hardware should only go
+to full sleep if no tx is pending.
+
+Reported-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/main.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *
+       if (--sc->ps_usecount != 0)
+               goto unlock;
+-      if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK))
++      if (sc->ps_flags & PS_WAIT_FOR_TX_ACK)
++              goto unlock;
++
++      if (sc->ps_idle)
+               mode = ATH9K_PM_FULL_SLEEP;
+       else if (sc->ps_enabled &&
+                !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
+                             PS_WAIT_FOR_CAB |
+-                            PS_WAIT_FOR_PSPOLL_DATA |
+-                            PS_WAIT_FOR_TX_ACK)))
++                            PS_WAIT_FOR_PSPOLL_DATA)))
+               mode = ATH9K_PM_NETWORK_SLEEP;
+       else
+               goto unlock;
diff --git a/queue-3.3/genirq-fix-incorrect-check-for-forced-irq-thread-handler.patch b/queue-3.3/genirq-fix-incorrect-check-for-forced-irq-thread-handler.patch
new file mode 100644 (file)
index 0000000..518a3d4
--- /dev/null
@@ -0,0 +1,32 @@
+From 540b60e24f3f4781d80e47122f0c4486a03375b8 Mon Sep 17 00:00:00 2001
+From: Alexander Gordeev <agordeev@redhat.com>
+Date: Fri, 9 Mar 2012 14:59:13 +0100
+Subject: genirq: Fix incorrect check for forced IRQ thread handler
+
+From: Alexander Gordeev <agordeev@redhat.com>
+
+commit 540b60e24f3f4781d80e47122f0c4486a03375b8 upstream.
+
+We do not want a bitwise AND between boolean operands
+
+Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Link: http://lkml.kernel.org/r/20120309135912.GA2114@dhcp-26-207.brq.redhat.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/manage.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -773,7 +773,7 @@ static int irq_thread(void *data)
+                       struct irqaction *action);
+       int wake;
+-      if (force_irqthreads & test_bit(IRQTF_FORCED_THREAD,
++      if (force_irqthreads && test_bit(IRQTF_FORCED_THREAD,
+                                       &action->thread_flags))
+               handler_fn = irq_forced_thread_fn;
+       else
diff --git a/queue-3.3/genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch b/queue-3.3/genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch
new file mode 100644 (file)
index 0000000..33cf67d
--- /dev/null
@@ -0,0 +1,93 @@
+From a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 Mon Sep 17 00:00:00 2001
+From: Russell King <linux@arm.linux.org.uk>
+Date: Mon, 5 Mar 2012 15:07:25 -0800
+Subject: genirq: Fix long-term regression in genirq irq_set_irq_type() handling
+
+From: Russell King <linux@arm.linux.org.uk>
+
+commit a09b659cd68c10ec6a30cb91ebd2c327fcd5bfe5 upstream.
+
+In 2008, commit 0c5d1eb77a8be ("genirq: record trigger type") modified the
+way set_irq_type() handles the 'no trigger' condition.  However, this has
+an adverse effect on PCMCIA support on Intel StrongARM and probably PXA
+platforms.
+
+PCMCIA has several status signals on the socket which can trigger
+interrupts; some of these status signals depend on the card's mode
+(whether it is configured in memory or IO mode).  For example, cards have
+a 'Ready/IRQ' signal: in memory mode, this provides an indication to
+PCMCIA that the card has finished its power up initialization.  In IO
+mode, it provides the device interrupt signal.  Other status signals
+switch between on-board battery status and loud speaker output.
+
+In classical PCMCIA implementations, where you have a specific socket
+controller, the controller provides a method to mask interrupts from the
+socket, and importantly ignore any state transitions on the pins which
+correspond with interrupts once masked.  This masking prevents unwanted
+events caused by the removal and application of socket power being
+forwarded.
+
+However, on platforms where there is no socket controller, the PCMCIA
+status and interrupt signals are routed to standard edge-triggered GPIOs.
+These GPIOs can be configured to interrupt on rising edge, falling edge,
+or never.  This is where the problems start.
+
+Edge triggered interrupts are required to record events while disabled via
+the usual methods of {free,request,disable,enable}_irq() to prevent
+problems with dropped interrupts (eg, the 8390 driver uses disable_irq()
+to defer the delivery of interrupts).  As a result, these interfaces can
+not be used to implement the desired behaviour.
+
+The side effect of this is that if the 'Ready/IRQ' GPIO is disabled via
+disable_irq() on suspend, and enabled via enable_irq() after resume, we
+will record the state transitions caused by powering events as valid
+interrupts, and foward them to the card driver, which may attempt to
+access a card which is not powered up.
+
+This leads delays resume while drivers spin in their interrupt handlers,
+and complaints from drivers before they realize what's happened.
+
+Moreover, in the case of the 'Ready/IRQ' signal, this is requested and
+freed by the card driver itself; the PCMCIA core has no idea whether the
+interrupt is requested, and, therefore, whether a call to disable_irq()
+would be valid.  (We tried this around 2.4.17 / 2.5.1 kernel era, and
+ended up throwing it out because of this problem.)
+
+Therefore, it was decided back in around 2002 to disable the edge
+triggering instead, resulting in all state transitions on the GPIO being
+ignored.  That's what we actually need the hardware to do.
+
+The commit above changes this behaviour; it explicitly prevents the 'no
+trigger' state being selected.
+
+The reason that request_irq() does not accept the 'no trigger' state is
+for compatibility with existing drivers which do not provide their desired
+triggering configuration.  The set_irq_type() function is 'new' and not
+used by non-trigger aware drivers.
+
+Therefore, revert this change, and restore previously working platforms
+back to their former state.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Cc: linux@arm.linux.org.uk
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/chip.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/kernel/irq/chip.c
++++ b/kernel/irq/chip.c
+@@ -61,8 +61,7 @@ int irq_set_irq_type(unsigned int irq, u
+               return -EINVAL;
+       type &= IRQ_TYPE_SENSE_MASK;
+-      if (type != IRQ_TYPE_NONE)
+-              ret = __irq_set_trigger(desc, irq, type);
++      ret = __irq_set_trigger(desc, irq, type);
+       irq_put_desc_busunlock(desc, flags);
+       return ret;
+ }
diff --git a/queue-3.3/ib-iser-post-initial-receive-buffers-before-sending-the-final-login-request.patch b/queue-3.3/ib-iser-post-initial-receive-buffers-before-sending-the-final-login-request.patch
new file mode 100644 (file)
index 0000000..c067f22
--- /dev/null
@@ -0,0 +1,136 @@
+From 89e984e2c2cd14f77ccb26c47726ac7f13b70ae8 Mon Sep 17 00:00:00 2001
+From: Or Gerlitz <ogerlitz@mellanox.com>
+Date: Mon, 5 Mar 2012 18:21:44 +0200
+Subject: IB/iser: Post initial receive buffers before sending the final login request
+
+From: Or Gerlitz <ogerlitz@mellanox.com>
+
+commit 89e984e2c2cd14f77ccb26c47726ac7f13b70ae8 upstream.
+
+An iser target may send iscsi NO-OP PDUs as soon as it marks the iSER
+iSCSI session as fully operative.  This means that there is window
+where there are no posted receive buffers on the initiator side, so
+it's possible for the iSER RC connection to break because of RNR NAK /
+retry errors.  To fix this, rely on the flags bits in the login
+request to have FFP (0x3) in the lower nibble as a marker for the
+final login request, and post an initial chunk of receive buffers
+before sending that login request instead of after getting the login
+response.
+
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/iser/iscsi_iser.c     |   18 +++-------------
+ drivers/infiniband/ulp/iser/iscsi_iser.h     |    1 
+ drivers/infiniband/ulp/iser/iser_initiator.c |   30 +++++++++++++++------------
+ 3 files changed, 22 insertions(+), 27 deletions(-)
+
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
+@@ -364,6 +364,9 @@ iscsi_iser_conn_bind(struct iscsi_cls_se
+       }
+       ib_conn = ep->dd_data;
++      if (iser_alloc_rx_descriptors(ib_conn))
++              return -ENOMEM;
++
+       /* binds the iSER connection retrieved from the previously
+        * connected ep_handle to the iSCSI layer connection. exchanges
+        * connection pointers */
+@@ -398,19 +401,6 @@ iscsi_iser_conn_stop(struct iscsi_cls_co
+       iser_conn->ib_conn = NULL;
+ }
+-static int
+-iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
+-{
+-      struct iscsi_conn *conn = cls_conn->dd_data;
+-      int err;
+-
+-      err = iser_conn_set_full_featured_mode(conn);
+-      if (err)
+-              return err;
+-
+-      return iscsi_conn_start(cls_conn);
+-}
+-
+ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
+ {
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+@@ -724,7 +714,7 @@ static struct iscsi_transport iscsi_iser
+       .get_conn_param         = iscsi_conn_get_param,
+       .get_ep_param           = iscsi_iser_get_ep_param,
+       .get_session_param      = iscsi_session_get_param,
+-      .start_conn             = iscsi_iser_conn_start,
++      .start_conn             = iscsi_conn_start,
+       .stop_conn              = iscsi_iser_conn_stop,
+       /* iscsi host params */
+       .get_host_param         = iscsi_host_get_param,
+--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
++++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
+@@ -366,4 +366,5 @@ int iser_dma_map_task_data(struct iscsi_
+ void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task);
+ int  iser_initialize_task_headers(struct iscsi_task *task,
+                       struct iser_tx_desc *tx_desc);
++int iser_alloc_rx_descriptors(struct iser_conn *ib_conn);
+ #endif
+--- a/drivers/infiniband/ulp/iser/iser_initiator.c
++++ b/drivers/infiniband/ulp/iser/iser_initiator.c
+@@ -170,7 +170,7 @@ static void iser_create_send_desc(struct
+ }
+-static int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
++int iser_alloc_rx_descriptors(struct iser_conn *ib_conn)
+ {
+       int i, j;
+       u64 dma_addr;
+@@ -242,23 +242,24 @@ void iser_free_rx_descriptors(struct ise
+       kfree(ib_conn->rx_descs);
+ }
+-/**
+- *  iser_conn_set_full_featured_mode - (iSER API)
+- */
+-int iser_conn_set_full_featured_mode(struct iscsi_conn *conn)
++static int iser_post_rx_bufs(struct iscsi_conn *conn, struct iscsi_hdr *req)
+ {
+       struct iscsi_iser_conn *iser_conn = conn->dd_data;
+-      iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
++      iser_dbg("req op %x flags %x\n", req->opcode, req->flags);
++      /* check if this is the last login - going to full feature phase */
++      if ((req->flags & ISCSI_FULL_FEATURE_PHASE) != ISCSI_FULL_FEATURE_PHASE)
++              return 0;
+-      /* Check that there is no posted recv or send buffers left - */
+-      /* they must be consumed during the login phase */
+-      BUG_ON(iser_conn->ib_conn->post_recv_buf_count != 0);
+-      BUG_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
+-
+-      if (iser_alloc_rx_descriptors(iser_conn->ib_conn))
+-              return -ENOMEM;
++      /*
++       * Check that there is one posted recv buffer (for the last login
++       * response) and no posted send buffers left - they must have been
++       * consumed during previous login phases.
++       */
++      WARN_ON(iser_conn->ib_conn->post_recv_buf_count != 1);
++      WARN_ON(atomic_read(&iser_conn->ib_conn->post_send_buf_count) != 0);
++      iser_dbg("Initially post: %d\n", ISER_MIN_POSTED_RX);
+       /* Initial post receive buffers */
+       if (iser_post_recvm(iser_conn->ib_conn, ISER_MIN_POSTED_RX))
+               return -ENOMEM;
+@@ -438,6 +439,9 @@ int iser_send_control(struct iscsi_conn
+               err = iser_post_recvl(iser_conn->ib_conn);
+               if (err)
+                       goto send_control_error;
++              err = iser_post_rx_bufs(conn, task->hdr);
++              if (err)
++                      goto send_control_error;
+       }
+       err = iser_post_send(iser_conn->ib_conn, mdesc);
diff --git a/queue-3.3/ima-fix-kconfig-dependencies.patch b/queue-3.3/ima-fix-kconfig-dependencies.patch
new file mode 100644 (file)
index 0000000..886b77a
--- /dev/null
@@ -0,0 +1,45 @@
+From f4a0391dfa91155bd961673b31eb42d9d45c799d Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@gmail.com>
+Date: Thu, 5 Jan 2012 12:49:54 -0200
+Subject: ima: fix Kconfig dependencies
+
+From: Fabio Estevam <festevam@gmail.com>
+
+commit f4a0391dfa91155bd961673b31eb42d9d45c799d upstream.
+
+Fix the following build warning:
+warning: (IMA) selects TCG_TPM which has unmet direct dependencies
+(HAS_IOMEM && EXPERIMENTAL)
+
+Suggested-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
+Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
+Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
+Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/Kconfig       |    1 -
+ security/integrity/ima/Kconfig |    2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/char/tpm/Kconfig
++++ b/drivers/char/tpm/Kconfig
+@@ -5,7 +5,6 @@
+ menuconfig TCG_TPM
+       tristate "TPM Hardware Support"
+       depends on HAS_IOMEM
+-      depends on EXPERIMENTAL
+       select SECURITYFS
+       ---help---
+         If you have a TPM security chip in your system, which
+--- a/security/integrity/ima/Kconfig
++++ b/security/integrity/ima/Kconfig
+@@ -9,7 +9,7 @@ config IMA
+       select CRYPTO_HMAC
+       select CRYPTO_MD5
+       select CRYPTO_SHA1
+-      select TCG_TPM if !S390 && !UML
++      select TCG_TPM if HAS_IOMEM && !UML
+       select TCG_TIS if TCG_TPM
+       help
+         The Trusted Computing Group(TCG) runtime Integrity
diff --git a/queue-3.3/iwlwifi-always-monitor-for-stuck-queues.patch b/queue-3.3/iwlwifi-always-monitor-for-stuck-queues.patch
new file mode 100644 (file)
index 0000000..c497bf8
--- /dev/null
@@ -0,0 +1,63 @@
+From 342bbf3fee2fa9a18147e74b2e3c4229a4564912 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Sun, 4 Mar 2012 08:50:46 -0800
+Subject: iwlwifi: always monitor for stuck queues
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 342bbf3fee2fa9a18147e74b2e3c4229a4564912 upstream.
+
+If we only monitor while associated, the following
+can happen:
+ - we're associated, and the queue stuck check
+   runs, setting the queue "touch" time to X
+ - we disassociate, stopping the monitoring,
+   which leaves the time set to X
+ - almost 2s later, we associate, and enqueue
+   a frame
+ - before the frame is transmitted, we monitor
+   for stuck queues, and find the time set to
+   X, although it is now later than X + 2000ms,
+   so we decide that the queue is stuck and
+   erroneously restart the device
+
+It happens more with P2P because there we can
+go between associated/unassociated frequently.
+
+Reported-by: Ben Cahill <ben.m.cahill@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-core.c |   18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -1465,20 +1465,10 @@ void iwl_bg_watchdog(unsigned long data)
+       if (timeout == 0)
+               return;
+-      /* monitor and check for stuck cmd queue */
+-      if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue))
+-              return;
+-
+-      /* monitor and check for other stuck queues */
+-      if (iwl_is_any_associated(priv)) {
+-              for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
+-                      /* skip as we already checked the command queue */
+-                      if (cnt == priv->shrd->cmd_queue)
+-                              continue;
+-                      if (iwl_check_stuck_queue(priv, cnt))
+-                              return;
+-              }
+-      }
++      /* monitor and check for stuck queues */
++      for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++)
++              if (iwl_check_stuck_queue(priv, cnt))
++                      return;
+       mod_timer(&priv->watchdog, jiffies +
+                 msecs_to_jiffies(IWL_WD_TICK(timeout)));
diff --git a/queue-3.3/math-introduce-div64_long.patch b/queue-3.3/math-introduce-div64_long.patch
new file mode 100644 (file)
index 0000000..a8d7249
--- /dev/null
@@ -0,0 +1,43 @@
+From f910381a55cdaa097030291f272f6e6e4380c39a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <levinsasha928@gmail.com>
+Date: Thu, 15 Mar 2012 12:36:13 -0400
+Subject: math: Introduce div64_long
+
+From: Sasha Levin <levinsasha928@gmail.com>
+
+commit f910381a55cdaa097030291f272f6e6e4380c39a upstream.
+
+Add a div64_long macro which is used to devide a 64bit number by a long (which
+can be 4 bytes on 32bit systems and 8 bytes on 64bit systems).
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
+Cc: johnstul@us.ibm.com
+Link: http://lkml.kernel.org/r/1331829374-31543-1-git-send-email-levinsasha928@gmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/math64.h |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/include/linux/math64.h
++++ b/include/linux/math64.h
+@@ -6,6 +6,8 @@
+ #if BITS_PER_LONG == 64
++#define div64_long(x,y) div64_s64((x),(y))
++
+ /**
+  * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder
+  *
+@@ -45,6 +47,8 @@ static inline s64 div64_s64(s64 dividend
+ #elif BITS_PER_LONG == 32
++#define div64_long(x,y) div_s64((x),(y))
++
+ #ifndef div_u64_rem
+ static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
+ {
diff --git a/queue-3.3/mlx4_core-fix-one-more-static-exported-function.patch b/queue-3.3/mlx4_core-fix-one-more-static-exported-function.patch
new file mode 100644 (file)
index 0000000..f5c3cfe
--- /dev/null
@@ -0,0 +1,31 @@
+From e10903b087e425298fb86c6ad4b1a88735480db7 Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Sun, 26 Feb 2012 01:48:12 -0800
+Subject: mlx4_core: Fix one more static exported function
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit e10903b087e425298fb86c6ad4b1a88735480db7 upstream.
+
+Commit 22c8bff6face ("mlx4_core: Exported functions can't be static")
+fixed most of this up, but forgot about mlx4_is_slave_active().  Fix
+this one too.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/main.c
++++ b/drivers/net/ethernet/mellanox/mlx4/main.c
+@@ -394,7 +394,7 @@ static int mlx4_how_many_lives_vf(struct
+       return ret;
+ }
+-static int mlx4_is_slave_active(struct mlx4_dev *dev, int slave)
++int mlx4_is_slave_active(struct mlx4_dev *dev, int slave)
+ {
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_slave_state *s_slave;
diff --git a/queue-3.3/mm-thp-fix-pmd_bad-triggering-in-code-paths-holding-mmap_sem-read-mode.patch b/queue-3.3/mm-thp-fix-pmd_bad-triggering-in-code-paths-holding-mmap_sem-read-mode.patch
new file mode 100644 (file)
index 0000000..d2991b3
--- /dev/null
@@ -0,0 +1,461 @@
+From 1a5a9906d4e8d1976b701f889d8f35d54b928f25 Mon Sep 17 00:00:00 2001
+From: Andrea Arcangeli <aarcange@redhat.com>
+Date: Wed, 21 Mar 2012 16:33:42 -0700
+Subject: mm: thp: fix pmd_bad() triggering in code paths holding mmap_sem read mode
+
+From: Andrea Arcangeli <aarcange@redhat.com>
+
+commit 1a5a9906d4e8d1976b701f889d8f35d54b928f25 upstream.
+
+In some cases it may happen that pmd_none_or_clear_bad() is called with
+the mmap_sem hold in read mode.  In those cases the huge page faults can
+allocate hugepmds under pmd_none_or_clear_bad() and that can trigger a
+false positive from pmd_bad() that will not like to see a pmd
+materializing as trans huge.
+
+It's not khugepaged causing the problem, khugepaged holds the mmap_sem
+in write mode (and all those sites must hold the mmap_sem in read mode
+to prevent pagetables to go away from under them, during code review it
+seems vm86 mode on 32bit kernels requires that too unless it's
+restricted to 1 thread per process or UP builds).  The race is only with
+the huge pagefaults that can convert a pmd_none() into a
+pmd_trans_huge().
+
+Effectively all these pmd_none_or_clear_bad() sites running with
+mmap_sem in read mode are somewhat speculative with the page faults, and
+the result is always undefined when they run simultaneously.  This is
+probably why it wasn't common to run into this.  For example if the
+madvise(MADV_DONTNEED) runs zap_page_range() shortly before the page
+fault, the hugepage will not be zapped, if the page fault runs first it
+will be zapped.
+
+Altering pmd_bad() not to error out if it finds hugepmds won't be enough
+to fix this, because zap_pmd_range would then proceed to call
+zap_pte_range (which would be incorrect if the pmd become a
+pmd_trans_huge()).
+
+The simplest way to fix this is to read the pmd in the local stack
+(regardless of what we read, no need of actual CPU barriers, only
+compiler barrier needed), and be sure it is not changing under the code
+that computes its value.  Even if the real pmd is changing under the
+value we hold on the stack, we don't care.  If we actually end up in
+zap_pte_range it means the pmd was not none already and it was not huge,
+and it can't become huge from under us (khugepaged locking explained
+above).
+
+All we need is to enforce that there is no way anymore that in a code
+path like below, pmd_trans_huge can be false, but pmd_none_or_clear_bad
+can run into a hugepmd.  The overhead of a barrier() is just a compiler
+tweak and should not be measurable (I only added it for THP builds).  I
+don't exclude different compiler versions may have prevented the race
+too by caching the value of *pmd on the stack (that hasn't been
+verified, but it wouldn't be impossible considering
+pmd_none_or_clear_bad, pmd_bad, pmd_trans_huge, pmd_none are all inlines
+and there's no external function called in between pmd_trans_huge and
+pmd_none_or_clear_bad).
+
+               if (pmd_trans_huge(*pmd)) {
+                       if (next-addr != HPAGE_PMD_SIZE) {
+                               VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
+                               split_huge_page_pmd(vma->vm_mm, pmd);
+                       } else if (zap_huge_pmd(tlb, vma, pmd, addr))
+                               continue;
+                       /* fall through */
+               }
+               if (pmd_none_or_clear_bad(pmd))
+
+Because this race condition could be exercised without special
+privileges this was reported in CVE-2012-1179.
+
+The race was identified and fully explained by Ulrich who debugged it.
+I'm quoting his accurate explanation below, for reference.
+
+====== start quote =======
+      mapcount 0 page_mapcount 1
+      kernel BUG at mm/huge_memory.c:1384!
+
+    At some point prior to the panic, a "bad pmd ..." message similar to the
+    following is logged on the console:
+
+      mm/memory.c:145: bad pmd ffff8800376e1f98(80000000314000e7).
+
+    The "bad pmd ..." message is logged by pmd_clear_bad() before it clears
+    the page's PMD table entry.
+
+        143 void pmd_clear_bad(pmd_t *pmd)
+        144 {
+    ->  145         pmd_ERROR(*pmd);
+        146         pmd_clear(pmd);
+        147 }
+
+    After the PMD table entry has been cleared, there is an inconsistency
+    between the actual number of PMD table entries that are mapping the page
+    and the page's map count (_mapcount field in struct page). When the page
+    is subsequently reclaimed, __split_huge_page() detects this inconsistency.
+
+       1381         if (mapcount != page_mapcount(page))
+       1382                 printk(KERN_ERR "mapcount %d page_mapcount %d\n",
+       1383                        mapcount, page_mapcount(page));
+    -> 1384         BUG_ON(mapcount != page_mapcount(page));
+
+    The root cause of the problem is a race of two threads in a multithreaded
+    process. Thread B incurs a page fault on a virtual address that has never
+    been accessed (PMD entry is zero) while Thread A is executing an madvise()
+    system call on a virtual address within the same 2 MB (huge page) range.
+
+               virtual address space
+              .---------------------.
+              |                     |
+              |                     |
+            .-|---------------------|
+            | |                     |
+            | |                     |<-- B(fault)
+            | |                     |
+      2 MB  | |/////////////////////|-.
+      huge <  |/////////////////////|  > A(range)
+      page  | |/////////////////////|-'
+            | |                     |
+            | |                     |
+            '-|---------------------|
+              |                     |
+              |                     |
+              '---------------------'
+
+    - Thread A is executing an madvise(..., MADV_DONTNEED) system call
+      on the virtual address range "A(range)" shown in the picture.
+
+    sys_madvise
+      // Acquire the semaphore in shared mode.
+      down_read(&current->mm->mmap_sem)
+      ...
+      madvise_vma
+        switch (behavior)
+        case MADV_DONTNEED:
+             madvise_dontneed
+               zap_page_range
+                 unmap_vmas
+                   unmap_page_range
+                     zap_pud_range
+                       zap_pmd_range
+                         //
+                         // Assume that this huge page has never been accessed.
+                         // I.e. content of the PMD entry is zero (not mapped).
+                         //
+                         if (pmd_trans_huge(*pmd)) {
+                             // We don't get here due to the above assumption.
+                         }
+                         //
+                         // Assume that Thread B incurred a page fault and
+             .---------> // sneaks in here as shown below.
+             |           //
+             |           if (pmd_none_or_clear_bad(pmd))
+             |               {
+             |                 if (unlikely(pmd_bad(*pmd)))
+             |                     pmd_clear_bad
+             |                     {
+             |                       pmd_ERROR
+             |                         // Log "bad pmd ..." message here.
+             |                       pmd_clear
+             |                         // Clear the page's PMD entry.
+             |                         // Thread B incremented the map count
+             |                         // in page_add_new_anon_rmap(), but
+             |                         // now the page is no longer mapped
+             |                         // by a PMD entry (-> inconsistency).
+             |                     }
+             |               }
+             |
+             v
+    - Thread B is handling a page fault on virtual address "B(fault)" shown
+      in the picture.
+
+    ...
+    do_page_fault
+      __do_page_fault
+        // Acquire the semaphore in shared mode.
+        down_read_trylock(&mm->mmap_sem)
+        ...
+        handle_mm_fault
+          if (pmd_none(*pmd) && transparent_hugepage_enabled(vma))
+              // We get here due to the above assumption (PMD entry is zero).
+              do_huge_pmd_anonymous_page
+                alloc_hugepage_vma
+                  // Allocate a new transparent huge page here.
+                ...
+                __do_huge_pmd_anonymous_page
+                  ...
+                  spin_lock(&mm->page_table_lock)
+                  ...
+                  page_add_new_anon_rmap
+                    // Here we increment the page's map count (starts at -1).
+                    atomic_set(&page->_mapcount, 0)
+                  set_pmd_at
+                    // Here we set the page's PMD entry which will be cleared
+                    // when Thread A calls pmd_clear_bad().
+                  ...
+                  spin_unlock(&mm->page_table_lock)
+
+    The mmap_sem does not prevent the race because both threads are acquiring
+    it in shared mode (down_read).  Thread B holds the page_table_lock while
+    the page's map count and PMD table entry are updated.  However, Thread A
+    does not synchronize on that lock.
+
+====== end quote =======
+
+[akpm@linux-foundation.org: checkpatch fixes]
+Reported-by: Ulrich Obergfell <uobergfe@redhat.com>
+Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
+Acked-by: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Mel Gorman <mgorman@suse.de>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Dave Jones <davej@redhat.com>
+Acked-by: Larry Woodman <lwoodman@redhat.com>
+Acked-by: Rik van Riel <riel@redhat.com>
+Cc: Mark Salter <msalter@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/vm86_32.c     |    2 +
+ fs/proc/task_mmu.c            |    9 ++++++
+ include/asm-generic/pgtable.h |   61 ++++++++++++++++++++++++++++++++++++++++++
+ mm/memcontrol.c               |    4 ++
+ mm/memory.c                   |   16 ++++++++---
+ mm/mempolicy.c                |    2 -
+ mm/mincore.c                  |    2 -
+ mm/pagewalk.c                 |    2 -
+ mm/swapfile.c                 |    4 --
+ 9 files changed, 92 insertions(+), 10 deletions(-)
+
+--- a/arch/x86/kernel/vm86_32.c
++++ b/arch/x86/kernel/vm86_32.c
+@@ -172,6 +172,7 @@ static void mark_screen_rdonly(struct mm
+       spinlock_t *ptl;
+       int i;
++      down_write(&mm->mmap_sem);
+       pgd = pgd_offset(mm, 0xA0000);
+       if (pgd_none_or_clear_bad(pgd))
+               goto out;
+@@ -190,6 +191,7 @@ static void mark_screen_rdonly(struct mm
+       }
+       pte_unmap_unlock(pte, ptl);
+ out:
++      up_write(&mm->mmap_sem);
+       flush_tlb();
+ }
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -409,6 +409,9 @@ static int smaps_pte_range(pmd_t *pmd, u
+       } else {
+               spin_unlock(&walk->mm->page_table_lock);
+       }
++
++      if (pmd_trans_unstable(pmd))
++              return 0;
+       /*
+        * The mmap_sem held all the way back in m_start() is what
+        * keeps khugepaged out of here and from collapsing things
+@@ -507,6 +510,8 @@ static int clear_refs_pte_range(pmd_t *p
+       struct page *page;
+       split_huge_page_pmd(walk->mm, pmd);
++      if (pmd_trans_unstable(pmd))
++              return 0;
+       pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+       for (; addr != end; pte++, addr += PAGE_SIZE) {
+@@ -670,6 +675,8 @@ static int pagemap_pte_range(pmd_t *pmd,
+       int err = 0;
+       split_huge_page_pmd(walk->mm, pmd);
++      if (pmd_trans_unstable(pmd))
++              return 0;
+       /* find the first VMA at or above 'addr' */
+       vma = find_vma(walk->mm, addr);
+@@ -961,6 +968,8 @@ static int gather_pte_stats(pmd_t *pmd,
+               spin_unlock(&walk->mm->page_table_lock);
+       }
++      if (pmd_trans_unstable(pmd))
++              return 0;
+       orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+       do {
+               struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
+--- a/include/asm-generic/pgtable.h
++++ b/include/asm-generic/pgtable.h
+@@ -425,6 +425,8 @@ extern void untrack_pfn_vma(struct vm_ar
+                               unsigned long size);
+ #endif
++#ifdef CONFIG_MMU
++
+ #ifndef CONFIG_TRANSPARENT_HUGEPAGE
+ static inline int pmd_trans_huge(pmd_t pmd)
+ {
+@@ -441,7 +443,66 @@ static inline int pmd_write(pmd_t pmd)
+       return 0;
+ }
+ #endif /* __HAVE_ARCH_PMD_WRITE */
++#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
++
++/*
++ * This function is meant to be used by sites walking pagetables with
++ * the mmap_sem hold in read mode to protect against MADV_DONTNEED and
++ * transhuge page faults. MADV_DONTNEED can convert a transhuge pmd
++ * into a null pmd and the transhuge page fault can convert a null pmd
++ * into an hugepmd or into a regular pmd (if the hugepage allocation
++ * fails). While holding the mmap_sem in read mode the pmd becomes
++ * stable and stops changing under us only if it's not null and not a
++ * transhuge pmd. When those races occurs and this function makes a
++ * difference vs the standard pmd_none_or_clear_bad, the result is
++ * undefined so behaving like if the pmd was none is safe (because it
++ * can return none anyway). The compiler level barrier() is critically
++ * important to compute the two checks atomically on the same pmdval.
++ */
++static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
++{
++      /* depend on compiler for an atomic pmd read */
++      pmd_t pmdval = *pmd;
++      /*
++       * The barrier will stabilize the pmdval in a register or on
++       * the stack so that it will stop changing under the code.
++       */
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++      barrier();
+ #endif
++      if (pmd_none(pmdval))
++              return 1;
++      if (unlikely(pmd_bad(pmdval))) {
++              if (!pmd_trans_huge(pmdval))
++                      pmd_clear_bad(pmd);
++              return 1;
++      }
++      return 0;
++}
++
++/*
++ * This is a noop if Transparent Hugepage Support is not built into
++ * the kernel. Otherwise it is equivalent to
++ * pmd_none_or_trans_huge_or_clear_bad(), and shall only be called in
++ * places that already verified the pmd is not none and they want to
++ * walk ptes while holding the mmap sem in read mode (write mode don't
++ * need this). If THP is not enabled, the pmd can't go away under the
++ * code even if MADV_DONTNEED runs, but if THP is enabled we need to
++ * run a pmd_trans_unstable before walking the ptes after
++ * split_huge_page_pmd returns (because it may have run when the pmd
++ * become null, but then a page fault can map in a THP and not a
++ * regular page).
++ */
++static inline int pmd_trans_unstable(pmd_t *pmd)
++{
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++      return pmd_none_or_trans_huge_or_clear_bad(pmd);
++#else
++      return 0;
++#endif
++}
++
++#endif /* CONFIG_MMU */
+ #endif /* !__ASSEMBLY__ */
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -5234,6 +5234,8 @@ static int mem_cgroup_count_precharge_pt
+       spinlock_t *ptl;
+       split_huge_page_pmd(walk->mm, pmd);
++      if (pmd_trans_unstable(pmd))
++              return 0;
+       pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+       for (; addr != end; pte++, addr += PAGE_SIZE)
+@@ -5396,6 +5398,8 @@ static int mem_cgroup_move_charge_pte_ra
+       spinlock_t *ptl;
+       split_huge_page_pmd(walk->mm, pmd);
++      if (pmd_trans_unstable(pmd))
++              return 0;
+ retry:
+       pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+       for (; addr != end; addr += PAGE_SIZE) {
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1247,16 +1247,24 @@ static inline unsigned long zap_pmd_rang
+       do {
+               next = pmd_addr_end(addr, end);
+               if (pmd_trans_huge(*pmd)) {
+-                      if (next-addr != HPAGE_PMD_SIZE) {
++                      if (next - addr != HPAGE_PMD_SIZE) {
+                               VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
+                               split_huge_page_pmd(vma->vm_mm, pmd);
+                       } else if (zap_huge_pmd(tlb, vma, pmd, addr))
+-                              continue;
++                              goto next;
+                       /* fall through */
+               }
+-              if (pmd_none_or_clear_bad(pmd))
+-                      continue;
++              /*
++               * Here there can be other concurrent MADV_DONTNEED or
++               * trans huge page faults running, and if the pmd is
++               * none or trans huge it can change under us. This is
++               * because MADV_DONTNEED holds the mmap_sem in read
++               * mode.
++               */
++              if (pmd_none_or_trans_huge_or_clear_bad(pmd))
++                      goto next;
+               next = zap_pte_range(tlb, vma, pmd, addr, next, details);
++next:
+               cond_resched();
+       } while (pmd++, addr = next, addr != end);
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -512,7 +512,7 @@ static inline int check_pmd_range(struct
+       do {
+               next = pmd_addr_end(addr, end);
+               split_huge_page_pmd(vma->vm_mm, pmd);
+-              if (pmd_none_or_clear_bad(pmd))
++              if (pmd_none_or_trans_huge_or_clear_bad(pmd))
+                       continue;
+               if (check_pte_range(vma, pmd, addr, next, nodes,
+                                   flags, private))
+--- a/mm/mincore.c
++++ b/mm/mincore.c
+@@ -164,7 +164,7 @@ static void mincore_pmd_range(struct vm_
+                       }
+                       /* fall through */
+               }
+-              if (pmd_none_or_clear_bad(pmd))
++              if (pmd_none_or_trans_huge_or_clear_bad(pmd))
+                       mincore_unmapped_range(vma, addr, next, vec);
+               else
+                       mincore_pte_range(vma, pmd, addr, next, vec);
+--- a/mm/pagewalk.c
++++ b/mm/pagewalk.c
+@@ -59,7 +59,7 @@ again:
+                       continue;
+               split_huge_page_pmd(walk->mm, pmd);
+-              if (pmd_none_or_clear_bad(pmd))
++              if (pmd_none_or_trans_huge_or_clear_bad(pmd))
+                       goto again;
+               err = walk_pte_range(pmd, addr, next, walk);
+               if (err)
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -932,9 +932,7 @@ static inline int unuse_pmd_range(struct
+       pmd = pmd_offset(pud, addr);
+       do {
+               next = pmd_addr_end(addr, end);
+-              if (unlikely(pmd_trans_huge(*pmd)))
+-                      continue;
+-              if (pmd_none_or_clear_bad(pmd))
++              if (pmd_none_or_trans_huge_or_clear_bad(pmd))
+                       continue;
+               ret = unuse_pte_range(vma, pmd, addr, next, entry, page);
+               if (ret)
diff --git a/queue-3.3/ntp-fix-integer-overflow-when-setting-time.patch b/queue-3.3/ntp-fix-integer-overflow-when-setting-time.patch
new file mode 100644 (file)
index 0000000..d380a15
--- /dev/null
@@ -0,0 +1,37 @@
+From a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <levinsasha928@gmail.com>
+Date: Thu, 15 Mar 2012 12:36:14 -0400
+Subject: ntp: Fix integer overflow when setting time
+
+From: Sasha Levin <levinsasha928@gmail.com>
+
+commit a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33 upstream.
+
+'long secs' is passed as divisor to div_s64, which accepts a 32bit
+divisor. On 64bit machines that value is trimmed back from 8 bytes
+back to 4, causing a divide by zero when the number is bigger than
+(1 << 32) - 1 and all 32 lower bits are 0.
+
+Use div64_long() instead.
+
+Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
+Cc: johnstul@us.ibm.com
+Link: http://lkml.kernel.org/r/1331829374-31543-2-git-send-email-levinsasha928@gmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/time/ntp.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/time/ntp.c
++++ b/kernel/time/ntp.c
+@@ -275,7 +275,7 @@ static inline s64 ntp_update_offset_fll(
+       time_status |= STA_MODE;
+-      return div_s64(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);
++      return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);
+ }
+ static void ntp_update_offset(long offset)
diff --git a/queue-3.3/p54spi-release-gpio-lines-and-irq-on-error-in-p54spi_probe.patch b/queue-3.3/p54spi-release-gpio-lines-and-irq-on-error-in-p54spi_probe.patch
new file mode 100644 (file)
index 0000000..1cb4356
--- /dev/null
@@ -0,0 +1,68 @@
+From 62ebeed8d00aef75eac4fd6c161cae75a41965ca Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc@gmail.com>
+Date: Thu, 1 Mar 2012 00:40:08 +0400
+Subject: p54spi: Release GPIO lines and IRQ on error in p54spi_probe
+
+From: Max Filippov <jcmvbkbc@gmail.com>
+
+commit 62ebeed8d00aef75eac4fd6c161cae75a41965ca upstream.
+
+This makes it possible to reload driver if insmod has failed due to
+missing firmware.
+
+Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
+Acked-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/p54/p54spi.c |   14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/p54/p54spi.c
++++ b/drivers/net/wireless/p54/p54spi.c
+@@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct
+       ret = spi_setup(spi);
+       if (ret < 0) {
+               dev_err(&priv->spi->dev, "spi_setup failed");
+-              goto err_free_common;
++              goto err_free;
+       }
+       ret = gpio_request(p54spi_gpio_power, "p54spi power");
+       if (ret < 0) {
+               dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+-              goto err_free_common;
++              goto err_free;
+       }
+       ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
+       if (ret < 0) {
+               dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
+-              goto err_free_common;
++              goto err_free_gpio_power;
+       }
+       gpio_direction_output(p54spi_gpio_power, 0);
+@@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct
+                         priv->spi);
+       if (ret < 0) {
+               dev_err(&priv->spi->dev, "request_irq() failed");
+-              goto err_free_common;
++              goto err_free_gpio_irq;
+       }
+       irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
+@@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct
+       return 0;
+ err_free_common:
++      free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
++err_free_gpio_irq:
++      gpio_free(p54spi_gpio_irq);
++err_free_gpio_power:
++      gpio_free(p54spi_gpio_power);
++err_free:
+       p54_free_common(priv->hw);
+       return ret;
+ }
diff --git a/queue-3.3/rt2x00-add-support-for-d-link-dwa-127-to-rt2800usb.patch b/queue-3.3/rt2x00-add-support-for-d-link-dwa-127-to-rt2800usb.patch
new file mode 100644 (file)
index 0000000..dbb349e
--- /dev/null
@@ -0,0 +1,31 @@
+From d42a179b941a9e4cc6cf41d0f3cbadd75fc48a89 Mon Sep 17 00:00:00 2001
+From: Gertjan van Wingerde <gwingerde@gmail.com>
+Date: Sat, 11 Feb 2012 21:58:09 +0100
+Subject: rt2x00: Add support for D-Link DWA-127 to rt2800usb.
+
+From: Gertjan van Wingerde <gwingerde@gmail.com>
+
+commit d42a179b941a9e4cc6cf41d0f3cbadd75fc48a89 upstream.
+
+This is an RT3070 based device.
+
+Reported-by: Mikhail Kryshen <mikhail@kryshen.net>
+Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
+Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rt2x00/rt2800usb.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800usb.c
++++ b/drivers/net/wireless/rt2x00/rt2800usb.c
+@@ -922,6 +922,7 @@ static struct usb_device_id rt2800usb_de
+       { USB_DEVICE(0x07d1, 0x3c13) },
+       { USB_DEVICE(0x07d1, 0x3c15) },
+       { USB_DEVICE(0x07d1, 0x3c16) },
++      { USB_DEVICE(0x2001, 0x3c1b) },
+       /* Draytek */
+       { USB_DEVICE(0x07fa, 0x7712) },
+       /* DVICO */
diff --git a/queue-3.3/rtc-disable-the-alarm-in-the-hardware-v2.patch b/queue-3.3/rtc-disable-the-alarm-in-the-hardware-v2.patch
new file mode 100644 (file)
index 0000000..3d18fab
--- /dev/null
@@ -0,0 +1,74 @@
+From 41c7f7424259ff11009449f87c95656f69f9b186 Mon Sep 17 00:00:00 2001
+From: Rabin Vincent <rabin.vincent@stericsson.com>
+Date: Tue, 22 Nov 2011 11:03:14 +0100
+Subject: rtc: Disable the alarm in the hardware (v2)
+
+From: Rabin Vincent <rabin.vincent@stericsson.com>
+
+commit 41c7f7424259ff11009449f87c95656f69f9b186 upstream.
+
+Currently, the RTC code does not disable the alarm in the hardware.
+
+This means that after a sequence such as the one below (the files are in the
+RTC sysfs), the box will boot up after 2 minutes even though we've
+asked for the alarm to be turned off.
+
+       # echo $((`cat since_epoch`)+120) > wakealarm
+       # echo 0 > wakealarm
+       # poweroff
+
+Fix this by disabling the alarm when there are no timers to run.
+
+The original version of this patch was reverted. This version
+disables the irq directly instead of setting a disabled timer
+in the future.
+
+Cc: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
+[Merged in the second revision from Rabin]
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/interface.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -763,6 +763,14 @@ static int rtc_timer_enqueue(struct rtc_
+       return 0;
+ }
++static void rtc_alarm_disable(struct rtc_device *rtc)
++{
++      if (!rtc->ops || !rtc->ops->alarm_irq_enable)
++              return;
++
++      rtc->ops->alarm_irq_enable(rtc->dev.parent, false);
++}
++
+ /**
+  * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
+  * @rtc rtc device
+@@ -784,8 +792,10 @@ static void rtc_timer_remove(struct rtc_
+               struct rtc_wkalrm alarm;
+               int err;
+               next = timerqueue_getnext(&rtc->timerqueue);
+-              if (!next)
++              if (!next) {
++                      rtc_alarm_disable(rtc);
+                       return;
++              }
+               alarm.time = rtc_ktime_to_tm(next->expires);
+               alarm.enabled = 1;
+               err = __rtc_set_alarm(rtc, &alarm);
+@@ -847,7 +857,8 @@ again:
+               err = __rtc_set_alarm(rtc, &alarm);
+               if (err == -ETIME)
+                       goto again;
+-      }
++      } else
++              rtc_alarm_disable(rtc);
+       mutex_unlock(&rtc->ops_lock);
+ }
diff --git a/queue-3.3/rtlwifi-handle-previous-allocation-failures-when-freeing-device-memory.patch b/queue-3.3/rtlwifi-handle-previous-allocation-failures-when-freeing-device-memory.patch
new file mode 100644 (file)
index 0000000..a4604f3
--- /dev/null
@@ -0,0 +1,56 @@
+From 7f66c2f93e5779625c10d262c84537427a2673ca Mon Sep 17 00:00:00 2001
+From: Simon Graham <simon.graham@virtualcomputer.com>
+Date: Tue, 7 Feb 2012 18:07:38 -0600
+Subject: rtlwifi: Handle previous allocation failures when freeing device memory
+
+From: Simon Graham <simon.graham@virtualcomputer.com>
+
+commit 7f66c2f93e5779625c10d262c84537427a2673ca upstream.
+
+Handle previous allocation failures when freeing device memory
+
+Signed-off-by: Simon Graham <simon.graham@virtualcomputer.com>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/pci.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/pci.c
++++ b/drivers/net/wireless/rtlwifi/pci.c
+@@ -1157,10 +1157,12 @@ static void _rtl_pci_free_tx_ring(struct
+               ring->idx = (ring->idx + 1) % ring->entries;
+       }
+-      pci_free_consistent(rtlpci->pdev,
+-                          sizeof(*ring->desc) * ring->entries,
+-                          ring->desc, ring->dma);
+-      ring->desc = NULL;
++      if (ring->desc) {
++              pci_free_consistent(rtlpci->pdev,
++                                  sizeof(*ring->desc) * ring->entries,
++                                  ring->desc, ring->dma);
++              ring->desc = NULL;
++      }
+ }
+ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci)
+@@ -1184,12 +1186,14 @@ static void _rtl_pci_free_rx_ring(struct
+                       kfree_skb(skb);
+               }
+-              pci_free_consistent(rtlpci->pdev,
++              if (rtlpci->rx_ring[rx_queue_idx].desc) {
++                      pci_free_consistent(rtlpci->pdev,
+                                   sizeof(*rtlpci->rx_ring[rx_queue_idx].
+                                          desc) * rtlpci->rxringcount,
+                                   rtlpci->rx_ring[rx_queue_idx].desc,
+                                   rtlpci->rx_ring[rx_queue_idx].dma);
+-              rtlpci->rx_ring[rx_queue_idx].desc = NULL;
++                      rtlpci->rx_ring[rx_queue_idx].desc = NULL;
++              }
+       }
+ }
diff --git a/queue-3.3/rtlwifi-rtl8192c-prevent-sleeping-from-invalid-context-in-rtl8192cu.patch b/queue-3.3/rtlwifi-rtl8192c-prevent-sleeping-from-invalid-context-in-rtl8192cu.patch
new file mode 100644 (file)
index 0000000..c67f114
--- /dev/null
@@ -0,0 +1,53 @@
+From ebecdcc12fed5d3c81853dea61a0a78a5aefab52 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Fri, 2 Mar 2012 15:23:36 -0600
+Subject: rtlwifi: rtl8192c: Prevent sleeping from invalid context in rtl8192cu
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit ebecdcc12fed5d3c81853dea61a0a78a5aefab52 upstream.
+
+When driver rtl8192cu is used with the debug level set to 3 or greater,
+the result is "sleeping function called from invalid context" due to
+an rcu_read_lock() call in the DM refresh routine in driver rtl8192c.
+This lock is not necessary as the USB driver does not use the struct
+being protected, thus the lock is set only when a PCI interface is
+active.
+
+This bug is reported in https://bugzilla.kernel.org/show_bug.cgi?id=42775.
+
+Reported-by: Ronald Wahl <ronald.wahl@raritan.com>
+Tested-by: Ronald Wahl <ronald.wahl@raritan.com>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Cc: Ronald Wahl <ronald.wahl@raritan.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c |   11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+@@ -1219,13 +1219,18 @@ static void rtl92c_dm_refresh_rate_adapt
+                                ("PreState = %d, CurState = %d\n",
+                                 p_ra->pre_ratr_state, p_ra->ratr_state));
+-                      rcu_read_lock();
+-                      sta = ieee80211_find_sta(mac->vif, mac->bssid);
++                      /* Only the PCI card uses sta in the update rate table
++                       * callback routine */
++                      if (rtlhal->interface == INTF_PCI) {
++                              rcu_read_lock();
++                              sta = ieee80211_find_sta(mac->vif, mac->bssid);
++                      }
+                       rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
+                                       p_ra->ratr_state);
+                       p_ra->pre_ratr_state = p_ra->ratr_state;
+-                      rcu_read_unlock();
++                      if (rtlhal->interface == INTF_PCI)
++                              rcu_read_unlock();
+               }
+       }
+ }
diff --git a/queue-3.3/rtlwifi-rtl8192c_common-rtl8192de-check-for-allocation-failures.patch b/queue-3.3/rtlwifi-rtl8192c_common-rtl8192de-check-for-allocation-failures.patch
new file mode 100644 (file)
index 0000000..24af8f0
--- /dev/null
@@ -0,0 +1,93 @@
+From 76a92be537f1c8c259e393632301446257ca3ea9 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sat, 7 Jan 2012 20:46:40 -0600
+Subject: rtlwifi: rtl8192c_common: rtl8192de: Check for allocation failures
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 76a92be537f1c8c259e393632301446257ca3ea9 upstream.
+
+In https://bugzilla.redhat.com/show_bug.cgi?id=771656, a kernel bug was
+triggered due to a failed skb allocation that was not checked. This event
+lead to an audit of all memory allocations in the complete rtlwifi family
+of drivers. This patch fixes the rest.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/pci.c                |    2 ++
+ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c |    2 ++
+ drivers/net/wireless/rtlwifi/rtl8192de/fw.c       |   14 +++++++++-----
+ drivers/net/wireless/rtlwifi/usb.c                |   12 +++++++-----
+ 4 files changed, 20 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/wireless/rtlwifi/pci.c
++++ b/drivers/net/wireless/rtlwifi/pci.c
+@@ -657,6 +657,8 @@ static void _rtl_receive_one(struct ieee
+               return;
+       uskb = dev_alloc_skb(skb->len + 128);
++      if (!uskb)
++              return;         /* exit if allocation failed */
+       memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status));
+       pdata = (u8 *)skb_put(uskb, skb->len);
+       memcpy(pdata, skb->data, skb->len);
+--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+@@ -788,6 +788,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ie
+       skb = dev_alloc_skb(totalpacketlen);
++      if (!skb)
++              return;
+       memcpy((u8 *) skb_put(skb, totalpacketlen),
+              &reserved_page_packet, totalpacketlen);
+--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+@@ -763,12 +763,16 @@ void rtl92d_set_fw_rsvdpagepkt(struct ie
+                     "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n",
+                     u1RsvdPageLoc, 3);
+       skb = dev_alloc_skb(totalpacketlen);
+-      memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet,
+-              totalpacketlen);
+-      rtstatus = _rtl92d_cmd_send_packet(hw, skb);
++      if (!skb) {
++              dlok = false;
++      } else {
++              memcpy((u8 *) skb_put(skb, totalpacketlen),
++                      &reserved_page_packet, totalpacketlen);
++              rtstatus = _rtl92d_cmd_send_packet(hw, skb);
+-      if (rtstatus)
+-              dlok = true;
++              if (rtstatus)
++                      dlok = true;
++      }
+       if (dlok) {
+               RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+                       ("Set RSVD page location to Fw.\n"));
+--- a/drivers/net/wireless/rtlwifi/usb.c
++++ b/drivers/net/wireless/rtlwifi/usb.c
+@@ -520,12 +520,14 @@ static void _rtl_usb_rx_process_noagg(st
+                       u8 *pdata;
+                       uskb = dev_alloc_skb(skb->len + 128);
+-                      memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
+-                             sizeof(rx_status));
+-                      pdata = (u8 *)skb_put(uskb, skb->len);
+-                      memcpy(pdata, skb->data, skb->len);
++                      if (uskb) {     /* drop packet on allocation failure */
++                              memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status,
++                                     sizeof(rx_status));
++                              pdata = (u8 *)skb_put(uskb, skb->len);
++                              memcpy(pdata, skb->data, skb->len);
++                              ieee80211_rx_irqsafe(hw, uskb);
++                      }
+                       dev_kfree_skb_any(skb);
+-                      ieee80211_rx_irqsafe(hw, uskb);
+               } else {
+                       dev_kfree_skb_any(skb);
+               }
diff --git a/queue-3.3/rtlwifi-rtl8192ce-fix-loss-of-receive-performance.patch b/queue-3.3/rtlwifi-rtl8192ce-fix-loss-of-receive-performance.patch
new file mode 100644 (file)
index 0000000..5507cf7
--- /dev/null
@@ -0,0 +1,40 @@
+From a9b89e2567c743483e6354f64d7a7e3a8c101e9e Mon Sep 17 00:00:00 2001
+From: Jingjun Wu <jingjun_wu@realsil.com.cn>
+Date: Fri, 2 Mar 2012 20:52:14 -0600
+Subject: rtlwifi: rtl8192ce: Fix loss of receive performance
+
+From: Jingjun Wu <jingjun_wu@realsil.com.cn>
+
+commit a9b89e2567c743483e6354f64d7a7e3a8c101e9e upstream.
+
+Driver rtl8192ce when used with the RTL8188CE device would start at about
+20 Mbps on a 54 Mbps connection, but quickly drop to 1 Mbps. One of the
+symptoms is that the AP would need to retransmit each packet 4 of 5 times
+before the driver would acknowledge it. Recovery is possible only by
+unloading and reloading the driver. This problem was reported at
+https://bugzilla.redhat.com/show_bug.cgi?id=770207.
+
+The problem is due to a missing update of the gain setting.
+
+Signed-off-by: Jingjun Wu <jingjun_wu@realsil.com.cn>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+@@ -524,6 +524,10 @@ void rtl92c_dm_write_dig(struct ieee8021
+                 dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
+                 dm_digtable.backoff_val));
++      dm_digtable.cur_igvalue += 2;
++      if (dm_digtable.cur_igvalue > 0x3f)
++              dm_digtable.cur_igvalue = 0x3f;
++
+       if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
+               rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
+                             dm_digtable.cur_igvalue);
diff --git a/queue-3.3/rtnetlink-fix-vf-ifla-policy.patch b/queue-3.3/rtnetlink-fix-vf-ifla-policy.patch
new file mode 100644 (file)
index 0000000..eaced50
--- /dev/null
@@ -0,0 +1,36 @@
+From 48752f6513012a1b078da08b145d5c40a644f058 Mon Sep 17 00:00:00 2001
+From: Greg Rose <gregory.v.rose@intel.com>
+Date: Wed, 8 Feb 2012 00:45:00 +0000
+Subject: rtnetlink: Fix VF IFLA policy
+
+From: Greg Rose <gregory.v.rose@intel.com>
+
+commit 48752f6513012a1b078da08b145d5c40a644f058 upstream.
+
+Add VF spoof check to IFLA policy.  The original patch I submitted to
+add the spoof checking feature to rtnl failed to add the proper policy
+rule that identifies the data type and len.  This patch corrects that
+oversight.  No bugs have been reported against this but it may cause
+some problem for the netlink message parsing that uses the policy
+table.
+
+Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
+Tested-by: Sibai Li <sibai.li@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/rtnetlink.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1133,6 +1133,8 @@ static const struct nla_policy ifla_vf_p
+                                   .len = sizeof(struct ifla_vf_vlan) },
+       [IFLA_VF_TX_RATE]       = { .type = NLA_BINARY,
+                                   .len = sizeof(struct ifla_vf_tx_rate) },
++      [IFLA_VF_SPOOFCHK]      = { .type = NLA_BINARY,
++                                  .len = sizeof(struct ifla_vf_spoofchk) },
+ };
+ static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
diff --git a/queue-3.3/serial-pl011-clear-pending-interrupts.patch b/queue-3.3/serial-pl011-clear-pending-interrupts.patch
new file mode 100644 (file)
index 0000000..477d7fb
--- /dev/null
@@ -0,0 +1,80 @@
+From 9b96fbacda34079dea0638ee1e92c56286f6114a Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Tue, 13 Mar 2012 13:27:23 +0100
+Subject: serial: PL011: clear pending interrupts
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+commit 9b96fbacda34079dea0638ee1e92c56286f6114a upstream.
+
+Chanho Min reported that when the boot loader transfers
+control to the kernel, there may be pending interrupts
+causing the UART to lock up in an eternal loop trying to
+pick tokens from the FIFO (since the RX interrupt flag
+indicates there are tokens) while in practice there are
+no tokens - in fact there is only a pending IRQ flag.
+
+This patch address the issue with a combination of two
+patches suggested by Russell King that clears and mask
+all interrupts at probe() and clears any pending error
+and RX interrupts at port startup time.
+
+We suspect the spurious interrupts are a side-effect of
+switching the UART from FIFO to non-FIFO mode.
+
+Cc: Shreshtha Kumar Sahu <shreshthakumar.sahu@stericsson.com>
+Reported-by: Chanho Min <chanho0207@gmail.com>
+Suggested-by: Russell King <linux@arm.linux.org.uk>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Reviewed-by: Jong-Sung Kim <neidhard.kim@lge.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/amba-pl011.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1381,6 +1381,10 @@ static int pl011_startup(struct uart_por
+       uap->port.uartclk = clk_get_rate(uap->clk);
++      /* Clear pending error and receive interrupts */
++      writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS |
++             UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR);
++
+       /*
+        * Allocate the IRQ
+        */
+@@ -1417,10 +1421,6 @@ static int pl011_startup(struct uart_por
+       cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
+       writew(cr, uap->port.membase + UART011_CR);
+-      /* Clear pending error interrupts */
+-      writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS,
+-             uap->port.membase + UART011_ICR);
+-
+       /*
+        * initialise the old status of the modem signals
+        */
+@@ -1435,6 +1435,9 @@ static int pl011_startup(struct uart_por
+        * as well.
+        */
+       spin_lock_irq(&uap->port.lock);
++      /* Clear out any spuriously appearing RX interrupts */
++       writew(UART011_RTIS | UART011_RXIS,
++              uap->port.membase + UART011_ICR);
+       uap->im = UART011_RTIM;
+       if (!pl011_dma_rx_running(uap))
+               uap->im |= UART011_RXIM;
+@@ -1927,6 +1930,10 @@ static int pl011_probe(struct amba_devic
+               goto unmap;
+       }
++      /* Ensure interrupts from this UART are masked and cleared */
++      writew(0, uap->port.membase + UART011_IMSC);
++      writew(0xffff, uap->port.membase + UART011_ICR);
++
+       uap->vendor = vendor;
+       uap->lcrh_rx = vendor->lcrh_rx;
+       uap->lcrh_tx = vendor->lcrh_tx;
index af2ed42cd0dfcd2fef6b6fac9465a145990f1b33..e7a7571f94c5f035230b83df9b57bf6bbd7d2121 100644 (file)
@@ -35,3 +35,28 @@ cdc-wdm-don-t-clear-wdm_read-unless-entire-read-buffer-is-emptied.patch
 usb-fsl_udc_core-fix-scheduling-while-atomic-dump-message.patch
 usb-fix-build-error-due-to-dma_mask-is-not-at-pdev_archdata-at-arm.patch
 usb-ums_realtek-do-not-use-stack-memory-for-dma-in-__do_config_autodelink.patch
+usb-qcserial-don-t-grab-qmi-port-on-gobi-1000-devices.patch
+usb-serial-add-support-for-the-sealevel-sealink-8-2038-rohs-device.patch
+usb-cp210x-update-to-support-cp2105-and-multiple-interface-devices.patch
+usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch
+rt2x00-add-support-for-d-link-dwa-127-to-rt2800usb.patch
+rtlwifi-rtl8192c_common-rtl8192de-check-for-allocation-failures.patch
+rtlwifi-handle-previous-allocation-failures-when-freeing-device-memory.patch
+rtlwifi-rtl8192c-prevent-sleeping-from-invalid-context-in-rtl8192cu.patch
+rtlwifi-rtl8192ce-fix-loss-of-receive-performance.patch
+serial-pl011-clear-pending-interrupts.patch
+iwlwifi-always-monitor-for-stuck-queues.patch
+ath9k-fix-going-to-full-sleep-on-ps-idle.patch
+math-introduce-div64_long.patch
+ntp-fix-integer-overflow-when-setting-time.patch
+uevent-send-events-in-correct-order-according-to-seqnum-v3.patch
+genirq-fix-long-term-regression-in-genirq-irq_set_irq_type-handling.patch
+genirq-fix-incorrect-check-for-forced-irq-thread-handler.patch
+rtc-disable-the-alarm-in-the-hardware-v2.patch
+p54spi-release-gpio-lines-and-irq-on-error-in-p54spi_probe.patch
+rtnetlink-fix-vf-ifla-policy.patch
+ib-iser-post-initial-receive-buffers-before-sending-the-final-login-request.patch
+mlx4_core-fix-one-more-static-exported-function.patch
+ima-fix-kconfig-dependencies.patch
+x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch
+mm-thp-fix-pmd_bad-triggering-in-code-paths-holding-mmap_sem-read-mode.patch
diff --git a/queue-3.3/uevent-send-events-in-correct-order-according-to-seqnum-v3.patch b/queue-3.3/uevent-send-events-in-correct-order-according-to-seqnum-v3.patch
new file mode 100644 (file)
index 0000000..92375ef
--- /dev/null
@@ -0,0 +1,94 @@
+From 7b60a18da393ed70db043a777fd9e6d5363077c4 Mon Sep 17 00:00:00 2001
+From: Andrew Vagin <avagin@openvz.org>
+Date: Wed, 7 Mar 2012 14:49:56 +0400
+Subject: uevent: send events in correct order according to seqnum (v3)
+
+From: Andrew Vagin <avagin@openvz.org>
+
+commit 7b60a18da393ed70db043a777fd9e6d5363077c4 upstream.
+
+The queue handling in the udev daemon assumes that the events are
+ordered.
+
+Before this patch uevent_seqnum is incremented under sequence_lock,
+than an event is send uner uevent_sock_mutex. I want to say that code
+contained a window between incrementing seqnum and sending an event.
+
+This patch locks uevent_sock_mutex before incrementing uevent_seqnum.
+
+v2: delete sequence_lock, uevent_seqnum is protected by uevent_sock_mutex
+v3: unlock the mutex before the goto exit
+
+Thanks for Kay for the comments.
+
+Signed-off-by: Andrew Vagin <avagin@openvz.org>
+Tested-By: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/kobject_uevent.c |   19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+--- a/lib/kobject_uevent.c
++++ b/lib/kobject_uevent.c
+@@ -29,16 +29,17 @@
+ u64 uevent_seqnum;
+ char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
+-static DEFINE_SPINLOCK(sequence_lock);
+ #ifdef CONFIG_NET
+ struct uevent_sock {
+       struct list_head list;
+       struct sock *sk;
+ };
+ static LIST_HEAD(uevent_sock_list);
+-static DEFINE_MUTEX(uevent_sock_mutex);
+ #endif
++/* This lock protects uevent_seqnum and uevent_sock_list */
++static DEFINE_MUTEX(uevent_sock_mutex);
++
+ /* the strings here must match the enum in include/linux/kobject.h */
+ static const char *kobject_actions[] = {
+       [KOBJ_ADD] =            "add",
+@@ -136,7 +137,6 @@ int kobject_uevent_env(struct kobject *k
+       struct kobject *top_kobj;
+       struct kset *kset;
+       const struct kset_uevent_ops *uevent_ops;
+-      u64 seq;
+       int i = 0;
+       int retval = 0;
+ #ifdef CONFIG_NET
+@@ -243,17 +243,16 @@ int kobject_uevent_env(struct kobject *k
+       else if (action == KOBJ_REMOVE)
+               kobj->state_remove_uevent_sent = 1;
++      mutex_lock(&uevent_sock_mutex);
+       /* we will send an event, so request a new sequence number */
+-      spin_lock(&sequence_lock);
+-      seq = ++uevent_seqnum;
+-      spin_unlock(&sequence_lock);
+-      retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
+-      if (retval)
++      retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)++uevent_seqnum);
++      if (retval) {
++              mutex_unlock(&uevent_sock_mutex);
+               goto exit;
++      }
+ #if defined(CONFIG_NET)
+       /* send netlink message */
+-      mutex_lock(&uevent_sock_mutex);
+       list_for_each_entry(ue_sk, &uevent_sock_list, list) {
+               struct sock *uevent_sock = ue_sk->sk;
+               struct sk_buff *skb;
+@@ -290,8 +289,8 @@ int kobject_uevent_env(struct kobject *k
+               } else
+                       retval = -ENOMEM;
+       }
+-      mutex_unlock(&uevent_sock_mutex);
+ #endif
++      mutex_unlock(&uevent_sock_mutex);
+       /* call uevent_helper, usually only enabled during early boot */
+       if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
diff --git a/queue-3.3/usb-cp210x-update-to-support-cp2105-and-multiple-interface-devices.patch b/queue-3.3/usb-cp210x-update-to-support-cp2105-and-multiple-interface-devices.patch
new file mode 100644 (file)
index 0000000..a804c60
--- /dev/null
@@ -0,0 +1,152 @@
+From a5360a53a7ccad5ed9ccef210b94fef13c6e5529 Mon Sep 17 00:00:00 2001
+From: Preston Fick <preston.fick@silabs.com>
+Date: Fri, 24 Feb 2012 13:42:39 -0600
+Subject: usb: cp210x: Update to support CP2105 and multiple interface devices
+
+From: Preston Fick <preston.fick@silabs.com>
+
+commit a5360a53a7ccad5ed9ccef210b94fef13c6e5529 upstream.
+
+This patch updates the cp210x driver to support CP210x multiple
+interface devices devices from Silicon Labs. The existing driver
+always sends control requests to interface 0, which is hardcoded in
+the usb_control_msg function calls. This only allows for single
+interface devices to be used, and causes a bug when using ports on an
+interface other than 0 in the multiple interface devices.
+
+Here are the changes included in this patch:
+- Updated the device list to contain the Silicon Labs factory default
+  VID/PID for multiple interface CP210x devices
+- Created a cp210x_port_private struct created for each port on
+  startup, this struct holds the interface number
+- Added a cp210x_release function to clean up the cp210x_port_private
+  memory created on startup
+- Modified usb_get_config and usb_set_config to get a pointer to the
+  cp210x_port_private struct, and use the interface number there in the
+  usb_control_message wIndex param
+
+Signed-off-by: Preston Fick <preston.fick@silabs.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/cp210x.c |   44 +++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 41 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -49,6 +49,7 @@ static int cp210x_tiocmset_port(struct u
+               unsigned int, unsigned int);
+ static void cp210x_break_ctl(struct tty_struct *, int);
+ static int cp210x_startup(struct usb_serial *);
++static void cp210x_release(struct usb_serial *);
+ static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
+ static bool debug;
+@@ -121,6 +122,8 @@ static const struct usb_device_id id_tab
+       { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
+       { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
++      { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
++      { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
+       { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
+       { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
+@@ -149,6 +152,10 @@ static const struct usb_device_id id_tab
+ MODULE_DEVICE_TABLE(usb, id_table);
++struct cp210x_port_private {
++      __u8                    bInterfaceNumber;
++};
++
+ static struct usb_driver cp210x_driver = {
+       .name           = "cp210x",
+       .probe          = usb_serial_probe,
+@@ -174,6 +181,7 @@ static struct usb_serial_driver cp210x_d
+       .tiocmget               = cp210x_tiocmget,
+       .tiocmset               = cp210x_tiocmset,
+       .attach                 = cp210x_startup,
++      .release                = cp210x_release,
+       .dtr_rts                = cp210x_dtr_rts
+ };
+@@ -261,6 +269,7 @@ static int cp210x_get_config(struct usb_
+               unsigned int *data, int size)
+ {
+       struct usb_serial *serial = port->serial;
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+       __le32 *buf;
+       int result, i, length;
+@@ -276,7 +285,7 @@ static int cp210x_get_config(struct usb_
+       /* Issue the request, attempting to read 'size' bytes */
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                               request, REQTYPE_DEVICE_TO_HOST, 0x0000,
+-                              0, buf, size, 300);
++                              port_priv->bInterfaceNumber, buf, size, 300);
+       /* Convert data into an array of integers */
+       for (i = 0; i < length; i++)
+@@ -307,6 +316,7 @@ static int cp210x_set_config(struct usb_
+               unsigned int *data, int size)
+ {
+       struct usb_serial *serial = port->serial;
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+       __le32 *buf;
+       int result, i, length;
+@@ -328,12 +338,12 @@ static int cp210x_set_config(struct usb_
+               result = usb_control_msg(serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_DEVICE, 0x0000,
+-                              0, buf, size, 300);
++                              port_priv->bInterfaceNumber, buf, size, 300);
+       } else {
+               result = usb_control_msg(serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_DEVICE, data[0],
+-                              0, NULL, 0, 300);
++                              port_priv->bInterfaceNumber, NULL, 0, 300);
+       }
+       kfree(buf);
+@@ -844,11 +854,39 @@ static void cp210x_break_ctl (struct tty
+ static int cp210x_startup(struct usb_serial *serial)
+ {
++      struct cp210x_port_private *port_priv;
++      int i;
++
+       /* cp210x buffers behave strangely unless device is reset */
+       usb_reset_device(serial->dev);
++
++      for (i = 0; i < serial->num_ports; i++) {
++              port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
++              if (!port_priv)
++                      return -ENOMEM;
++
++              memset(port_priv, 0x00, sizeof(*port_priv));
++              port_priv->bInterfaceNumber =
++                  serial->interface->cur_altsetting->desc.bInterfaceNumber;
++
++              usb_set_serial_port_data(serial->port[i], port_priv);
++      }
++
+       return 0;
+ }
++static void cp210x_release(struct usb_serial *serial)
++{
++      struct cp210x_port_private *port_priv;
++      int i;
++
++      for (i = 0; i < serial->num_ports; i++) {
++              port_priv = usb_get_serial_port_data(serial->port[i]);
++              kfree(port_priv);
++              usb_set_serial_port_data(serial->port[i], NULL);
++      }
++}
++
+ static int __init cp210x_init(void)
+ {
+       int retval;
diff --git a/queue-3.3/usb-qcserial-don-t-grab-qmi-port-on-gobi-1000-devices.patch b/queue-3.3/usb-qcserial-don-t-grab-qmi-port-on-gobi-1000-devices.patch
new file mode 100644 (file)
index 0000000..3e03745
--- /dev/null
@@ -0,0 +1,174 @@
+From c192c8e71a2ded01170c1a992cd21aaedc822756 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dcbw@redhat.com>
+Date: Fri, 24 Feb 2012 13:08:43 -0600
+Subject: USB: qcserial: don't grab QMI port on Gobi 1000 devices
+
+From: Dan Williams <dcbw@redhat.com>
+
+commit c192c8e71a2ded01170c1a992cd21aaedc822756 upstream.
+
+Gobi 1000 devices have a different port layout, which wasn't respected
+by the current driver, and thus it grabbed the QMI/net port.  In the
+near future we'll be attaching another driver to the QMI/net port for
+these devices (cdc-wdm and qmi_wwan) so make sure the qcserial driver
+doesn't claim them.  This patch also prevents qcserial from binding to
+interfaces 0 and 1 on 1K devices because those interfaces do not
+respond.
+
+Signed-off-by: Dan Williams <dcbw@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/qcserial.c |  105 ++++++++++++++++++++++++------------------
+ 1 file changed, 62 insertions(+), 43 deletions(-)
+
+--- a/drivers/usb/serial/qcserial.c
++++ b/drivers/usb/serial/qcserial.c
+@@ -24,39 +24,44 @@
+ static bool debug;
++#define DEVICE_G1K(v, p) \
++      USB_DEVICE(v, p), .driver_info = 1
++
+ static const struct usb_device_id id_table[] = {
+-      {USB_DEVICE(0x05c6, 0x9211)},   /* Acer Gobi QDL device */
+-      {USB_DEVICE(0x05c6, 0x9212)},   /* Acer Gobi Modem Device */
+-      {USB_DEVICE(0x03f0, 0x1f1d)},   /* HP un2400 Gobi Modem Device */
+-      {USB_DEVICE(0x03f0, 0x201d)},   /* HP un2400 Gobi QDL Device */
+-      {USB_DEVICE(0x03f0, 0x371d)},   /* HP un2430 Mobile Broadband Module */
+-      {USB_DEVICE(0x04da, 0x250d)},   /* Panasonic Gobi Modem device */
+-      {USB_DEVICE(0x04da, 0x250c)},   /* Panasonic Gobi QDL device */
+-      {USB_DEVICE(0x413c, 0x8172)},   /* Dell Gobi Modem device */
+-      {USB_DEVICE(0x413c, 0x8171)},   /* Dell Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa001)},   /* Novatel Gobi Modem device */
+-      {USB_DEVICE(0x1410, 0xa008)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa010)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa011)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa012)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa013)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x1410, 0xa014)},   /* Novatel Gobi QDL device */
+-      {USB_DEVICE(0x0b05, 0x1776)},   /* Asus Gobi Modem device */
+-      {USB_DEVICE(0x0b05, 0x1774)},   /* Asus Gobi QDL device */
+-      {USB_DEVICE(0x19d2, 0xfff3)},   /* ONDA Gobi Modem device */
+-      {USB_DEVICE(0x19d2, 0xfff2)},   /* ONDA Gobi QDL device */
+-      {USB_DEVICE(0x1557, 0x0a80)},   /* OQO Gobi QDL device */
+-      {USB_DEVICE(0x05c6, 0x9001)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9002)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9202)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9203)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9222)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9008)},   /* Generic Gobi QDL device */
+-      {USB_DEVICE(0x05c6, 0x9009)},   /* Generic Gobi Modem device */
+-      {USB_DEVICE(0x05c6, 0x9201)},   /* Generic Gobi QDL device */
+-      {USB_DEVICE(0x05c6, 0x9221)},   /* Generic Gobi QDL device */
+-      {USB_DEVICE(0x05c6, 0x9231)},   /* Generic Gobi QDL device */
+-      {USB_DEVICE(0x1f45, 0x0001)},   /* Unknown Gobi QDL device */
++      /* Gobi 1000 devices */
++      {DEVICE_G1K(0x05c6, 0x9211)},   /* Acer Gobi QDL device */
++      {DEVICE_G1K(0x05c6, 0x9212)},   /* Acer Gobi Modem Device */
++      {DEVICE_G1K(0x03f0, 0x1f1d)},   /* HP un2400 Gobi Modem Device */
++      {DEVICE_G1K(0x03f0, 0x201d)},   /* HP un2400 Gobi QDL Device */
++      {DEVICE_G1K(0x04da, 0x250d)},   /* Panasonic Gobi Modem device */
++      {DEVICE_G1K(0x04da, 0x250c)},   /* Panasonic Gobi QDL device */
++      {DEVICE_G1K(0x413c, 0x8172)},   /* Dell Gobi Modem device */
++      {DEVICE_G1K(0x413c, 0x8171)},   /* Dell Gobi QDL device */
++      {DEVICE_G1K(0x1410, 0xa001)},   /* Novatel Gobi Modem device */
++      {DEVICE_G1K(0x1410, 0xa008)},   /* Novatel Gobi QDL device */
++      {DEVICE_G1K(0x0b05, 0x1776)},   /* Asus Gobi Modem device */
++      {DEVICE_G1K(0x0b05, 0x1774)},   /* Asus Gobi QDL device */
++      {DEVICE_G1K(0x19d2, 0xfff3)},   /* ONDA Gobi Modem device */
++      {DEVICE_G1K(0x19d2, 0xfff2)},   /* ONDA Gobi QDL device */
++      {DEVICE_G1K(0x1557, 0x0a80)},   /* OQO Gobi QDL device */
++      {DEVICE_G1K(0x05c6, 0x9001)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9002)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9202)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9203)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9222)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9008)},   /* Generic Gobi QDL device */
++      {DEVICE_G1K(0x05c6, 0x9009)},   /* Generic Gobi Modem device */
++      {DEVICE_G1K(0x05c6, 0x9201)},   /* Generic Gobi QDL device */
++      {DEVICE_G1K(0x05c6, 0x9221)},   /* Generic Gobi QDL device */
++      {DEVICE_G1K(0x05c6, 0x9231)},   /* Generic Gobi QDL device */
++      {DEVICE_G1K(0x1f45, 0x0001)},   /* Unknown Gobi QDL device */
++
++      /* Gobi 2000 devices */
++      {USB_DEVICE(0x1410, 0xa010)},   /* Novatel Gobi 2000 QDL device */
++      {USB_DEVICE(0x1410, 0xa011)},   /* Novatel Gobi 2000 QDL device */
++      {USB_DEVICE(0x1410, 0xa012)},   /* Novatel Gobi 2000 QDL device */
++      {USB_DEVICE(0x1410, 0xa013)},   /* Novatel Gobi 2000 QDL device */
++      {USB_DEVICE(0x1410, 0xa014)},   /* Novatel Gobi 2000 QDL device */
+       {USB_DEVICE(0x413c, 0x8185)},   /* Dell Gobi 2000 QDL device (N0218, VU936) */
+       {USB_DEVICE(0x413c, 0x8186)},   /* Dell Gobi 2000 Modem device (N0218, VU936) */
+       {USB_DEVICE(0x05c6, 0x9208)},   /* Generic Gobi 2000 QDL device */
+@@ -92,6 +97,8 @@ static const struct usb_device_id id_tab
+       {USB_DEVICE(0x05c6, 0x9204)},   /* Gobi 2000 QDL device */
+       {USB_DEVICE(0x05c6, 0x9205)},   /* Gobi 2000 Modem device */
++      /* Gobi 3000 devices */
++      {USB_DEVICE(0x03f0, 0x371d)},   /* HP un2430 Gobi 3000 QDL */
+       {USB_DEVICE(0x05c6, 0x920c)},   /* Gobi 3000 QDL */
+       {USB_DEVICE(0x05c6, 0x920d)},   /* Gobi 3000 Composite */
+       {USB_DEVICE(0x1410, 0xa020)},   /* Novatel Gobi 3000 QDL */
+@@ -122,8 +129,10 @@ static int qcprobe(struct usb_serial *se
+       int retval = -ENODEV;
+       __u8 nintf;
+       __u8 ifnum;
++      bool is_gobi1k = id->driver_info ? true : false;
+       dbg("%s", __func__);
++      dbg("Is Gobi 1000 = %d", is_gobi1k);
+       nintf = serial->dev->actconfig->desc.bNumInterfaces;
+       dbg("Num Interfaces = %d", nintf);
+@@ -169,15 +178,25 @@ static int qcprobe(struct usb_serial *se
+       case 3:
+       case 4:
+-              /* Composite mode */
+-              /* ifnum == 0 is a broadband network adapter */
+-              if (ifnum == 1) {
+-                      /*
+-                       * Diagnostics Monitor (serial line 9600 8N1)
+-                       * Qualcomm DM protocol
+-                       * use "libqcdm" (ModemManager) for communication
+-                       */
+-                      dbg("Diagnostics Monitor found");
++              /* Composite mode; don't bind to the QMI/net interface as that
++               * gets handled by other drivers.
++               */
++
++              /* Gobi 1K USB layout:
++               * 0: serial port (doesn't respond)
++               * 1: serial port (doesn't respond)
++               * 2: AT-capable modem port
++               * 3: QMI/net
++               *
++               * Gobi 2K+ USB layout:
++               * 0: QMI/net
++               * 1: DM/DIAG (use libqcdm from ModemManager for communication)
++               * 2: AT-capable modem port
++               * 3: NMEA
++               */
++
++              if (ifnum == 1 && !is_gobi1k) {
++                      dbg("Gobi 2K+ DM/DIAG interface found");
+                       retval = usb_set_interface(serial->dev, ifnum, 0);
+                       if (retval < 0) {
+                               dev_err(&serial->dev->dev,
+@@ -196,13 +215,13 @@ static int qcprobe(struct usb_serial *se
+                               retval = -ENODEV;
+                               kfree(data);
+                       }
+-              } else if (ifnum==3) {
++              } else if (ifnum==3 && !is_gobi1k) {
+                       /*
+                        * NMEA (serial line 9600 8N1)
+                        * # echo "\$GPS_START" > /dev/ttyUSBx
+                        * # echo "\$GPS_STOP"  > /dev/ttyUSBx
+                        */
+-                      dbg("NMEA GPS interface found");
++                      dbg("Gobi 2K+ NMEA GPS interface found");
+                       retval = usb_set_interface(serial->dev, ifnum, 0);
+                       if (retval < 0) {
+                               dev_err(&serial->dev->dev,
diff --git a/queue-3.3/usb-serial-add-support-for-the-sealevel-sealink-8-2038-rohs-device.patch b/queue-3.3/usb-serial-add-support-for-the-sealevel-sealink-8-2038-rohs-device.patch
new file mode 100644 (file)
index 0000000..f2a0926
--- /dev/null
@@ -0,0 +1,46 @@
+From 6d161b99f875269ad4ffa44375e1e54bca6fd02e Mon Sep 17 00:00:00 2001
+From: Scott Dial <scott.dial@scientiallc.com>
+Date: Fri, 24 Feb 2012 19:04:09 -0500
+Subject: usb-serial: Add support for the Sealevel SeaLINK+8 2038-ROHS device
+
+From: Scott Dial <scott.dial@scientiallc.com>
+
+commit 6d161b99f875269ad4ffa44375e1e54bca6fd02e upstream.
+
+This patch adds new device IDs to the ftdi_sio module to support
+the new Sealevel SeaLINK+8 2038-ROHS device.
+
+Signed-off-by: Scott Dial <scott.dial@scientiallc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c     |    4 ++++
+ drivers/usb/serial/ftdi_sio_ids.h |    4 ++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -537,6 +537,10 @@ static struct usb_device_id id_table_com
+       { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_6_PID) },
+       { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
+       { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
++      { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_1_PID) },
++      { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_2_PID) },
++      { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_3_PID) },
++      { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803R_4_PID) },
+       { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
+       { USB_DEVICE(OCT_VID, OCT_US101_PID) },
+       { USB_DEVICE(OCT_VID, OCT_DK201_PID) },
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -689,6 +689,10 @@
+ #define SEALEVEL_2803_6_PID   0X2863  /* SeaLINK+8 (2803) Port 6 */
+ #define SEALEVEL_2803_7_PID   0X2873  /* SeaLINK+8 (2803) Port 7 */
+ #define SEALEVEL_2803_8_PID   0X2883  /* SeaLINK+8 (2803) Port 8 */
++#define SEALEVEL_2803R_1_PID  0Xa02a  /* SeaLINK+8 (2803-ROHS) Port 1+2 */
++#define SEALEVEL_2803R_2_PID  0Xa02b  /* SeaLINK+8 (2803-ROHS) Port 3+4 */
++#define SEALEVEL_2803R_3_PID  0Xa02c  /* SeaLINK+8 (2803-ROHS) Port 5+6 */
++#define SEALEVEL_2803R_4_PID  0Xa02d  /* SeaLINK+8 (2803-ROHS) Port 7+8 */
+ /*
+  * JETI SPECTROMETER SPECBOS 1201
diff --git a/queue-3.3/usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch b/queue-3.3/usb-serial-mos7840-fixed-mcs7820-device-attach-problem.patch
new file mode 100644 (file)
index 0000000..d482449
--- /dev/null
@@ -0,0 +1,144 @@
+From 093ea2d3a766cb8a4c4de57efec6c0a127a58792 Mon Sep 17 00:00:00 2001
+From: Donald Lee <donald@asix.com.tw>
+Date: Wed, 14 Mar 2012 15:26:33 +0800
+Subject: USB: serial: mos7840: Fixed MCS7820 device attach problem
+
+From: Donald Lee <donald@asix.com.tw>
+
+commit 093ea2d3a766cb8a4c4de57efec6c0a127a58792 upstream.
+
+A MCS7820 device supports two serial ports and a MCS7840 device supports
+four serial ports. Both devices use the same driver, but the attach function
+in driver was unable to correctly handle the port numbers for MCS7820
+device. This problem has been fixed in this patch and this fix has been
+verified on x86 Linux kernel 3.2.9 with both MCS7820 and MCS7840 devices.
+
+Signed-off-by: Donald Lee <donald@asix.com.tw>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c |   81 +++++++++++++++++++++++++++++--------------
+ 1 file changed, 56 insertions(+), 25 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -174,6 +174,7 @@
+ #define CLK_MULTI_REGISTER         ((__u16)(0x02))
+ #define CLK_START_VALUE_REGISTER   ((__u16)(0x03))
++#define GPIO_REGISTER              ((__u16)(0x07))
+ #define SERIAL_LCR_DLAB            ((__u16)(0x0080))
+@@ -1101,14 +1102,25 @@ static int mos7840_open(struct tty_struc
+       mos7840_port->read_urb = port->read_urb;
+       /* set up our bulk in urb */
+-
+-      usb_fill_bulk_urb(mos7840_port->read_urb,
+-                        serial->dev,
+-                        usb_rcvbulkpipe(serial->dev,
+-                                        port->bulk_in_endpointAddress),
+-                        port->bulk_in_buffer,
+-                        mos7840_port->read_urb->transfer_buffer_length,
+-                        mos7840_bulk_in_callback, mos7840_port);
++      if ((serial->num_ports == 2)
++              && ((((__u16)port->number -
++                      (__u16)(port->serial->minor)) % 2) != 0)) {
++              usb_fill_bulk_urb(mos7840_port->read_urb,
++                      serial->dev,
++                      usb_rcvbulkpipe(serial->dev,
++                              (port->bulk_in_endpointAddress) + 2),
++                      port->bulk_in_buffer,
++                      mos7840_port->read_urb->transfer_buffer_length,
++                      mos7840_bulk_in_callback, mos7840_port);
++      } else {
++              usb_fill_bulk_urb(mos7840_port->read_urb,
++                      serial->dev,
++                      usb_rcvbulkpipe(serial->dev,
++                              port->bulk_in_endpointAddress),
++                      port->bulk_in_buffer,
++                      mos7840_port->read_urb->transfer_buffer_length,
++                      mos7840_bulk_in_callback, mos7840_port);
++      }
+       dbg("mos7840_open: bulkin endpoint is %d",
+           port->bulk_in_endpointAddress);
+@@ -1519,13 +1531,25 @@ static int mos7840_write(struct tty_stru
+       memcpy(urb->transfer_buffer, current_position, transfer_size);
+       /* fill urb with data and submit  */
+-      usb_fill_bulk_urb(urb,
+-                        serial->dev,
+-                        usb_sndbulkpipe(serial->dev,
+-                                        port->bulk_out_endpointAddress),
+-                        urb->transfer_buffer,
+-                        transfer_size,
+-                        mos7840_bulk_out_data_callback, mos7840_port);
++      if ((serial->num_ports == 2)
++              && ((((__u16)port->number -
++                      (__u16)(port->serial->minor)) % 2) != 0)) {
++              usb_fill_bulk_urb(urb,
++                      serial->dev,
++                      usb_sndbulkpipe(serial->dev,
++                              (port->bulk_out_endpointAddress) + 2),
++                      urb->transfer_buffer,
++                      transfer_size,
++                      mos7840_bulk_out_data_callback, mos7840_port);
++      } else {
++              usb_fill_bulk_urb(urb,
++                      serial->dev,
++                      usb_sndbulkpipe(serial->dev,
++                              port->bulk_out_endpointAddress),
++                      urb->transfer_buffer,
++                      transfer_size,
++                      mos7840_bulk_out_data_callback, mos7840_port);
++      }
+       data1 = urb->transfer_buffer;
+       dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
+@@ -1838,7 +1862,7 @@ static int mos7840_send_cmd_write_baud_r
+       } else {
+ #ifdef HW_flow_control
+-              / *setting h/w flow control bit to 0 */
++              /* setting h/w flow control bit to 0 */
+               Data = 0xb;
+               mos7840_port->shadowMCR = Data;
+               status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
+@@ -2305,19 +2329,26 @@ static int mos7840_ioctl(struct tty_stru
+ static int mos7840_calc_num_ports(struct usb_serial *serial)
+ {
+-      int mos7840_num_ports = 0;
++      __u16 Data = 0x00;
++      int ret = 0;
++      int mos7840_num_ports;
+-      dbg("numberofendpoints: cur %d, alt %d",
+-          (int)serial->interface->cur_altsetting->desc.bNumEndpoints,
+-          (int)serial->interface->altsetting->desc.bNumEndpoints);
+-      if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) {
+-              mos7840_num_ports = serial->num_ports = 2;
+-      } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) {
++      ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
++              MCS_RDREQ, MCS_RD_RTYPE, 0, GPIO_REGISTER, &Data,
++              VENDOR_READ_LENGTH, MOS_WDR_TIMEOUT);
++
++      if ((Data & 0x01) == 0) {
++              mos7840_num_ports = 2;
++              serial->num_bulk_in = 2;
++              serial->num_bulk_out = 2;
++              serial->num_ports = 2;
++      } else {
++              mos7840_num_ports = 4;
+               serial->num_bulk_in = 4;
+               serial->num_bulk_out = 4;
+-              mos7840_num_ports = serial->num_ports = 4;
++              serial->num_ports = 4;
+       }
+-      dbg ("mos7840_num_ports = %d", mos7840_num_ports);
++
+       return mos7840_num_ports;
+ }
diff --git a/queue-3.3/x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch b/queue-3.3/x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch
new file mode 100644 (file)
index 0000000..51aaf68
--- /dev/null
@@ -0,0 +1,110 @@
+From 73d63d038ee9f769f5e5b46792d227fe20e442c5 Mon Sep 17 00:00:00 2001
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+Date: Mon, 12 Mar 2012 11:36:33 -0700
+Subject: x86/ioapic: Add register level checks to detect bogus io-apic entries
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Suresh Siddha <suresh.b.siddha@intel.com>
+
+commit 73d63d038ee9f769f5e5b46792d227fe20e442c5 upstream.
+
+With the recent changes to clear_IO_APIC_pin() which tries to
+clear remoteIRR bit explicitly, some of the users started to see
+"Unable to reset IRR for apic .." messages.
+
+Close look shows that these are related to bogus IO-APIC entries
+which return's all 1's for their io-apic registers. And the
+above mentioned error messages are benign. But kernel should
+have ignored such io-apic's in the first place.
+
+Check if register 0, 1, 2 of the listed io-apic are all 1's and
+ignore such io-apic.
+
+Reported-by: Álvaro Castillo <midgoon@gmail.com>
+Tested-by: Jon Dufresne <jon@jondufresne.org>
+Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
+Cc: yinghai@kernel.org
+Cc: kernel-team@fedoraproject.org
+Cc: Josh Boyer <jwboyer@redhat.com>
+Link: http://lkml.kernel.org/r/1331577393.31585.94.camel@sbsiddha-desk.sc.intel.com
+[ Performed minor cleanup of affected code. ]
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/apic/io_apic.c |   40 ++++++++++++++++++++++++++++++++--------
+ 1 file changed, 32 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -3967,18 +3967,36 @@ int mp_find_ioapic_pin(int ioapic, u32 g
+ static __init int bad_ioapic(unsigned long address)
+ {
+       if (nr_ioapics >= MAX_IO_APICS) {
+-              printk(KERN_WARNING "WARNING: Max # of I/O APICs (%d) exceeded "
+-                     "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
++              pr_warn("WARNING: Max # of I/O APICs (%d) exceeded (found %d), skipping\n",
++                      MAX_IO_APICS, nr_ioapics);
+               return 1;
+       }
+       if (!address) {
+-              printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
+-                     " found in table, skipping!\n");
++              pr_warn("WARNING: Bogus (zero) I/O APIC address found in table, skipping!\n");
+               return 1;
+       }
+       return 0;
+ }
++static __init int bad_ioapic_register(int idx)
++{
++      union IO_APIC_reg_00 reg_00;
++      union IO_APIC_reg_01 reg_01;
++      union IO_APIC_reg_02 reg_02;
++
++      reg_00.raw = io_apic_read(idx, 0);
++      reg_01.raw = io_apic_read(idx, 1);
++      reg_02.raw = io_apic_read(idx, 2);
++
++      if (reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1) {
++              pr_warn("I/O APIC 0x%x registers return all ones, skipping!\n",
++                      mpc_ioapic_addr(idx));
++              return 1;
++      }
++
++      return 0;
++}
++
+ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+ {
+       int idx = 0;
+@@ -3995,6 +4013,12 @@ void __init mp_register_ioapic(int id, u
+       ioapics[idx].mp_config.apicaddr = address;
+       set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
++
++      if (bad_ioapic_register(idx)) {
++              clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
++              return;
++      }
++
+       ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
+       ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
+@@ -4015,10 +4039,10 @@ void __init mp_register_ioapic(int id, u
+       if (gsi_cfg->gsi_end >= gsi_top)
+               gsi_top = gsi_cfg->gsi_end + 1;
+-      printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
+-             "GSI %d-%d\n", idx, mpc_ioapic_id(idx),
+-             mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
+-             gsi_cfg->gsi_base, gsi_cfg->gsi_end);
++      pr_info("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, GSI %d-%d\n",
++              idx, mpc_ioapic_id(idx),
++              mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
++              gsi_cfg->gsi_base, gsi_cfg->gsi_end);
+       nr_ioapics++;
+ }