[kernel/f18] Turn off Intel IOMMU by default
Justin M. Forbes
jforbes at fedoraproject.org
Tue Jan 15 22:18:56 UTC 2013
commit b7b0a09dedc45f35ba1041fd123757079da2c4a2
Author: Justin M. Forbes <jforbes at redhat.com>
Date: Tue Jan 15 16:13:12 2013 -0600
Turn off Intel IOMMU by default
...aptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch | 50 -
3.7.3-stable-queue.patch |15769 ++++++++++++++++++++
...ot-use-Lid-and-Sleep-button-for-S5-wakeup.patch | 46 -
...remove-vestigial-request-queue-allocation.patch | 69 -
config-x86-generic | 2 +-
kernel.spec | 33 +-
mac80211-fix-ibss-scanning.patch | 132 -
7 files changed, 15779 insertions(+), 322 deletions(-)
---
diff --git a/3.7.3-stable-queue.patch b/3.7.3-stable-queue.patch
new file mode 100644
index 0000000..e9b57d5
--- /dev/null
+++ b/3.7.3-stable-queue.patch
@@ -0,0 +1,15769 @@
+From 13ae633cf729b0ecb677b75b04886ff8fada8fad Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Tue, 20 Nov 2012 10:02:06 +0900
+Subject: regulator: wm831x: Set the new rather than old value for DVS VSEL
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit 13ae633cf729b0ecb677b75b04886ff8fada8fad upstream.
+
+Reported-by: Guennadi Liakhovetski <g.liakhovetski at gmx.de>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/regulator/wm831x-dcdc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/regulator/wm831x-dcdc.c
++++ b/drivers/regulator/wm831x-dcdc.c
+@@ -290,7 +290,7 @@ static int wm831x_buckv_set_voltage_sel(
+ if (vsel > dcdc->dvs_vsel) {
+ ret = wm831x_set_bits(wm831x, dvs_reg,
+ WM831X_DC1_DVS_VSEL_MASK,
+- dcdc->dvs_vsel);
++ vsel);
+ if (ret == 0)
+ dcdc->dvs_vsel = vsel;
+ else
+From 596ab5ec3bf10a22be30d7cb1d903a4b83fd607c Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd at openwrt.org>
+Date: Mon, 10 Dec 2012 16:40:41 +0100
+Subject: ath5k: fix tx path skb leaks
+
+From: Felix Fietkau <nbd at openwrt.org>
+
+commit 596ab5ec3bf10a22be30d7cb1d903a4b83fd607c upstream.
+
+ieee80211_free_txskb() needs to be used instead of dev_kfree_skb_any for
+tx packets passed to the driver from mac80211
+
+Signed-off-by: Felix Fietkau <nbd at openwrt.org>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath5k/base.c | 4 ++--
+ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath5k/base.c
++++ b/drivers/net/wireless/ath/ath5k/base.c
+@@ -848,7 +848,7 @@ ath5k_txbuf_free_skb(struct ath5k_hw *ah
+ return;
+ dma_unmap_single(ah->dev, bf->skbaddr, bf->skb->len,
+ DMA_TO_DEVICE);
+- dev_kfree_skb_any(bf->skb);
++ ieee80211_free_txskb(ah->hw, bf->skb);
+ bf->skb = NULL;
+ bf->skbaddr = 0;
+ bf->desc->ds_data = 0;
+@@ -1575,7 +1575,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw,
+ return;
+
+ drop_packet:
+- dev_kfree_skb_any(skb);
++ ieee80211_free_txskb(hw, skb);
+ }
+
+ static void
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -62,7 +62,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct
+ u16 qnum = skb_get_queue_mapping(skb);
+
+ if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) {
+- dev_kfree_skb_any(skb);
++ ieee80211_free_txskb(hw, skb);
+ return;
+ }
+
+From 25a172655f837bdb032e451f95441bb4acec51bb Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Wed, 28 Nov 2012 10:51:34 +0200
+Subject: iwlwifi: don't handle masked interrupt
+
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+
+commit 25a172655f837bdb032e451f95441bb4acec51bb upstream.
+
+This can lead to a panic if the driver isn't ready to
+handle them. Since our interrupt line is shared, we can get
+an interrupt at any time (and CONFIG_DEBUG_SHIRQ checks
+that even when the interrupt is being freed).
+
+If the op_mode has gone away, we musn't call it. To avoid
+this the transport disables the interrupts when the hw is
+stopped and the op_mode is leaving.
+If there is an event that would cause an interrupt the INTA
+register is updated regardless of the enablement of the
+interrupts: even if the interrupts are disabled, the INTA
+will be changed, but the device won't issue an interrupt.
+But the ISR can be called at any time, so we ought ignore
+the value in the INTA otherwise we can call the op_mode
+after it was freed.
+
+I found this bug when the op_mode_start failed, and called
+iwl_trans_stop_hw(trans, true). Then I played with the
+RFKILL button, and removed the module.
+While removing the module, the IRQ is freed, and the ISR is
+called (CONFIG_DEBUG_SHIRQ enabled). Panic.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Reviewed-by: Gregory Greenman <gregory.greenman at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/pcie/rx.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
+@@ -927,12 +927,20 @@ static irqreturn_t iwl_isr(int irq, void
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here. */
+- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */
++ inta_mask = iwl_read32(trans, CSR_INT_MASK);
+ iwl_write32(trans, CSR_INT_MASK, 0x00000000);
+
+ /* Discover which interrupts are active/pending */
+ inta = iwl_read32(trans, CSR_INT);
+
++ if (inta & (~inta_mask)) {
++ IWL_DEBUG_ISR(trans,
++ "We got a masked interrupt (0x%08x)...Ack and ignore\n",
++ inta & (~inta_mask));
++ iwl_write32(trans, CSR_INT, inta & (~inta_mask));
++ inta &= inta_mask;
++ }
++
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+@@ -1015,7 +1023,7 @@ irqreturn_t iwl_isr_ict(int irq, void *d
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here.
+ */
+- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */
++ inta_mask = iwl_read32(trans, CSR_INT_MASK);
+ iwl_write32(trans, CSR_INT_MASK, 0x00000000);
+
+
+From 27edb1accf5695ff00a32c85c4a00ac7e1e7f298 Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Sun, 2 Dec 2012 09:56:44 +0200
+Subject: iwlwifi: silently ignore fw flaws in Tx path
+
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+
+commit 27edb1accf5695ff00a32c85c4a00ac7e1e7f298 upstream.
+
+We know that we have issues with the fw in the reclaim path.
+This is why iwl_reclaim doesn't complain too loud when it
+happens since it is recoverable. Somehow, the caller of
+iwl_reclaim however WARNed when it happens. This doesn't
+make any sense.
+
+When I digged into the history of that code, I discovered
+that this bug occurs only when we receive a BA notification.
+So move the W/A in the BA notification handling code where
+it was before.
+
+This patch addresses:
+http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2387
+
+Reported-by: Florian Reitmeir <florian at reitmeir.org>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/dvm/tx.c | 49 ++++++++++++----------------------
+ 1 file changed, 18 insertions(+), 31 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
++++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
+@@ -1100,29 +1100,6 @@ static void iwl_check_abort_status(struc
+ }
+ }
+
+-static int iwl_reclaim(struct iwl_priv *priv, int sta_id, int tid,
+- int txq_id, int ssn, struct sk_buff_head *skbs)
+-{
+- if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE &&
+- tid != IWL_TID_NON_QOS &&
+- txq_id != priv->tid_data[sta_id][tid].agg.txq_id)) {
+- /*
+- * FIXME: this is a uCode bug which need to be addressed,
+- * log the information and return for now.
+- * Since it is can possibly happen very often and in order
+- * not to fill the syslog, don't use IWL_ERR or IWL_WARN
+- */
+- IWL_DEBUG_TX_QUEUES(priv,
+- "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",
+- txq_id, sta_id, tid,
+- priv->tid_data[sta_id][tid].agg.txq_id);
+- return 1;
+- }
+-
+- iwl_trans_reclaim(priv->trans, txq_id, ssn, skbs);
+- return 0;
+-}
+-
+ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd)
+ {
+@@ -1184,9 +1161,8 @@ int iwlagn_rx_reply_tx(struct iwl_priv *
+ next_reclaimed);
+ }
+
+- /*we can free until ssn % q.n_bd not inclusive */
+- WARN_ON_ONCE(iwl_reclaim(priv, sta_id, tid,
+- txq_id, ssn, &skbs));
++ iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
++
+ iwlagn_check_ratid_empty(priv, sta_id, tid);
+ freed = 0;
+
+@@ -1311,16 +1287,27 @@ int iwlagn_rx_reply_compressed_ba(struct
+ return 0;
+ }
+
++ if (unlikely(scd_flow != agg->txq_id)) {
++ /*
++ * FIXME: this is a uCode bug which need to be addressed,
++ * log the information and return for now.
++ * Since it is can possibly happen very often and in order
++ * not to fill the syslog, don't use IWL_ERR or IWL_WARN
++ */
++ IWL_DEBUG_TX_QUEUES(priv,
++ "Bad queue mapping txq_id=%d, agg_txq[sta:%d,tid:%d]=%d\n",
++ scd_flow, sta_id, tid, agg->txq_id);
++ spin_unlock(&priv->sta_lock);
++ return 0;
++ }
++
+ __skb_queue_head_init(&reclaimed_skbs);
+
+ /* Release all TFDs before the SSN, i.e. all TFDs in front of
+ * block-ack window (we assume that they've been successfully
+ * transmitted ... if not, it's too late anyway). */
+- if (iwl_reclaim(priv, sta_id, tid, scd_flow,
+- ba_resp_scd_ssn, &reclaimed_skbs)) {
+- spin_unlock(&priv->sta_lock);
+- return 0;
+- }
++ iwl_trans_reclaim(priv->trans, scd_flow, ba_resp_scd_ssn,
++ &reclaimed_skbs);
+
+ IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
+ "sta_id = %d\n",
+From cbbc0138efe1dcd5426b8fc5d87741f5057aee72 Mon Sep 17 00:00:00 2001
+From: Rafał Miłecki <zajec5 at gmail.com>
+Date: Mon, 10 Dec 2012 07:53:56 +0100
+Subject: bcma: mips: fix clearing device IRQ
+
+From: Rafał Miłecki <zajec5 at gmail.com>
+
+commit cbbc0138efe1dcd5426b8fc5d87741f5057aee72 upstream.
+
+We were using wrong IRQ number so clearing wasn't working at all.
+Depending on a platform this could result in a one device having two
+interrupts assigned. On BCM4706 this resulted in all IRQs being broken.
+
+Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
+Cc: Hauke Mehrtens <hauke at hauke-m.de>
+Acked-by: Hauke Mehrtens <hauke at hauke-m.de>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/bcma/driver_mips.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/bcma/driver_mips.c
++++ b/drivers/bcma/driver_mips.c
+@@ -115,7 +115,7 @@ static void bcma_core_mips_set_irq(struc
+ bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
+ ~(1 << irqflag));
+ else
+- bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
++ bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
+
+ /* assign the new one */
+ if (irq == 0) {
+From f5685ba675449b072feab6a5391a9ef9f604bc94 Mon Sep 17 00:00:00 2001
+From: Helmut Schaa <helmut.schaa at googlemail.com>
+Date: Mon, 3 Dec 2012 22:35:39 +0100
+Subject: rt2x00: Only specify interface combinations if more then one interface is possible
+
+From: Helmut Schaa <helmut.schaa at googlemail.com>
+
+commit f5685ba675449b072feab6a5391a9ef9f604bc94 upstream.
+
+Otherwise rt2500* triggers a warning in cfg80211, from net/wireless/core.c:
+
+ /* Combinations with just one interface aren't real */
+ if (WARN_ON(c->max_interfaces < 2))
+
+This was introduced in commit 55d2e9da744ba11eae900b4bfc2da72eace3c1e1:
+rt2x00: Replace open coded interface checking with interface combinations.
+
+Reported-by: Stefan Lippers-Hollmann <s.l-h at gmx.de>
+Tested-by: Stefan Lippers-Hollmann <s.l-h at gmx.de>
+Signed-off-by: Helmut Schaa <helmut.schaa at googlemail.com>
+Acked-by: Gertjan van Wingerde <gwingerde at gmail.com>
+Acked-by: Stanislaw Gruszka <sgruszka at redhat.com>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/rt2x00/rt2x00dev.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -1123,6 +1123,9 @@ static inline void rt2x00lib_set_if_comb
+ struct ieee80211_iface_limit *if_limit;
+ struct ieee80211_iface_combination *if_combination;
+
++ if (rt2x00dev->ops->max_ap_intf < 2)
++ return;
++
+ /*
+ * Build up AP interface limits structure.
+ */
+From 87cac8f879a5ecd7109dbe688087e8810b3364eb Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger at de.ibm.com>
+Date: Tue, 2 Oct 2012 16:25:38 +0200
+Subject: s390/kvm: dont announce RRBM support
+
+From: Christian Borntraeger <borntraeger at de.ibm.com>
+
+commit 87cac8f879a5ecd7109dbe688087e8810b3364eb upstream.
+
+Newer kernels (linux-next with the transparent huge page patches)
+use rrbm if the feature is announced via feature bit 66.
+RRBM will cause intercepts, so KVM does not handle it right now,
+causing an illegal instruction in the guest.
+The easy solution is to disable the feature bit for the guest.
+
+This fixes bugs like:
+Kernel BUG at 0000000000124c2a [verbose debug info unavailable]
+illegal operation: 0001 [#1] SMP
+Modules linked in: virtio_balloon virtio_net ipv6 autofs4
+CPU: 0 Not tainted 3.5.4 #1
+Process fmempig (pid: 659, task: 000000007b712fd0, ksp: 000000007bed3670)
+Krnl PSW : 0704d00180000000 0000000000124c2a (pmdp_clear_flush_young+0x5e/0x80)
+ R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:1 PM:0 EA:3
+ 00000000003cc000 0000000000000004 0000000000000000 0000000079800000
+ 0000000000040000 0000000000000000 000000007bed3918 000000007cf40000
+ 0000000000000001 000003fff7f00000 000003d281a94000 000000007bed383c
+ 000000007bed3918 00000000005ecbf8 00000000002314a6 000000007bed36e0
+ Krnl Code:>0000000000124c2a: b9810025 ogr %r2,%r5
+ 0000000000124c2e: 41343000 la %r3,0(%r4,%r3)
+ 0000000000124c32: a716fffa brct %r1,124c26
+ 0000000000124c36: b9010022 lngr %r2,%r2
+ 0000000000124c3a: e3d0f0800004 lg %r13,128(%r15)
+ 0000000000124c40: eb22003f000c srlg %r2,%r2,63
+[ 2150.713198] Call Trace:
+[ 2150.713223] ([<00000000002312c4>] page_referenced_one+0x6c/0x27c)
+[ 2150.713749] [<0000000000233812>] page_referenced+0x32a/0x410
+[...]
+
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+CC: Alex Graf <agraf at suse.de>
+Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
+Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/s390/kvm/kvm-s390.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -997,7 +997,7 @@ static int __init kvm_s390_init(void)
+ }
+ memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
+ facilities[0] &= 0xff00fff3f47c0000ULL;
+- facilities[1] &= 0x201c000000000000ULL;
++ facilities[1] &= 0x001c000000000000ULL;
+ return 0;
+ }
+
+From ce6a04ac1b759beafc88dbc443ae5da867579eeb Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger at de.ibm.com>
+Date: Thu, 15 Nov 2012 09:35:16 +0100
+Subject: s390/kvm: Fix address space mixup
+
+From: Christian Borntraeger <borntraeger at de.ibm.com>
+
+commit ce6a04ac1b759beafc88dbc443ae5da867579eeb upstream.
+
+I was chasing down a bug of random validity intercepts on s390.
+(guest prefix page not mapped in the host virtual aspace). Turns out
+that the problem was a wrong address space control element. The
+cause was quite complex:
+
+During paging activity a DAT protection during SIE caused a program
+interrupt. Normally, the sie retry loop tries to catch all
+interrupts during and shortly before sie to rerun the setup. The
+problem is now that protection causes a suppressing program interrupt,
+causing the PSW to point to the instruction AFTER SIE in case of DAT
+protection. This confused the logic of the retry loop to not trigger,
+instead we jumped directly back to SIE after return from
+the program interrupt. (the protection fault handler itself did
+a rewind of the psw). This usually works quite well, but:
+
+If now the protection fault handler has to wait, another program
+might be scheduled in. Later on the sie process will be schedules
+in again. In that case the content of CR1 (primary address space)
+will be wrong because switch_to will put the user space ASCE into CR1
+and not the guest ASCE.
+
+In addition the program parameter is also wrong for every protection
+fault of a guest, since we dont issue the SPP instruction.
+
+So lets also check for PSW == instruction after SIE in the program
+check handler. Instead of expensively checking all program
+interruption codes that might be suppressing we assume that a program
+interrupt pointing after SIE was always a program interrupt in SIE.
+(Otherwise we have a kernel bug anyway).
+
+We also have to compensate the rewinding, since the C-level handlers
+will do that. Therefore we need to add a nop with the same length
+as SIE before the sie_loop.
+
+Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+CC: Heiko Carstens <heiko.carstens at de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/s390/kernel/entry64.S | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+--- a/arch/s390/kernel/entry64.S
++++ b/arch/s390/kernel/entry64.S
+@@ -80,14 +80,21 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_
+ #endif
+ .endm
+
+- .macro HANDLE_SIE_INTERCEPT scratch
++ .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck
+ #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
+ tmhh %r8,0x0001 # interrupting from user ?
+ jnz .+42
+ lgr \scratch,%r9
+ slg \scratch,BASED(.Lsie_loop)
+ clg \scratch,BASED(.Lsie_length)
++ .if \pgmcheck
++ # Some program interrupts are suppressing (e.g. protection).
++ # We must also check the instruction after SIE in that case.
++ # do_protection_exception will rewind to rewind_pad
++ jh .+22
++ .else
+ jhe .+22
++ .endif
+ lg %r9,BASED(.Lsie_loop)
+ SPP BASED(.Lhost_id) # set host id
+ #endif
+@@ -391,7 +398,7 @@ ENTRY(pgm_check_handler)
+ lg %r12,__LC_THREAD_INFO
+ larl %r13,system_call
+ lmg %r8,%r9,__LC_PGM_OLD_PSW
+- HANDLE_SIE_INTERCEPT %r14
++ HANDLE_SIE_INTERCEPT %r14,1
+ tmhh %r8,0x0001 # test problem state bit
+ jnz 1f # -> fault in user space
+ tmhh %r8,0x4000 # PER bit set in old PSW ?
+@@ -467,7 +474,7 @@ ENTRY(io_int_handler)
+ lg %r12,__LC_THREAD_INFO
+ larl %r13,system_call
+ lmg %r8,%r9,__LC_IO_OLD_PSW
+- HANDLE_SIE_INTERCEPT %r14
++ HANDLE_SIE_INTERCEPT %r14,0
+ SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
+ tmhh %r8,0x0001 # interrupting from user?
+ jz io_skip
+@@ -613,7 +620,7 @@ ENTRY(ext_int_handler)
+ lg %r12,__LC_THREAD_INFO
+ larl %r13,system_call
+ lmg %r8,%r9,__LC_EXT_OLD_PSW
+- HANDLE_SIE_INTERCEPT %r14
++ HANDLE_SIE_INTERCEPT %r14,0
+ SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
+ tmhh %r8,0x0001 # interrupting from user ?
+ jz ext_skip
+@@ -661,7 +668,7 @@ ENTRY(mcck_int_handler)
+ lg %r12,__LC_THREAD_INFO
+ larl %r13,system_call
+ lmg %r8,%r9,__LC_MCK_OLD_PSW
+- HANDLE_SIE_INTERCEPT %r14
++ HANDLE_SIE_INTERCEPT %r14,0
+ tm __LC_MCCK_CODE,0x80 # system damage?
+ jo mcck_panic # yes -> rest of mcck code invalid
+ lghi %r14,__LC_CPU_TIMER_SAVE_AREA
+@@ -960,6 +967,13 @@ ENTRY(sie64a)
+ stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
+ xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
+ lmg %r0,%r13,0(%r3) # load guest gprs 0-13
++# some program checks are suppressing. C code (e.g. do_protection_exception)
++# will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other
++# instructions in the sie_loop should not cause program interrupts. So
++# lets use a nop (47 00 00 00) as a landing pad.
++# See also HANDLE_SIE_INTERCEPT
++rewind_pad:
++ nop 0
+ sie_loop:
+ lg %r14,__LC_THREAD_INFO # pointer thread_info struct
+ tm __TI_flags+7(%r14),_TIF_EXIT_SIE
+@@ -999,6 +1013,7 @@ sie_fault:
+ .Lhost_id:
+ .quad 0
+
++ EX_TABLE(rewind_pad,sie_fault)
+ EX_TABLE(sie_loop,sie_fault)
+ #endif
+
+From 11ee7e99f35ecb15f59b21da6a82d96d2cd3fcc8 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton at samba.org>
+Date: Sun, 11 Nov 2012 19:01:05 +0000
+Subject: powerpc: Fix CONFIG_RELOCATABLE=y CONFIG_CRASH_DUMP=n build
+
+From: Anton Blanchard <anton at samba.org>
+
+commit 11ee7e99f35ecb15f59b21da6a82d96d2cd3fcc8 upstream.
+
+If we build a kernel with CONFIG_RELOCATABLE=y CONFIG_CRASH_DUMP=n,
+the kernel fails when we run at a non zero offset. It turns out
+we were incorrectly wrapping some of the relocatable kernel code
+with CONFIG_CRASH_DUMP.
+
+Signed-off-by: Anton Blanchard <anton at samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/head_64.S | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/kernel/head_64.S
++++ b/arch/powerpc/kernel/head_64.S
+@@ -422,7 +422,7 @@ _STATIC(__after_prom_start)
+ tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */
+ #endif
+
+-#ifdef CONFIG_CRASH_DUMP
++#ifdef CONFIG_RELOCATABLE
+ /*
+ * Check if the kernel has to be running as relocatable kernel based on the
+ * variable __run_at_load, if it is set the kernel is treated as relocatable
+From ce73ec6db47af84d1466402781ae0872a9e7873c Mon Sep 17 00:00:00 2001
+From: Shan Hai <shan.hai at windriver.com>
+Date: Thu, 8 Nov 2012 15:57:49 +0000
+Subject: powerpc/vdso: Remove redundant locking in update_vsyscall_tz()
+
+From: Shan Hai <shan.hai at windriver.com>
+
+commit ce73ec6db47af84d1466402781ae0872a9e7873c upstream.
+
+The locking in update_vsyscall_tz() is not only unnecessary because the vdso
+code copies the data unproteced in __kernel_gettimeofday() but also
+introduces a hard to reproduce race condition between update_vsyscall()
+and update_vsyscall_tz(), which causes user space process to loop
+forever in vdso code.
+
+The following patch removes the locking from update_vsyscall_tz().
+
+Locking is not only unnecessary because the vdso code copies the data
+unprotected in __kernel_gettimeofday() but also erroneous because updating
+the tb_update_count is not atomic and introduces a hard to reproduce race
+condition between update_vsyscall() and update_vsyscall_tz(), which further
+causes user space process to loop forever in vdso code.
+
+The below scenario describes the race condition,
+x==0 Boot CPU other CPU
+ proc_P: x==0
+ timer interrupt
+ update_vsyscall
+x==1 x++;sync settimeofday
+ update_vsyscall_tz
+x==2 x++;sync
+x==3 sync;x++
+ sync;x++
+ proc_P: x==3 (loops until x becomes even)
+
+Because the ++ operator would be implemented as three instructions and not
+atomic on powerpc.
+
+A similar change was made for x86 in commit 6c260d58634
+("x86: vdso: Remove bogus locking in update_vsyscall_tz")
+
+Signed-off-by: Shan Hai <shan.hai at windriver.com>
+Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/time.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/arch/powerpc/kernel/time.c
++++ b/arch/powerpc/kernel/time.c
+@@ -774,13 +774,8 @@ void update_vsyscall_old(struct timespec
+
+ void update_vsyscall_tz(void)
+ {
+- /* Make userspace gettimeofday spin until we're done. */
+- ++vdso_data->tb_update_count;
+- smp_mb();
+ vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
+ vdso_data->tz_dsttime = sys_tz.tz_dsttime;
+- smp_mb();
+- ++vdso_data->tb_update_count;
+ }
+
+ static void __init clocksource_init(void)
+From e6449c9b2d90c1bd9a5985bf05ddebfd1631cd6b Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg at openwrt.org>
+Date: Thu, 20 Dec 2012 03:44:28 +0000
+Subject: powerpc: Add missing NULL terminator to avoid boot panic on PPC40x
+
+From: Gabor Juhos <juhosg at openwrt.org>
+
+commit e6449c9b2d90c1bd9a5985bf05ddebfd1631cd6b upstream.
+
+The missing NULL terminator can cause a panic on
+PPC405 boards during boot:
+
+ Linux/PowerPC load: console=ttyS0,115200 root=/dev/mtdblock1 rootfstype=squashfs,jffs2 noinitrd init=/etc/preinit
+ Finalizing device tree... flat tree at 0x6a5160
+ bootconsole [udbg0] enabled
+ Page fault in user mode with in_atomic() = 1 mm = (null)
+ NIP = c0275f50 MSR = fffffffe
+ Oops: Weird page fault, sig: 11 [#1]
+ PowerPC 40x Platform
+ Modules linked in:
+ NIP: c0275f50 LR: c0275f60 CTR: c0280000
+ REGS: c0275eb0 TRAP: 636f7265 Not tainted (3.7.1)
+ MSR: fffffffe <VEC,VSX,EE,PR,FP,ME,SE,BE,IR,DR,PMM,RI> CR: c06a6190 XER: 00000001
+ TASK = c02662a8[0] 'swapper' THREAD: c0274000
+ GPR00: c0275ec0 c000c658 c027c4bf 00000000 c0275ee0 c000a0ec c020a1a8 c020a1f0
+ GPR08: c020f631 c020f404 c025f078 c025f080 c0275f10
+ Call Trace:
+ ---[ end trace 31fd0ba7d8756001 ]---
+
+ Kernel panic - not syncing: Attempted to kill the idle task!
+
+The panic happens since commit 9597abe00c1bab2aedce6b49866bf6d1e81c9eed
+(sections: fix section conflicts in arch/powerpc), however the root
+cause of this is that the NULL terminator were not added in commit
+a4f740cf33f7f6c164bbde3c0cdbcc77b0c4997c (of/flattree: Add of_flat_dt_match()
+helper function).
+
+Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
+Cc: Grant Likely <grant.likely at secretlab.ca>
+Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/40x/ppc40x_simple.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
++++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
+@@ -57,7 +57,8 @@ static const char * const board[] __init
+ "amcc,makalu",
+ "apm,klondike",
+ "est,hotfoot",
+- "plathome,obs600"
++ "plathome,obs600",
++ NULL
+ };
+
+ static int __init ppc40x_probe(void)
+From e400e72f250d2567e89c9bafb47ab91e8d9a15a2 Mon Sep 17 00:00:00 2001
+From: Scott Wood <scottwood at freescale.com>
+Date: Wed, 22 Aug 2012 15:04:23 +0000
+Subject: KVM: PPC: e500: fix allocation size error on g2h_tlb1_map
+
+From: Scott Wood <scottwood at freescale.com>
+
+commit e400e72f250d2567e89c9bafb47ab91e8d9a15a2 upstream.
+
+We were only allocating half the bytes we need, which was made more
+obvious by a recent fix to the memset in clear_tlb1_bitmap().
+
+Signed-off-by: Scott Wood <scottwood at freescale.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/powerpc/kvm/e500_tlb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/kvm/e500_tlb.c
++++ b/arch/powerpc/kvm/e500_tlb.c
+@@ -1332,7 +1332,7 @@ int kvmppc_e500_tlb_init(struct kvmppc_v
+ if (!vcpu_e500->gtlb_priv[1])
+ goto err;
+
+- vcpu_e500->g2h_tlb1_map = kzalloc(sizeof(unsigned int) *
++ vcpu_e500->g2h_tlb1_map = kzalloc(sizeof(u64) *
+ vcpu_e500->gtlb_params[1].entries,
+ GFP_KERNEL);
+ if (!vcpu_e500->g2h_tlb1_map)
+From 5419369ed6bd4cf711fdda5e52a5999b940413f5 Mon Sep 17 00:00:00 2001
+From: Alex Williamson <alex.williamson at redhat.com>
+Date: Thu, 29 Nov 2012 14:07:59 -0700
+Subject: KVM: Fix user memslot overlap check
+
+From: Alex Williamson <alex.williamson at redhat.com>
+
+commit 5419369ed6bd4cf711fdda5e52a5999b940413f5 upstream.
+
+Prior to memory slot sorting this loop compared all of the user memory
+slots for overlap with new entries. With memory slot sorting, we're
+just checking some number of entries in the array that may or may not
+be user slots. Instead, walk all the slots with kvm_for_each_memslot,
+which has the added benefit of terminating early when we hit the first
+empty slot, and skip comparison to private slots.
+
+Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
+Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ virt/kvm/kvm_main.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -709,8 +709,7 @@ int __kvm_set_memory_region(struct kvm *
+ int r;
+ gfn_t base_gfn;
+ unsigned long npages;
+- unsigned long i;
+- struct kvm_memory_slot *memslot;
++ struct kvm_memory_slot *memslot, *slot;
+ struct kvm_memory_slot old, new;
+ struct kvm_memslots *slots, *old_memslots;
+
+@@ -761,13 +760,11 @@ int __kvm_set_memory_region(struct kvm *
+
+ /* Check for overlaps */
+ r = -EEXIST;
+- for (i = 0; i < KVM_MEMORY_SLOTS; ++i) {
+- struct kvm_memory_slot *s = &kvm->memslots->memslots[i];
+-
+- if (s == memslot || !s->npages)
++ kvm_for_each_memslot(slot, kvm->memslots) {
++ if (slot->id >= KVM_MEMORY_SLOTS || slot == memslot)
+ continue;
+- if (!((base_gfn + npages <= s->base_gfn) ||
+- (base_gfn >= s->base_gfn + s->npages)))
++ if (!((base_gfn + npages <= slot->base_gfn) ||
++ (base_gfn >= slot->base_gfn + slot->npages)))
+ goto out_free;
+ }
+
+From d99e79ec5574fc556c988f613ed6175f6de66f4a Mon Sep 17 00:00:00 2001
+From: Sebastian Ott <sebott at linux.vnet.ibm.com>
+Date: Fri, 30 Nov 2012 16:48:59 +0100
+Subject: s390/cio: fix pgid reserved check
+
+From: Sebastian Ott <sebott at linux.vnet.ibm.com>
+
+commit d99e79ec5574fc556c988f613ed6175f6de66f4a upstream.
+
+The check to whom a device is reserved is done by checking the path
+state of the affected channel paths. If it turns out that one path is
+flagged as reserved by someone else the whole device is marked as such.
+
+However the meaning of the RESVD_ELSE bit is that the addressed device
+is reserved to a different pathgroup (and not reserved to a different
+LPAR). If we do this test on a path which is currently not a member of
+the pathgroup we could erroneously mark the device as reserved to
+someone else.
+
+To fix this collect the reserved state for all potential members of the
+pathgroup and only mark the device as reserved if all of those potential
+members have the RESVD_ELSE bit set.
+
+Acked-by: Peter Oberparleiter <peter.oberparleiter at de.ibm.com>
+Signed-off-by: Sebastian Ott <sebott at linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/s390/cio/device_pgid.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/s390/cio/device_pgid.c
++++ b/drivers/s390/cio/device_pgid.c
+@@ -234,7 +234,7 @@ static int pgid_cmp(struct pgid *p1, str
+ * Determine pathgroup state from PGID data.
+ */
+ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
+- int *mismatch, int *reserved, u8 *reset)
++ int *mismatch, u8 *reserved, u8 *reset)
+ {
+ struct pgid *pgid = &cdev->private->pgid[0];
+ struct pgid *first = NULL;
+@@ -248,7 +248,7 @@ static void pgid_analyze(struct ccw_devi
+ if ((cdev->private->pgid_valid_mask & lpm) == 0)
+ continue;
+ if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE)
+- *reserved = 1;
++ *reserved |= lpm;
+ if (pgid_is_reset(pgid)) {
+ *reset |= lpm;
+ continue;
+@@ -316,14 +316,14 @@ static void snid_done(struct ccw_device
+ struct subchannel *sch = to_subchannel(cdev->dev.parent);
+ struct pgid *pgid;
+ int mismatch = 0;
+- int reserved = 0;
++ u8 reserved = 0;
+ u8 reset = 0;
+ u8 donepm;
+
+ if (rc)
+ goto out;
+ pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset);
+- if (reserved)
++ if (reserved == cdev->private->pgid_valid_mask)
+ rc = -EUSERS;
+ else if (mismatch)
+ rc = -EOPNOTSUPP;
+@@ -336,7 +336,7 @@ static void snid_done(struct ccw_device
+ }
+ out:
+ CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
+- "todo=%02x mism=%d rsvd=%d reset=%02x\n", id->ssid,
++ "todo=%02x mism=%d rsvd=%02x reset=%02x\n", id->ssid,
+ id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm,
+ cdev->private->pgid_todo_mask, mismatch, reserved, reset);
+ switch (rc) {
+From 8add1ecb81f541ef2fcb0b85a5470ad9ecfb4a84 Mon Sep 17 00:00:00 2001
+From: Huacai Chen <chenhc at lemote.com>
+Date: Mon, 13 Aug 2012 20:52:24 +0800
+Subject: MIPS: Fix poweroff failure when HOTPLUG_CPU configured.
+
+From: Huacai Chen <chenhc at lemote.com>
+
+commit 8add1ecb81f541ef2fcb0b85a5470ad9ecfb4a84 upstream.
+
+When poweroff machine, kernel_power_off() call disable_nonboot_cpus().
+And if we have HOTPLUG_CPU configured, disable_nonboot_cpus() is not an
+empty function but attempt to actually disable the nonboot cpus. Since
+system state is SYSTEM_POWER_OFF, play_dead() won't be called and thus
+disable_nonboot_cpus() hangs. Therefore, we make this patch to avoid
+poweroff failure.
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Signed-off-by: Hongliang Tao <taohl at lemote.com>
+Signed-off-by: Hua Yan <yanh at lemote.com>
+Cc: Yong Zhang <yong.zhang at windriver.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Patchwork: https://patchwork.linux-mips.org/patch/4211/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/mips/kernel/process.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -72,9 +72,7 @@ void __noreturn cpu_idle(void)
+ }
+ }
+ #ifdef CONFIG_HOTPLUG_CPU
+- if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
+- (system_state == SYSTEM_RUNNING ||
+- system_state == SYSTEM_BOOTING))
++ if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map))
+ play_dead();
+ #endif
+ rcu_idle_exit();
+From 7964c06d66c76507d8b6b662bffea770c29ef0ce Mon Sep 17 00:00:00 2001
+From: Jason Liu <r64343 at freescale.com>
+Date: Fri, 11 Jan 2013 14:31:47 -0800
+Subject: mm: compaction: fix echo 1 > compact_memory return error issue
+
+From: Jason Liu <r64343 at freescale.com>
+
+commit 7964c06d66c76507d8b6b662bffea770c29ef0ce upstream.
+
+when run the folloing command under shell, it will return error
+
+ sh/$ echo 1 > /proc/sys/vm/compact_memory
+ sh/$ sh: write error: Bad address
+
+After strace, I found the following log:
+
+ ...
+ write(1, "1\n", 2) = 3
+ write(1, "", 4294967295) = -1 EFAULT (Bad address)
+ write(2, "echo: write error: Bad address\n", 31echo: write error: Bad address
+ ) = 31
+
+This tells system return 3(COMPACT_COMPLETE) after write data to
+compact_memory.
+
+The fix is to make the system just return 0 instead 3(COMPACT_COMPLETE)
+from sysctl_compaction_handler after compaction_nodes finished.
+
+Signed-off-by: Jason Liu <r64343 at freescale.com>
+Suggested-by: David Rientjes <rientjes at google.com>
+Acked-by: Mel Gorman <mgorman at suse.de>
+Cc: Rik van Riel <riel at redhat.com>
+Cc: Minchan Kim <minchan at kernel.org>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
+Acked-by: David Rientjes <rientjes at google.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ mm/compaction.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -1174,7 +1174,7 @@ static int compact_node(int nid)
+ }
+
+ /* Compact all nodes in the system */
+-static int compact_nodes(void)
++static void compact_nodes(void)
+ {
+ int nid;
+
+@@ -1183,8 +1183,6 @@ static int compact_nodes(void)
+
+ for_each_online_node(nid)
+ compact_node(nid);
+-
+- return COMPACT_COMPLETE;
+ }
+
+ /* The written value is actually unused, all memory is compacted */
+@@ -1195,7 +1193,7 @@ int sysctl_compaction_handler(struct ctl
+ void __user *buffer, size_t *length, loff_t *ppos)
+ {
+ if (write)
+- return compact_nodes();
++ compact_nodes();
+
+ return 0;
+ }
+From c060f943d0929f3e429c5d9522290584f6281d6e Mon Sep 17 00:00:00 2001
+From: Laura Abbott <lauraa at codeaurora.org>
+Date: Fri, 11 Jan 2013 14:31:51 -0800
+Subject: mm: use aligned zone start for pfn_to_bitidx calculation
+
+From: Laura Abbott <lauraa at codeaurora.org>
+
+commit c060f943d0929f3e429c5d9522290584f6281d6e upstream.
+
+The current calculation in pfn_to_bitidx assumes that (pfn -
+zone->zone_start_pfn) >> pageblock_order will return the same bit for
+all pfn in a pageblock. If zone_start_pfn is not aligned to
+pageblock_nr_pages, this may not always be correct.
+
+Consider the following with pageblock order = 10, zone start 2MB:
+
+ pfn | pfn - zone start | (pfn - zone start) >> page block order
+ ----------------------------------------------------------------
+ 0x26000 | 0x25e00 | 0x97
+ 0x26100 | 0x25f00 | 0x97
+ 0x26200 | 0x26000 | 0x98
+ 0x26300 | 0x26100 | 0x98
+
+This means that calling {get,set}_pageblock_migratetype on a single page
+will not set the migratetype for the full block. Fix this by rounding
+down zone_start_pfn when doing the bitidx calculation.
+
+For our use case, the effects of this bug were mostly tied to the fact
+that CMA allocations would either take a long time or fail to happen.
+Depending on the driver using CMA, this could result in anything from
+visual glitches to application failures.
+
+Signed-off-by: Laura Abbott <lauraa at codeaurora.org>
+Acked-by: Mel Gorman <mgorman at suse.de>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ mm/page_alloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -5506,7 +5506,7 @@ static inline int pfn_to_bitidx(struct z
+ pfn &= (PAGES_PER_SECTION-1);
+ return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
+ #else
+- pfn = pfn - zone->zone_start_pfn;
++ pfn = pfn - round_down(zone->zone_start_pfn, pageblock_nr_pages);
+ return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
+ #endif /* CONFIG_SPARSEMEM */
+ }
+From 10d73e655cef6e86ea8589dca3df4e495e4900b0 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Fri, 11 Jan 2013 14:31:52 -0800
+Subject: mm: bootmem: fix free_all_bootmem_core() with odd bitmap alignment
+
+From: Max Filippov <jcmvbkbc at gmail.com>
+
+commit 10d73e655cef6e86ea8589dca3df4e495e4900b0 upstream.
+
+Currently free_all_bootmem_core ignores that node_min_pfn may be not
+multiple of BITS_PER_LONG. Eg commit 6dccdcbe2c3e ("mm: bootmem: fix
+checking the bitmap when finally freeing bootmem") shifts vec by lower
+bits of start instead of lower bits of idx. Also
+
+ if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL)
+
+assumes that vec bit 0 corresponds to start pfn, which is only true when
+node_min_pfn is a multiple of BITS_PER_LONG. Also loop in the else
+clause can double-free pages (e.g. with node_min_pfn == start == 1,
+map[0] == ~0 on 32-bit machine page 32 will be double-freed).
+
+This bug causes the following message during xtensa kernel boot:
+
+ bootmem::free_all_bootmem_core nid=0 start=1 end=8000
+ BUG: Bad page state in process swapper pfn:00001
+ page:d04bd020 count:0 mapcount:-127 mapping: (null) index:0x2
+ page flags: 0x0()
+ Call Trace:
+ bad_page+0x8c/0x9c
+ free_pages_prepare+0x5e/0x88
+ free_hot_cold_page+0xc/0xa0
+ __free_pages+0x24/0x38
+ __free_pages_bootmem+0x54/0x56
+ free_all_bootmem_core$part$11+0xeb/0x138
+ free_all_bootmem+0x46/0x58
+ mem_init+0x25/0xa4
+ start_kernel+0x11e/0x25c
+ should_never_return+0x0/0x3be7
+
+The fix is the following:
+ - always align vec so that its bit 0 corresponds to start
+ - provide BITS_PER_LONG bits in vec, if those bits are available in the
+ map
+ - don't free pages past next start position in the else clause.
+
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Cc: Gavin Shan <shangw at linux.vnet.ibm.com>
+Cc: Johannes Weiner <hannes at cmpxchg.org>
+Cc: Tejun Heo <tj at kernel.org>
+Cc: Yinghai Lu <yinghai at kernel.org>
+Cc: Joonsoo Kim <js1304 at gmail.com>
+Cc: Prasad Koya <prasad.koya at gmail.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ mm/bootmem.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+--- a/mm/bootmem.c
++++ b/mm/bootmem.c
+@@ -185,10 +185,23 @@ static unsigned long __init free_all_boo
+
+ while (start < end) {
+ unsigned long *map, idx, vec;
++ unsigned shift;
+
+ map = bdata->node_bootmem_map;
+ idx = start - bdata->node_min_pfn;
++ shift = idx & (BITS_PER_LONG - 1);
++ /*
++ * vec holds at most BITS_PER_LONG map bits,
++ * bit 0 corresponds to start.
++ */
+ vec = ~map[idx / BITS_PER_LONG];
++
++ if (shift) {
++ vec >>= shift;
++ if (end - start >= BITS_PER_LONG)
++ vec |= ~map[idx / BITS_PER_LONG + 1] <<
++ (BITS_PER_LONG - shift);
++ }
+ /*
+ * If we have a properly aligned and fully unreserved
+ * BITS_PER_LONG block of pages in front of us, free
+@@ -201,19 +214,18 @@ static unsigned long __init free_all_boo
+ count += BITS_PER_LONG;
+ start += BITS_PER_LONG;
+ } else {
+- unsigned long off = 0;
++ unsigned long cur = start;
+
+- vec >>= start & (BITS_PER_LONG - 1);
+- while (vec) {
++ start = ALIGN(start + 1, BITS_PER_LONG);
++ while (vec && cur != start) {
+ if (vec & 1) {
+- page = pfn_to_page(start + off);
++ page = pfn_to_page(cur);
+ __free_pages_bootmem(page, 0);
+ count++;
+ }
+ vec >>= 1;
+- off++;
++ ++cur;
+ }
+- start = ALIGN(start + 1, BITS_PER_LONG);
+ }
+ }
+
+From 1680260226a8fd2aab590319da83ad8e610da9bd Mon Sep 17 00:00:00 2001
+From: Rajkumar Manoharan <rmanohar at qca.qualcomm.com>
+Date: Thu, 25 Oct 2012 17:11:31 +0530
+Subject: ath9k_hw: Enable hw PLL power save for AR9462
+
+From: Rajkumar Manoharan <rmanohar at qca.qualcomm.com>
+
+commit 1680260226a8fd2aab590319da83ad8e610da9bd upstream.
+
+This reduced the power consumption to half in full and network sleep.
+
+Signed-off-by: Rajkumar Manoharan <rmanohar at qca.qualcomm.com>
+Cc: Paul Stewart <pstew at chromium.org>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_hw.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+@@ -219,10 +219,10 @@ static void ar9003_hw_init_mode_regs(str
+
+ /* Awake -> Sleep Setting */
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
+- ar9462_pciephy_pll_on_clkreq_disable_L1_2p0);
++ ar9462_pciephy_clkreq_disable_L1_2p0);
+ /* Sleep -> Awake Setting */
+ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
+- ar9462_pciephy_pll_on_clkreq_disable_L1_2p0);
++ ar9462_pciephy_clkreq_disable_L1_2p0);
+
+ /* Fast clock modal settings */
+ INIT_INI_ARRAY(&ah->iniModesFastClock,
+From 9c170e068636deb3e3f96114034bb711675f0faa Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd at openwrt.org>
+Date: Thu, 6 Dec 2012 18:40:11 +0100
+Subject: Revert "ath9k_hw: Update AR9003 high_power tx gain table"
+
+From: Felix Fietkau <nbd at openwrt.org>
+
+commit 9c170e068636deb3e3f96114034bb711675f0faa upstream.
+
+This reverts commit f74b9d365ddd33a375802b064f96a5d0e99af7c0.
+
+Turns out reverting commit a240dc7b3c7463bd60cf0a9b2a90f52f78aae0fd
+"ath9k_hw: Updated AR9003 tx gain table for 5GHz" was not enough to
+bring the tx power back to normal levels on devices like the
+Buffalo WZR-HP-G450H, this one needs to be reverted as well.
+
+This revert improves tx power by ~10 db on that device
+
+Signed-off-by: Felix Fietkau <nbd at openwrt.org>
+Cc: rmanohar at qca.qualcomm.com
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h | 172 +++++++++----------
+ 1 file changed, 86 insertions(+), 86 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+@@ -534,98 +534,98 @@ static const u32 ar9300_2p2_baseband_cor
+
+ static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
+ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
+- {0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+- {0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+- {0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+- {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+- {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+- {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+- {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+- {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+- {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+- {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
+- {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
+- {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+- {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+- {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+- {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+- {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+- {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+- {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+- {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+- {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+- {0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+- {0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+- {0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+- {0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+- {0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+- {0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+- {0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+- {0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+- {0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+- {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+- {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+- {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+- {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+- {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+- {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+- {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
+- {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
+- {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+- {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+- {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+- {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+- {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+- {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+- {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+- {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+- {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+- {0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+- {0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+- {0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+- {0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+- {0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+- {0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+- {0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+- {0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+- {0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+- {0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
++ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
++ {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
++ {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
++ {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
++ {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
++ {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
++ {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
++ {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
++ {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
++ {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
++ {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
++ {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
++ {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
++ {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
++ {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
++ {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
++ {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
++ {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
++ {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
++ {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
++ {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83},
++ {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
++ {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
++ {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
++ {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
++ {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
++ {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
++ {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
++ {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
++ {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
++ {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
++ {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
++ {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
++ {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
++ {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
++ {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
++ {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
++ {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
++ {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
++ {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
++ {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
++ {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
++ {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
++ {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
++ {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
++ {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
++ {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
++ {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
++ {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
++ {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
++ {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
++ {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
++ {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
++ {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+- {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+- {0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+- {0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+- {0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+- {0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+- {0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+- {0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+- {0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+- {0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+- {0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+- {0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+- {0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+- {0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+- {0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+- {0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++ {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
++ {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
++ {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
++ {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
++ {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
++ {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
++ {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
++ {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++ {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++ {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++ {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++ {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+- {0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+- {0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+- {0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
++ {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
++ {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
++ {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
+ {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
+From b3cd8021379306c0be6932e4d3b4b01efc681769 Mon Sep 17 00:00:00 2001
+From: Gabor Juhos <juhosg at openwrt.org>
+Date: Sun, 9 Dec 2012 23:57:09 +0100
+Subject: ath9k: ar9003: fix OTP register offsets for AR9340
+
+From: Gabor Juhos <juhosg at openwrt.org>
+
+commit b3cd8021379306c0be6932e4d3b4b01efc681769 upstream.
+
+Trying to access the OTP memory on the AR9340
+causes a data bus error like this:
+
+ Data bus error, epc == 86e84164, ra == 86e84164
+ Oops[#1]:
+ Cpu 0
+ $ 0 : 00000000 00000061 deadc0de 00000000
+ $ 4 : b8115f18 00015f18 00000007 00000004
+ $ 8 : 00000001 7c7c3c7c 7c7c7c7c 7c7c7c7c
+ $12 : 7c7c3c7c 001f0041 00000000 7c7c7c3c
+ $16 : 86ee0000 00015f18 00000000 00000007
+ $20 : 00000004 00000064 00000004 86d71c44
+ $24 : 00000000 86e6ca00
+ $28 : 86d70000 86d71b20 86ece0c0 86e84164
+ Hi : 00000000
+ Lo : 00000064
+ epc : 86e84164 ath9k_hw_wait+0x58/0xb0 [ath9k_hw]
+ Tainted: G O
+ ra : 86e84164 ath9k_hw_wait+0x58/0xb0 [ath9k_hw]
+ Status: 1100d403 KERNEL EXL IE
+ Cause : 4080801c
+ PrId : 0001974c (MIPS 74Kc)
+ Modules linked in: ath9k(O+) ath9k_common(O) ath9k_hw(O) ath(O) ar934x_nfc
+ mac80211(O) usbcore usb_common scsi_mod nls_base nand nand_ecc nand_ids
+ crc_ccitt cfg80211(O) compat(O) arc4 aes_generic crypto_blkcipher cryptomgr
+ aead crypto_hash crypto_algapi ledtrig_timer ledtrig_default_on leds_gpio
+ Process insmod (pid: 459, threadinfo=86d70000, task=87942140, tls=779ac440)
+ Stack : 802fb500 000200da 804db150 804e0000 87816130 86ee0000 00010000 86d71b88
+ 86d71bc0 00000004 00000003 86e9fcd0 80305300 0002c0d0 86e74c50 800b4c20
+ 000003e8 00000001 00000000 86ee0000 000003ff 86e9fd64 80305300 80123938
+ fffffffc 00000004 000058bc 00000000 86ea0000 86ee0000 000001ff 878d6000
+ 99999999 86e9fdc0 86ee0fcc 86e9e664 0000c0d0 86ee0000 0000700000007000
+ ...
+ Call Trace:
+ [<86e84164>] ath9k_hw_wait+0x58/0xb0 [ath9k_hw]
+ [<86e9fcd0>] ath9k_hw_setup_statusring+0x16b8/0x1c7c [ath9k_hw]
+
+ Code: 0000a812 0040f809 00000000 <00531024> 1054000b 24020001 0c05b5dc 2404000a 26520001
+
+The cause of the error is that the OTP register
+offsets are different on the AR9340 than the
+actually used values.
+
+Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+@@ -68,13 +68,13 @@
+ #define AR9300_BASE_ADDR 0x3ff
+ #define AR9300_BASE_ADDR_512 0x1ff
+
+-#define AR9300_OTP_BASE 0x14000
+-#define AR9300_OTP_STATUS 0x15f18
++#define AR9300_OTP_BASE (AR_SREV_9340(ah) ? 0x30000 : 0x14000)
++#define AR9300_OTP_STATUS (AR_SREV_9340(ah) ? 0x30018 : 0x15f18)
+ #define AR9300_OTP_STATUS_TYPE 0x7
+ #define AR9300_OTP_STATUS_VALID 0x4
+ #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+ #define AR9300_OTP_STATUS_SM_BUSY 0x1
+-#define AR9300_OTP_READ_DATA 0x15f1c
++#define AR9300_OTP_READ_DATA (AR_SREV_9340(ah) ? 0x3001c : 0x15f1c)
+
+ enum targetPowerHTRates {
+ HT_TARGET_RATE_0_8_16,
+From b7c0c238898d200e80487516e2b67aba2a522cc0 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd at openwrt.org>
+Date: Mon, 10 Dec 2012 14:03:17 +0100
+Subject: ath9k_hw: Fix signal strength / channel noise reporting
+
+From: Felix Fietkau <nbd at openwrt.org>
+
+commit b7c0c238898d200e80487516e2b67aba2a522cc0 upstream.
+
+While AR_PHY_CCA_NOM_VAL_* does contain the expected internal noise floor
+for a chip measured in clean air, it refers to the lowest expected reading.
+
+Depending on the frequency, this measurement can vary by about 6db, thus
+causing a higher reported channel noise and signal strength.
+
+Factor in the 6db offset when converting internal noisefloor to channel noise.
+
+This patch makes the reported values more accurate for all chips without
+affecting NF calibration behavior.
+
+Signed-off-by: Felix Fietkau <nbd at openwrt.org>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/calib.c | 1 +
+ drivers/net/wireless/ath/ath9k/calib.h | 3 +++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/ath/ath9k/calib.c
++++ b/drivers/net/wireless/ath/ath9k/calib.c
+@@ -69,6 +69,7 @@ s16 ath9k_hw_getchan_noise(struct ath_hw
+
+ if (chan && chan->noisefloor) {
+ s8 delta = chan->noisefloor -
++ ATH9K_NF_CAL_NOISE_THRESH -
+ ath9k_hw_get_default_nf(ah, chan);
+ if (delta > 0)
+ noise += delta;
+--- a/drivers/net/wireless/ath/ath9k/calib.h
++++ b/drivers/net/wireless/ath/ath9k/calib.h
+@@ -21,6 +21,9 @@
+
+ #define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
+
++/* Internal noise floor can vary by about 6db depending on the frequency */
++#define ATH9K_NF_CAL_NOISE_THRESH 6
++
+ #define NUM_NF_READINGS 6
+ #define ATH9K_NF_CAL_HIST_MAX 5
+
+From a796a1dd5da9645ad77aa687d1a890ecd63ab5a6 Mon Sep 17 00:00:00 2001
+From: Sujith Manoharan <c_manoha at qca.qualcomm.com>
+Date: Wed, 26 Dec 2012 12:27:39 +0530
+Subject: ath9k_hw: Fix RX gain initvals for AR9485
+
+From: Sujith Manoharan <c_manoha at qca.qualcomm.com>
+
+commit a796a1dd5da9645ad77aa687d1a890ecd63ab5a6 upstream.
+
+Populate iniModesRxGain with the correct initvals
+array for AR9485 v1.1
+
+Signed-off-by: Sujith Manoharan <c_manoha at qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/ath9k/ar9003_hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+@@ -540,7 +540,7 @@ static void ar9003_rx_gain_table_mode0(s
+ ar9340Common_rx_gain_table_1p0);
+ else if (AR_SREV_9485_11(ah))
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+- ar9485Common_wo_xlna_rx_gain_1_1);
++ ar9485_common_rx_gain_1_1);
+ else if (AR_SREV_9550(ah)) {
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
+ ar955x_1p0_common_rx_gain_table);
+From 5b632fe85ec82e5c43740b52e74c66df50a37db3 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+Date: Mon, 3 Dec 2012 12:56:33 +0100
+Subject: mac80211: introduce IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL
+
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+
+commit 5b632fe85ec82e5c43740b52e74c66df50a37db3 upstream.
+
+Commit f0425beda4d404a6e751439b562100b902ba9c98 "mac80211: retry sending
+failed BAR frames later instead of tearing down aggr" caused regression
+on rt2x00 hardware (connection hangs). This regression was fixed by
+commit be03d4a45c09ee5100d3aaaedd087f19bc20d01 "rt2x00: Don't let
+mac80211 send a BAR when an AMPDU subframe fails". But the latter
+commit caused yet another problem reported in
+https://bugzilla.kernel.org/show_bug.cgi?id=42828#c22
+
+After long discussion in this thread:
+http://mid.gmane.org/20121018075615.GA18212@redhat.com
+and testing various alternative solutions, which failed on one or other
+setup, we have no other good fix for the issues like just revert both
+mentioned earlier commits.
+
+To do not affect other hardware which benefit from commit
+f0425beda4d404a6e751439b562100b902ba9c98, instead of reverting it,
+introduce flag that when used will restore mac80211 behaviour before
+the commit.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka at redhat.com>
+[replaced link with mid.gmane.org that has message-id]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ include/net/mac80211.h | 5 +++++
+ net/mac80211/status.c | 6 +++++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1253,6 +1253,10 @@ struct ieee80211_tx_control {
+ * @IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF: Use the P2P Device address for any
+ * P2P Interface. This will be honoured even if more than one interface
+ * is supported.
++ *
++ * @IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL: On this hardware TX BA session
++ * should be tear down once BAR frame will not be acked.
++ *
+ */
+ enum ieee80211_hw_flags {
+ IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
+@@ -1281,6 +1285,7 @@ enum ieee80211_hw_flags {
+ IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23,
+ IEEE80211_HW_SCAN_WHILE_IDLE = 1<<24,
+ IEEE80211_HW_P2P_DEV_ADDR_FOR_INTF = 1<<25,
++ IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL = 1<<26,
+ };
+
+ /**
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -432,7 +432,11 @@ void ieee80211_tx_status(struct ieee8021
+ IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
+ IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
+
+- ieee80211_set_bar_pending(sta, tid, ssn);
++ if (local->hw.flags &
++ IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL)
++ ieee80211_stop_tx_ba_session(&sta->sta, tid);
++ else
++ ieee80211_set_bar_pending(sta, tid, ssn);
+ }
+ }
+
+From 6c653f66772c39c5e25db715bbd4730596fccd9e Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey at googlemail.com>
+Date: Sat, 22 Dec 2012 04:35:24 +0100
+Subject: carl9170: fix -EINVAL bailout during init with !CONFIG_MAC80211_MESH
+
+From: Christian Lamparter <chunkeey at googlemail.com>
+
+commit 6c653f66772c39c5e25db715bbd4730596fccd9e upstream.
+
+Sean reported that as of 3.7, his AR9170 device no longer works
+because the driver fails during initialization. He noted this
+is due to:
+"In carl9170/fw.c, ar->hw->wiphy is tagged with
+NL80211_IFTYPE_MESH_POINT support if the firmware has Content
+after Beacon Queuing. This is both in interface_modes and the
+only iface_combinations entry.
+
+If CONFIG_MAC80211_MESH is not set, ieee80211_register_hw
+removes NL80211_IFTYPE_MESH_POINT from interface_modes, but
+not iface_combinations.
+
+wiphy_register then checks to see if every interface type in
+every interface combination is in interface_modes.
+NL80211_IFTYPE_MESH_POINT was removed, so you get a WARN_ON
+warning and it returns -EINVAL, giving up."
+
+Unfortunately, the iface_combination (types) feature bitmap
+in ieee80211_iface_limit is part of a const member in the
+ieee80211_iface_combination struct. Hence, the MESH_POINT
+feature flag can't be masked by wiphy_register in the
+same way as interface_modes in ieee80211_register_hw.
+
+Reported-by: Sean Patrick Santos <quantheory at gmail.com>
+Signed-off-by: Christian Lamparter <chunkeey at googlemail.com>
+Tested-by: Sean Patrick Santos <quantheory at gmail.com>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/ath/carl9170/fw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/carl9170/fw.c
++++ b/drivers/net/wireless/ath/carl9170/fw.c
+@@ -341,8 +341,12 @@ static int carl9170_fw(struct ar9170 *ar
+ if (SUPP(CARL9170FW_WLANTX_CAB)) {
+ if_comb_types |=
+ BIT(NL80211_IFTYPE_AP) |
+- BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_P2P_GO);
++
++#ifdef CONFIG_MAC80211_MESH
++ if_comb_types |=
++ BIT(NL80211_IFTYPE_MESH_POINT);
++#endif /* CONFIG_MAC80211_MESH */
+ }
+ }
+
+From 9d2373420900a39f5212a3b289331aa3535b1000 Mon Sep 17 00:00:00 2001
+From: Stephan Gatzka <stephan.gatzka at gmail.com>
+Date: Wed, 28 Nov 2012 20:04:32 +0100
+Subject: firewire: net: Fix handling of fragmented multicast/broadcast packets.
+
+From: Stephan Gatzka <stephan.gatzka at gmail.com>
+
+commit 9d2373420900a39f5212a3b289331aa3535b1000 upstream.
+
+This patch fixes both the transmit and receive portion of sending
+fragmented mutlicast and broadcast packets.
+
+The transmit section was broken because the offset for INTFRAG and
+LASTFRAG packets were just miscalculated by IEEE1394_GASP_HDR_SIZE (which
+was reserved with skb_push() in fwnet_send_packet).
+
+The receive section was broken because in fwnet_incoming_packet is a call
+to fwnet_peer_find_by_node_id(). Called with generation == -1 it will
+not find a peer and the partial datagrams are associated to a peer.
+
+[Stefan R: The fix to use context->card->generation is not perfect.
+It relies on the IR tasklet which processes packets from the prior bus
+generation to run before the self-ID-complete worklet which sets the
+current card generation. Alas, there is no simple way of a race-free
+implementation. Let's do it this way for now.]
+
+Signed-off-by: Stephan Gatzka <stephan.gatzka at gmail.com>
+Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/firewire/net.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -861,8 +861,8 @@ static void fwnet_receive_broadcast(stru
+ if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
+ buf_ptr += 2;
+ length -= IEEE1394_GASP_HDR_SIZE;
+- fwnet_incoming_packet(dev, buf_ptr, length,
+- source_node_id, -1, true);
++ fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
++ context->card->generation, true);
+ }
+
+ packet.payload_length = dev->rcv_buffer_size;
+@@ -958,7 +958,12 @@ static void fwnet_transmit_packet_done(s
+ break;
+ }
+
+- skb_pull(skb, ptask->max_payload);
++ if (ptask->dest_node == IEEE1394_ALL_NODES) {
++ skb_pull(skb,
++ ptask->max_payload + IEEE1394_GASP_HDR_SIZE);
++ } else {
++ skb_pull(skb, ptask->max_payload);
++ }
+ if (ptask->outstanding_pkts > 1) {
+ fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
+ dg_size, fg_off, datagram_label);
+@@ -1062,7 +1067,7 @@ static int fwnet_send_packet(struct fwne
+ smp_rmb();
+ node_id = dev->card->node_id;
+
+- p = skb_push(ptask->skb, 8);
++ p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE);
+ put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p);
+ put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24
+ | RFC2734_SW_VERSION, &p[4]);
+From 3935e89505a1c3ab3f3b0c7ef0eae54124f48905 Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn at mork.no>
+Date: Wed, 19 Dec 2012 20:51:31 +0100
+Subject: watchdog: Fix disable/enable regression
+
+From: Bjørn Mork <bjorn at mork.no>
+
+commit 3935e89505a1c3ab3f3b0c7ef0eae54124f48905 upstream.
+
+Commit 8d4516904b39 ("watchdog: Fix CPU hotplug regression") causes an
+oops or hard lockup when doing
+
+ echo 0 > /proc/sys/kernel/nmi_watchdog
+ echo 1 > /proc/sys/kernel/nmi_watchdog
+
+and the kernel is booted with nmi_watchdog=1 (default)
+
+Running laptop-mode-tools and disconnecting/connecting AC power will
+cause this to trigger, making it a common failure scenario on laptops.
+
+Instead of bailing out of watchdog_disable() when !watchdog_enabled we
+can initialize the hrtimer regardless of watchdog_enabled status. This
+makes it safe to call watchdog_disable() in the nmi_watchdog=0 case,
+without the negative effect on the enabled => disabled => enabled case.
+
+All these tests pass with this patch:
+- nmi_watchdog=1
+ echo 0 > /proc/sys/kernel/nmi_watchdog
+ echo 1 > /proc/sys/kernel/nmi_watchdog
+
+- nmi_watchdog=0
+ echo 0 > /sys/devices/system/cpu/cpu1/online
+
+- nmi_watchdog=0
+ echo mem > /sys/power/state
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=51661
+
+Signed-off-by: Bjørn Mork <bjorn at mork.no>
+Cc: Norbert Warmuth <nwarmuth at t-online.de>
+Cc: Joseph Salisbury <joseph.salisbury at canonical.com>
+Cc: Thomas Gleixner <tglx at linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ kernel/watchdog.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -343,6 +343,10 @@ static void watchdog_enable(unsigned int
+ {
+ struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
+
++ /* kick off the timer for the hardlockup detector */
++ hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ hrtimer->function = watchdog_timer_fn;
++
+ if (!watchdog_enabled) {
+ kthread_park(current);
+ return;
+@@ -351,10 +355,6 @@ static void watchdog_enable(unsigned int
+ /* Enable the perf event */
+ watchdog_nmi_enable(cpu);
+
+- /* kick off the timer for the hardlockup detector */
+- hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+- hrtimer->function = watchdog_timer_fn;
+-
+ /* done here because hrtimer_start can only pin to smp_processor_id() */
+ hrtimer_start(hrtimer, ns_to_ktime(get_sample_period()),
+ HRTIMER_MODE_REL_PINNED);
+@@ -368,9 +368,6 @@ static void watchdog_disable(unsigned in
+ {
+ struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer);
+
+- if (!watchdog_enabled)
+- return;
+-
+ watchdog_set_prio(SCHED_NORMAL, 0);
+ hrtimer_cancel(hrtimer);
+ /* disable the perf event */
+From 72222be39afbd39c16eb180646b0ac44bb1ba460 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Wed, 28 Nov 2012 13:46:56 +0000
+Subject: ASoC: wm8994: Use the same DCS codes for all WM1811 variants
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit 72222be39afbd39c16eb180646b0ac44bb1ba460 upstream.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm8994.c | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -3839,20 +3839,8 @@ static int wm8994_codec_probe(struct snd
+ wm8994->hubs.no_cache_dac_hp_direct = true;
+ wm8994->fll_byp = true;
+
+- switch (control->cust_id) {
+- case 0:
+- case 2:
+- wm8994->hubs.dcs_codes_l = -9;
+- wm8994->hubs.dcs_codes_r = -7;
+- break;
+- case 1:
+- case 3:
+- wm8994->hubs.dcs_codes_l = -8;
+- wm8994->hubs.dcs_codes_r = -7;
+- break;
+- default:
+- break;
+- }
++ wm8994->hubs.dcs_codes_l = -9;
++ wm8994->hubs.dcs_codes_r = -7;
+
+ snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1,
+ WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN);
+From a3adb1432d7a3ad86bb17a1638e44414537e4118 Mon Sep 17 00:00:00 2001
+From: Lars-Peter Clausen <lars at metafoo.de>
+Date: Fri, 7 Dec 2012 18:30:51 +0100
+Subject: ASoC: sigmadsp: Fix endianness conversion issue
+
+From: Lars-Peter Clausen <lars at metafoo.de>
+
+commit a3adb1432d7a3ad86bb17a1638e44414537e4118 upstream.
+
+The 'addr' field of the sigma_action struct is stored as big endian in the
+firmware file.
+
+Signed-off-by: Lars-Peter Clausen <lars at metafoo.de>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/sigmadsp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/sigmadsp.c
++++ b/sound/soc/codecs/sigmadsp.c
+@@ -225,7 +225,7 @@ EXPORT_SYMBOL(process_sigma_firmware);
+ static int sigma_action_write_regmap(void *control_data,
+ const struct sigma_action *sa, size_t len)
+ {
+- return regmap_raw_write(control_data, le16_to_cpu(sa->addr),
++ return regmap_raw_write(control_data, be16_to_cpu(sa->addr),
+ sa->payload, len - 2);
+ }
+
+From f7ebaaeb0b4b97b20c1816f11884e7bfe610a2fa Mon Sep 17 00:00:00 2001
+From: Sangbeom Kim <sbkim73 at samsung.com>
+Date: Sat, 24 Nov 2012 11:13:28 +0900
+Subject: regulator: s2mps11: Fix ramp delay value shift operation
+
+From: Sangbeom Kim <sbkim73 at samsung.com>
+
+commit f7ebaaeb0b4b97b20c1816f11884e7bfe610a2fa upstream.
+
+This patch fix the abnormal ramp delay setting.
+The shift operation was wrong.
+
+Signed-off-by: Sangbeom Kim <sbkim73 at samsung.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/regulator/s2mps11.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/regulator/s2mps11.c
++++ b/drivers/regulator/s2mps11.c
+@@ -269,16 +269,16 @@ static __devinit int s2mps11_pmic_probe(
+
+ if (ramp_enable) {
+ if (s2mps11->buck2_ramp)
+- ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) >> 6;
++ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay2) << 6;
+ if (s2mps11->buck3_ramp || s2mps11->buck4_ramp)
+- ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) >> 4;
++ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay34) << 4;
+ sec_reg_write(iodev, S2MPS11_REG_RAMP, ramp_reg | ramp_enable);
+ }
+
+ ramp_reg &= 0x00;
+- ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) >> 6;
+- ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) >> 4;
+- ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) >> 2;
++ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay5) << 6;
++ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay16) << 4;
++ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay7810) << 2;
+ ramp_reg |= get_ramp_delay(s2mps11->ramp_delay9);
+ sec_reg_write(iodev, S2MPS11_REG_RAMP_BUCK, ramp_reg);
+
+From beecadea1b8d67f591b13f7099559f32f3fd601d Mon Sep 17 00:00:00 2001
+From: Xi Wang <xi.wang at gmail.com>
+Date: Fri, 16 Nov 2012 14:40:03 -0500
+Subject: SCSI: mvsas: fix undefined bit shift
+
+From: Xi Wang <xi.wang at gmail.com>
+
+commit beecadea1b8d67f591b13f7099559f32f3fd601d upstream.
+
+The macro bit(n) is defined as ((u32)1 << n), and thus it doesn't work
+with n >= 32, such as in mvs_94xx_assign_reg_set():
+
+ if (i >= 32) {
+ mvi->sata_reg_set |= bit(i);
+ ...
+ }
+
+The shift ((u32)1 << n) with n >= 32 also leads to undefined behavior.
+The result varies depending on the architecture.
+
+This patch changes bit(n) to do a 64-bit shift. It also simplifies
+mv_ffc64() using __ffs64(), since invoking ffz() with ~0 is undefined.
+
+Signed-off-by: Xi Wang <xi.wang at gmail.com>
+Acked-by: Xiangliang Yu <yuxiangl at marvell.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/mvsas/mv_94xx.h | 14 ++------------
+ drivers/scsi/mvsas/mv_sas.h | 2 +-
+ 2 files changed, 3 insertions(+), 13 deletions(-)
+
+--- a/drivers/scsi/mvsas/mv_94xx.h
++++ b/drivers/scsi/mvsas/mv_94xx.h
+@@ -258,21 +258,11 @@ enum sas_sata_phy_regs {
+ #define SPI_ADDR_VLD_94XX (1U << 1)
+ #define SPI_CTRL_SpiStart_94XX (1U << 0)
+
+-#define mv_ffc(x) ffz(x)
+-
+ static inline int
+ mv_ffc64(u64 v)
+ {
+- int i;
+- i = mv_ffc((u32)v);
+- if (i >= 0)
+- return i;
+- i = mv_ffc((u32)(v>>32));
+-
+- if (i != 0)
+- return 32 + i;
+-
+- return -1;
++ u64 x = ~v;
++ return x ? __ffs64(x) : -1;
+ }
+
+ #define r_reg_set_enable(i) \
+--- a/drivers/scsi/mvsas/mv_sas.h
++++ b/drivers/scsi/mvsas/mv_sas.h
+@@ -69,7 +69,7 @@ extern struct kmem_cache *mvs_task_list_
+ #define DEV_IS_EXPANDER(type) \
+ ((type == EDGE_DEV) || (type == FANOUT_DEV))
+
+-#define bit(n) ((u32)1 << n)
++#define bit(n) ((u64)1 << n)
+
+ #define for_each_phy(__lseq_mask, __mc, __lseq) \
+ for ((__mc) = (__lseq_mask), (__lseq) = 0; \
+From 072f19b4bea31cdd482d79f805413f2f9ac9e233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sasha.levin at oracle.com>
+Date: Thu, 15 Nov 2012 15:51:46 -0500
+Subject: SCSI: prevent stack buffer overflow in host_reset
+
+From: Sasha Levin <sasha.levin at oracle.com>
+
+commit 072f19b4bea31cdd482d79f805413f2f9ac9e233 upstream.
+
+store_host_reset() has tried to re-invent the wheel to compare sysfs strings.
+Unfortunately it did so poorly and never bothered to check the input from
+userspace before overwriting stack with it, so something simple as:
+
+echo "WoopsieWoopsie" >
+/sys/devices/pseudo_0/adapter0/host0/scsi_host/host0/host_reset
+
+would result in:
+
+[ 316.310101] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffff81f5bac7
+[ 316.310101]
+[ 316.320051] Pid: 6655, comm: sh Tainted: G W 3.7.0-rc5-next-20121114-sasha-00016-g5c9d68d-dirty #129
+[ 316.320051] Call Trace:
+[ 316.340058] pps pps0: PPS event at 1352918752.620355751
+[ 316.340062] pps pps0: capture assert seq #303
+[ 316.320051] [<ffffffff83b3856b>] panic+0xcd/0x1f4
+[ 316.320051] [<ffffffff81f5bac7>] ? store_host_reset+0xd7/0x100
+[ 316.320051] [<ffffffff8110b996>] __stack_chk_fail+0x16/0x20
+[ 316.320051] [<ffffffff81f5bac7>] store_host_reset+0xd7/0x100
+[ 316.320051] [<ffffffff81e55bb3>] dev_attr_store+0x13/0x30
+[ 316.320051] [<ffffffff812f7db1>] sysfs_write_file+0x101/0x170
+[ 316.320051] [<ffffffff8127acc8>] vfs_write+0xb8/0x180
+[ 316.320051] [<ffffffff8127ae80>] sys_write+0x50/0xa0
+[ 316.320051] [<ffffffff83c03418>] tracesys+0xe1/0xe6
+
+Fix this by uninventing whatever was going on there and just use sysfs_streq.
+
+Bug introduced by 29443691 ("[SCSI] scsi: Added support for adapter and
+firmware reset").
+
+[jejb: added necessary const to prevent compile warnings]
+Signed-off-by: Sasha Levin <sasha.levin at oracle.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/scsi_sysfs.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -247,11 +247,11 @@ show_shost_active_mode(struct device *de
+
+ static DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL);
+
+-static int check_reset_type(char *str)
++static int check_reset_type(const char *str)
+ {
+- if (strncmp(str, "adapter", 10) == 0)
++ if (sysfs_streq(str, "adapter"))
+ return SCSI_ADAPTER_RESET;
+- else if (strncmp(str, "firmware", 10) == 0)
++ else if (sysfs_streq(str, "firmware"))
+ return SCSI_FIRMWARE_RESET;
+ else
+ return 0;
+@@ -264,12 +264,9 @@ store_host_reset(struct device *dev, str
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct scsi_host_template *sht = shost->hostt;
+ int ret = -EINVAL;
+- char str[10];
+ int type;
+
+- sscanf(buf, "%s", str);
+- type = check_reset_type(str);
+-
++ type = check_reset_type(buf);
+ if (!type)
+ goto exit_store_host_reset;
+
+From 63ea923a97cb0d78efcbbd229950e101588f0ddb Mon Sep 17 00:00:00 2001
+From: Armen Baloyan <armen.baloyan at qlogic.com>
+Date: Wed, 21 Nov 2012 02:39:53 -0500
+Subject: SCSI: qla2xxx: Properly set result field of bsg_job reply structure for success and failure.
+
+From: Armen Baloyan <armen.baloyan at qlogic.com>
+
+commit 63ea923a97cb0d78efcbbd229950e101588f0ddb upstream.
+
+FC transport on receiving bsg_job submission failure, calls bsg_job->job_done()
+and sets the bsg_job->reply->result the returned value. In contrast, when the
+success code (0) is returned fc transport doesn't call bsg_job->job_done() and
+doesn't populate bsg_job->reply->result.
+
+Signed-off-by: Steve Hodgson <steve at purestorage.com>
+Signed-off-by: Armen Baloyan <armen.baloyan at qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap at qlogic.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_bsg.c | 65 +++++++++++++++--------------------------
+ 1 file changed, 24 insertions(+), 41 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -219,7 +219,8 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_
+ break;
+ }
+ exit_fcp_prio_cfg:
+- bsg_job->job_done(bsg_job);
++ if (!ret)
++ bsg_job->job_done(bsg_job);
+ return ret;
+ }
+
+@@ -741,7 +742,6 @@ qla2x00_process_loopback(struct fc_bsg_j
+ if (qla81xx_get_port_config(vha, config)) {
+ ql_log(ql_log_warn, vha, 0x701f,
+ "Get port config failed.\n");
+- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = -EPERM;
+ goto done_free_dma_req;
+ }
+@@ -761,7 +761,6 @@ qla2x00_process_loopback(struct fc_bsg_j
+ new_config, elreq.options);
+
+ if (rval) {
+- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = -EPERM;
+ goto done_free_dma_req;
+ }
+@@ -795,7 +794,6 @@ qla2x00_process_loopback(struct fc_bsg_j
+ "MPI reset failed.\n");
+ }
+
+- bsg_job->reply->result = (DID_ERROR << 16);
+ rval = -EIO;
+ goto done_free_dma_req;
+ }
+@@ -812,33 +810,25 @@ qla2x00_process_loopback(struct fc_bsg_j
+ ql_log(ql_log_warn, vha, 0x702c,
+ "Vendor request %s failed.\n", type);
+
+- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+- sizeof(struct fc_bsg_reply);
+-
+- memcpy(fw_sts_ptr, response, sizeof(response));
+- fw_sts_ptr += sizeof(response);
+- *fw_sts_ptr = command_sent;
+ rval = 0;
+ bsg_job->reply->result = (DID_ERROR << 16);
++ bsg_job->reply->reply_payload_rcv_len = 0;
+ } else {
+ ql_dbg(ql_dbg_user, vha, 0x702d,
+ "Vendor request %s completed.\n", type);
+-
+- bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
+- sizeof(response) + sizeof(uint8_t);
+- bsg_job->reply->reply_payload_rcv_len =
+- bsg_job->reply_payload.payload_len;
+- fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
+- sizeof(struct fc_bsg_reply);
+- memcpy(fw_sts_ptr, response, sizeof(response));
+- fw_sts_ptr += sizeof(response);
+- *fw_sts_ptr = command_sent;
+- bsg_job->reply->result = DID_OK;
++ bsg_job->reply->result = (DID_OK << 16);
+ sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
+ bsg_job->reply_payload.sg_cnt, rsp_data,
+ rsp_data_len);
+ }
+- bsg_job->job_done(bsg_job);
++
++ bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
++ sizeof(response) + sizeof(uint8_t);
++ fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
++ sizeof(struct fc_bsg_reply);
++ memcpy(fw_sts_ptr, response, sizeof(response));
++ fw_sts_ptr += sizeof(response);
++ *fw_sts_ptr = command_sent;
+
+ dma_free_coherent(&ha->pdev->dev, rsp_data_len,
+ rsp_data, rsp_data_dma);
+@@ -853,6 +843,8 @@ done_unmap_req_sg:
+ dma_unmap_sg(&ha->pdev->dev,
+ bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
++ if (!rval)
++ bsg_job->job_done(bsg_job);
+ return rval;
+ }
+
+@@ -877,16 +869,15 @@ qla84xx_reset(struct fc_bsg_job *bsg_job
+ if (rval) {
+ ql_log(ql_log_warn, vha, 0x7030,
+ "Vendor request 84xx reset failed.\n");
+- rval = 0;
+- bsg_job->reply->result = (DID_ERROR << 16);
++ rval = (DID_ERROR << 16);
+
+ } else {
+ ql_dbg(ql_dbg_user, vha, 0x7031,
+ "Vendor request 84xx reset completed.\n");
+ bsg_job->reply->result = DID_OK;
++ bsg_job->job_done(bsg_job);
+ }
+
+- bsg_job->job_done(bsg_job);
+ return rval;
+ }
+
+@@ -976,8 +967,7 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_
+ ql_log(ql_log_warn, vha, 0x7037,
+ "Vendor request 84xx updatefw failed.\n");
+
+- rval = 0;
+- bsg_job->reply->result = (DID_ERROR << 16);
++ rval = (DID_ERROR << 16);
+ } else {
+ ql_dbg(ql_dbg_user, vha, 0x7038,
+ "Vendor request 84xx updatefw completed.\n");
+@@ -986,7 +976,6 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_
+ bsg_job->reply->result = DID_OK;
+ }
+
+- bsg_job->job_done(bsg_job);
+ dma_pool_free(ha->s_dma_pool, mn, mn_dma);
+
+ done_free_fw_buf:
+@@ -996,6 +985,8 @@ done_unmap_sg:
+ dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
+ bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
+
++ if (!rval)
++ bsg_job->job_done(bsg_job);
+ return rval;
+ }
+
+@@ -1163,8 +1154,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_
+ ql_log(ql_log_warn, vha, 0x7043,
+ "Vendor request 84xx mgmt failed.\n");
+
+- rval = 0;
+- bsg_job->reply->result = (DID_ERROR << 16);
++ rval = (DID_ERROR << 16);
+
+ } else {
+ ql_dbg(ql_dbg_user, vha, 0x7044,
+@@ -1184,8 +1174,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_
+ }
+ }
+
+- bsg_job->job_done(bsg_job);
+-
+ done_unmap_sg:
+ if (mgmt_b)
+ dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
+@@ -1200,6 +1188,8 @@ done_unmap_sg:
+ exit_mgmt:
+ dma_pool_free(ha->s_dma_pool, mn, mn_dma);
+
++ if (!rval)
++ bsg_job->job_done(bsg_job);
+ return rval;
+ }
+
+@@ -1276,9 +1266,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job
+ fcport->port_name[3], fcport->port_name[4],
+ fcport->port_name[5], fcport->port_name[6],
+ fcport->port_name[7], rval, fcport->fp_speed, mb[0], mb[1]);
+- rval = 0;
+- bsg_job->reply->result = (DID_ERROR << 16);
+-
++ rval = (DID_ERROR << 16);
+ } else {
+ if (!port_param->mode) {
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
+@@ -1292,9 +1280,9 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job
+ }
+
+ bsg_job->reply->result = DID_OK;
++ bsg_job->job_done(bsg_job);
+ }
+
+- bsg_job->job_done(bsg_job);
+ return rval;
+ }
+
+@@ -1887,8 +1875,6 @@ qla2x00_process_vendor_specific(struct f
+ return qla24xx_process_bidir_cmd(bsg_job);
+
+ default:
+- bsg_job->reply->result = (DID_ERROR << 16);
+- bsg_job->job_done(bsg_job);
+ return -ENOSYS;
+ }
+ }
+@@ -1919,8 +1905,6 @@ qla24xx_bsg_request(struct fc_bsg_job *b
+ ql_dbg(ql_dbg_user, vha, 0x709f,
+ "BSG: ISP abort active/needed -- cmd=%d.\n",
+ bsg_job->request->msgcode);
+- bsg_job->reply->result = (DID_ERROR << 16);
+- bsg_job->job_done(bsg_job);
+ return -EBUSY;
+ }
+
+@@ -1943,7 +1927,6 @@ qla24xx_bsg_request(struct fc_bsg_job *b
+ case FC_BSG_RPT_CT:
+ default:
+ ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
+- bsg_job->reply->result = ret;
+ break;
+ }
+ return ret;
+From a394aac88506159e047630fc90dc2242568382d8 Mon Sep 17 00:00:00 2001
+From: David Jeffery <djeffery at redhat.com>
+Date: Wed, 21 Nov 2012 02:39:54 -0500
+Subject: SCSI: qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically.
+
+From: David Jeffery <djeffery at redhat.com>
+
+commit a394aac88506159e047630fc90dc2242568382d8 upstream.
+
+When the qla2xxx driver loses access to multiple, remote ports, there is a race
+condition which can occur which will keep the request stuck on a scsi request
+queue indefinitely.
+
+This bad state occurred do to a race condition with how the FCPORT_UPDATE_NEEDED
+bit is set in qla2x00_schedule_rport_del(), and how it is cleared in
+qla2x00_do_dpc(). The problem port has its drport pointer set, but it has never
+been processed by the driver to inform the fc transport that the port has been
+lost. qla2x00_schedule_rport_del() sets drport, and then sets the
+FCPORT_UPDATE_NEEDED bit. In qla2x00_do_dpc(), the port lists are walked and
+any drport pointer is handled and the fc transport informed of the port loss,
+then the FCPORT_UPDATE_NEEDED bit is cleared. This leaves a race where the
+dpc thread is processing one port removal, another port removal is marked
+with a call to qla2x00_schedule_rport_del(), and the dpc thread clears the
+bit for both removals, even though only the first removal was actually
+handled. Until another event occurs to set FCPORT_UPDATE_NEEDED, the later
+port removal is never finished and qla2xxx stays in a bad state which causes
+requests to become stuck on request queues.
+
+This patch updates the driver to test and clear FCPORT_UPDATE_NEEDED
+atomically. This ensures the port state changes are processed and not lost.
+
+Signed-off-by: David Jeffery <djeffery at redhat.com>
+Signed-off-by: Chad Dupuis <chad.dupuis at qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap at qlogic.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_os.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -4505,9 +4505,9 @@ qla2x00_do_dpc(void *data)
+ "ISP abort end.\n");
+ }
+
+- if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) {
++ if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
++ &base_vha->dpc_flags)) {
+ qla2x00_update_fcports(base_vha);
+- clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
+ }
+
+ if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) {
+From 220d36b4c2d96446e88d561714829ec5801b4fc7 Mon Sep 17 00:00:00 2001
+From: Giridhar Malavali <giridhar.malavali at qlogic.com>
+Date: Wed, 21 Nov 2012 02:39:55 -0500
+Subject: SCSI: qla2xxx: Change in setting UNLOADING flag and FC vports logout sequence while unloading qla2xxx driver.
+
+From: Giridhar Malavali <giridhar.malavali at qlogic.com>
+
+commit 220d36b4c2d96446e88d561714829ec5801b4fc7 upstream.
+
+Signed-off-by: Giridhar Malavali <giridhar.malavali at qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap at qlogic.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_attr.c | 3 +--
+ drivers/scsi/qla2xxx/qla_os.c | 3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_attr.c
++++ b/drivers/scsi/qla2xxx/qla_attr.c
+@@ -1615,8 +1615,7 @@ qla2x00_terminate_rport_io(struct fc_rpo
+ * At this point all fcport's software-states are cleared. Perform any
+ * final cleanup of firmware resources (PCBs and XCBs).
+ */
+- if (fcport->loop_id != FC_NO_LOOP_ID &&
+- !test_bit(UNLOADING, &fcport->vha->dpc_flags)) {
++ if (fcport->loop_id != FC_NO_LOOP_ID) {
+ if (IS_FWI2_CAPABLE(fcport->vha->hw))
+ fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
+ fcport->loop_id, fcport->d_id.b.domain,
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -2755,6 +2755,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
+
+ ha->flags.host_shutting_down = 1;
+
++ set_bit(UNLOADING, &base_vha->dpc_flags);
+ mutex_lock(&ha->vport_lock);
+ while (ha->cur_vport_count) {
+ struct Scsi_Host *scsi_host;
+@@ -2784,8 +2785,6 @@ qla2x00_remove_one(struct pci_dev *pdev)
+ "Error while clearing DRV-Presence.\n");
+ }
+
+- set_bit(UNLOADING, &base_vha->dpc_flags);
+-
+ qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
+ qla2x00_dfs_remove(base_vha);
+From 9bceab4e08c5e329e9def7fe1cab41c467236517 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve at purestorage.com>
+Date: Wed, 21 Nov 2012 02:39:56 -0500
+Subject: SCSI: qla2xxx: Free rsp_data even on error in qla2x00_process_loopback()
+
+From: Steve Hodgson <steve at purestorage.com>
+
+commit 9bceab4e08c5e329e9def7fe1cab41c467236517 upstream.
+
+Signed-off-by: Steve Hodgson <steve at purestorage.com>
+Signed-off-by: Armen Baloyan <armen.baloyan at qlogic.com>
+Signed-off-by: Saurav Kashyap <saurav.kashyap at qlogic.com>
+Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_bsg.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_bsg.c
++++ b/drivers/scsi/qla2xxx/qla_bsg.c
+@@ -743,7 +743,7 @@ qla2x00_process_loopback(struct fc_bsg_j
+ ql_log(ql_log_warn, vha, 0x701f,
+ "Get port config failed.\n");
+ rval = -EPERM;
+- goto done_free_dma_req;
++ goto done_free_dma_rsp;
+ }
+
+ ql_dbg(ql_dbg_user, vha, 0x70c0,
+@@ -762,7 +762,7 @@ qla2x00_process_loopback(struct fc_bsg_j
+
+ if (rval) {
+ rval = -EPERM;
+- goto done_free_dma_req;
++ goto done_free_dma_rsp;
+ }
+
+ type = "FC_BSG_HST_VENDOR_LOOPBACK";
+@@ -795,7 +795,7 @@ qla2x00_process_loopback(struct fc_bsg_j
+ }
+
+ rval = -EIO;
+- goto done_free_dma_req;
++ goto done_free_dma_rsp;
+ }
+ } else {
+ type = "FC_BSG_HST_VENDOR_LOOPBACK";
+@@ -830,6 +830,7 @@ qla2x00_process_loopback(struct fc_bsg_j
+ fw_sts_ptr += sizeof(response);
+ *fw_sts_ptr = command_sent;
+
++done_free_dma_rsp:
+ dma_free_coherent(&ha->pdev->dev, rsp_data_len,
+ rsp_data, rsp_data_dma);
+ done_free_dma_req:
+From 64c13330a38935120501b19c97a3e6095747c7a1 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve at purestorage.com>
+Date: Mon, 5 Nov 2012 18:02:41 -0800
+Subject: iscsi-target: Fix bug in handling of ExpStatSN ACK during u32 wrap-around
+
+From: Steve Hodgson <steve at purestorage.com>
+
+commit 64c13330a38935120501b19c97a3e6095747c7a1 upstream.
+
+This patch fixes a bug in the hanlding of initiator provided ExpStatSN and
+individual iscsi_cmd->stat_sn comparision during iscsi_conn->stat_sn
+wrap-around within iscsit_ack_from_expstatsn() code.
+
+This bug would manifest itself as iscsi_cmd descriptors not being Acked
+by a lower ExpStatSn, causing them to be leaked until an iSCSI connection
+or session reinstatement event occurs to release all commands.
+
+Also fix up two other uses of incorrect CmdSN SNA comparison to use wrapper
+usage from include/scsi/iscsi_proto.h.
+
+Signed-off-by: Steve Hodgson <steve at purestorage.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 2 +-
+ drivers/target/iscsi/iscsi_target_erl2.c | 2 +-
+ drivers/target/iscsi/iscsi_target_tmr.c | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -735,7 +735,7 @@ static void iscsit_ack_from_expstatsn(st
+ list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
+ spin_lock(&cmd->istate_lock);
+ if ((cmd->i_state == ISTATE_SENT_STATUS) &&
+- (cmd->stat_sn < exp_statsn)) {
++ iscsi_sna_lt(cmd->stat_sn, exp_statsn)) {
+ cmd->i_state = ISTATE_REMOVE;
+ spin_unlock(&cmd->istate_lock);
+ iscsit_add_cmd_to_immediate_queue(cmd, conn,
+--- a/drivers/target/iscsi/iscsi_target_erl2.c
++++ b/drivers/target/iscsi/iscsi_target_erl2.c
+@@ -372,7 +372,7 @@ int iscsit_prepare_cmds_for_realligance(
+ * made generic here.
+ */
+ if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd &&
+- (cmd->cmd_sn >= conn->sess->exp_cmd_sn)) {
++ iscsi_sna_gte(cmd->stat_sn, conn->sess->exp_cmd_sn)) {
+ list_del(&cmd->i_conn_node);
+ spin_unlock_bh(&conn->cmd_lock);
+ iscsit_free_cmd(cmd);
+--- a/drivers/target/iscsi/iscsi_target_tmr.c
++++ b/drivers/target/iscsi/iscsi_target_tmr.c
+@@ -50,8 +50,8 @@ u8 iscsit_tmr_abort_task(
+ if (!ref_cmd) {
+ pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
+ " %hu.\n", hdr->rtt, conn->cid);
+- return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn &&
+- be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ?
++ return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) &&
++ iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ?
+ ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
+ }
+ if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
+From 1c5c12c666fda27c7c494b34934a0a0631a48130 Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland at purestorage.com>
+Date: Mon, 5 Nov 2012 18:02:42 -0800
+Subject: iscsi-target: Always send a response before terminating iSCSI connection
+
+From: Roland Dreier <roland at purestorage.com>
+
+commit 1c5c12c666fda27c7c494b34934a0a0631a48130 upstream.
+
+There are some cases, for example when the initiator sends an
+out-of-bounds ErrorRecoveryLevel value, where the iSCSI target
+terminates the connection without sending back any error. Audit the
+login path and add appropriate iscsit_tx_login_rsp() calls to make
+sure this doesn't happen.
+
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target_login.c | 8 ++++----
+ drivers/target/iscsi/iscsi_target_nego.c | 10 ++++++++--
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -127,13 +127,13 @@ int iscsi_check_for_session_reinstatemen
+
+ initiatorname_param = iscsi_find_param_from_key(
+ INITIATORNAME, conn->param_list);
+- if (!initiatorname_param)
+- return -1;
+-
+ sessiontype_param = iscsi_find_param_from_key(
+ SESSIONTYPE, conn->param_list);
+- if (!sessiontype_param)
++ if (!initiatorname_param || !sessiontype_param) {
++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
++ ISCSI_LOGIN_STATUS_MISSING_FIELDS);
+ return -1;
++ }
+
+ sessiontype = (strncmp(sessiontype_param->value, NORMAL, 6)) ? 1 : 0;
+
+--- a/drivers/target/iscsi/iscsi_target_nego.c
++++ b/drivers/target/iscsi/iscsi_target_nego.c
+@@ -620,8 +620,11 @@ static int iscsi_target_handle_csg_one(s
+ login->req_buf,
+ payload_length,
+ conn);
+- if (ret < 0)
++ if (ret < 0) {
++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
++ ISCSI_LOGIN_STATUS_INIT_ERR);
+ return -1;
++ }
+
+ if (login->first_request)
+ if (iscsi_target_check_first_request(conn, login) < 0)
+@@ -636,8 +639,11 @@ static int iscsi_target_handle_csg_one(s
+ login->rsp_buf,
+ &login->rsp_length,
+ conn->param_list);
+- if (ret < 0)
++ if (ret < 0) {
++ iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
++ ISCSI_LOGIN_STATUS_INIT_ERR);
+ return -1;
++ }
+
+ if (!login->auth_complete &&
+ ISCSI_TPG_ATTRIB(ISCSI_TPG_C(conn))->authentication) {
+From 3c989d7603872bf878840f7ce3ea49b73bea4c6c Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
+Date: Fri, 23 Nov 2012 12:07:39 +0800
+Subject: iscsit: use GFP_ATOMIC under spin lock
+
+From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
+
+commit 3c989d7603872bf878840f7ce3ea49b73bea4c6c upstream.
+
+The function iscsit_build_conn_drop_async_message() is called
+from iscsit_close_connection() with spin lock 'sess->conn_lock'
+held, so we should use GFP_ATOMIC instead of GFP_KERNEL.
+
+Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -2360,7 +2360,7 @@ static void iscsit_build_conn_drop_async
+ if (!conn_p)
+ return;
+
+- cmd = iscsit_allocate_cmd(conn_p, GFP_KERNEL);
++ cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC);
+ if (!cmd) {
+ iscsit_dec_conn_usage_count(conn_p);
+ return;
+From 06e97b489006f28e23bb028febfa1c01c266d676 Mon Sep 17 00:00:00 2001
+From: Steve Hodgson <steve at purestorage.com>
+Date: Fri, 16 Nov 2012 08:06:17 -0800
+Subject: qla2xxx: Look up LUN for abort requests
+
+From: Steve Hodgson <steve at purestorage.com>
+
+commit 06e97b489006f28e23bb028febfa1c01c266d676 upstream.
+
+Search through the list of pending commands on the session list to find
+the command the initiator is actually aborting, so that we can pass the
+correct LUN to the core TMR handling code.
+
+(nab: Allow abort requests to work to LUN=0 with mainline target code)
+
+Signed-off-by: Steve Hodgson <steve at purestorage.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: Nicholas Bellinger <nab at risingtidesystems.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_target.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -1264,8 +1264,27 @@ static int __qlt_24xx_handle_abts(struct
+ struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess)
+ {
+ struct qla_hw_data *ha = vha->hw;
++ struct se_session *se_sess = sess->se_sess;
+ struct qla_tgt_mgmt_cmd *mcmd;
++ struct se_cmd *se_cmd;
++ u32 lun = 0;
+ int rc;
++ bool found_lun = false;
++
++ spin_lock(&se_sess->sess_cmd_lock);
++ list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
++ struct qla_tgt_cmd *cmd =
++ container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
++ if (cmd->tag == abts->exchange_addr_to_abort) {
++ lun = cmd->unpacked_lun;
++ found_lun = true;
++ break;
++ }
++ }
++ spin_unlock(&se_sess->sess_cmd_lock);
++
++ if (!found_lun)
++ return -ENOENT;
+
+ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
+ "qla_target(%d): task abort (tag=%d)\n",
+@@ -1283,7 +1302,7 @@ static int __qlt_24xx_handle_abts(struct
+ mcmd->sess = sess;
+ memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));
+
+- rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, TMR_ABORT_TASK,
++ rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, TMR_ABORT_TASK,
+ abts->exchange_addr_to_abort);
+ if (rc != 0) {
+ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
+From 3100d49d3cd236443faae9d81137c81b22d36003 Mon Sep 17 00:00:00 2001
+From: Mikael Pettersson <mikpe at it.uu.se>
+Date: Sun, 16 Sep 2012 20:53:43 +0200
+Subject: sata_promise: fix hardreset lockdep error
+
+From: Mikael Pettersson <mikpe at it.uu.se>
+
+commit 3100d49d3cd236443faae9d81137c81b22d36003 upstream.
+
+sata_promise's pdc_hard_reset_port() needs to serialize because it
+flips a port-specific bit in controller register that's shared by
+all ports. The code takes the ata host lock for this, but that's
+broken because an interrupt may arrive on our irq during the hard
+reset sequence, and that too will take the ata host lock. With
+lockdep enabled a big nasty warning is seen.
+
+Fixed by adding private state to the ata host structure, containing
+a second lock used only for serializing the hard reset sequences.
+This eliminated the lockdep warnings both on my test rig and on
+the original reporter's machine.
+
+Signed-off-by: Mikael Pettersson <mikpe at it.uu.se>
+Tested-by: Adko Branil <adkobranil at yahoo.com>
+Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/ata/sata_promise.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/sata_promise.c
++++ b/drivers/ata/sata_promise.c
+@@ -147,6 +147,10 @@ struct pdc_port_priv {
+ dma_addr_t pkt_dma;
+ };
+
++struct pdc_host_priv {
++ spinlock_t hard_reset_lock;
++};
++
+ static int pdc_sata_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
+ static int pdc_sata_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
+ static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+@@ -801,9 +805,10 @@ static void pdc_hard_reset_port(struct a
+ void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+ void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1;
+ unsigned int ata_no = pdc_ata_port_to_ata_no(ap);
++ struct pdc_host_priv *hpriv = ap->host->private_data;
+ u8 tmp;
+
+- spin_lock(&ap->host->lock);
++ spin_lock(&hpriv->hard_reset_lock);
+
+ tmp = readb(pcictl_b1_mmio);
+ tmp &= ~(0x10 << ata_no);
+@@ -814,7 +819,7 @@ static void pdc_hard_reset_port(struct a
+ writeb(tmp, pcictl_b1_mmio);
+ readb(pcictl_b1_mmio); /* flush */
+
+- spin_unlock(&ap->host->lock);
++ spin_unlock(&hpriv->hard_reset_lock);
+ }
+
+ static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
+@@ -1182,6 +1187,7 @@ static int pdc_ata_init_one(struct pci_d
+ const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
+ const struct ata_port_info *ppi[PDC_MAX_PORTS];
+ struct ata_host *host;
++ struct pdc_host_priv *hpriv;
+ void __iomem *host_mmio;
+ int n_ports, i, rc;
+ int is_sataii_tx4;
+@@ -1218,6 +1224,11 @@ static int pdc_ata_init_one(struct pci_d
+ dev_err(&pdev->dev, "failed to allocate host\n");
+ return -ENOMEM;
+ }
++ hpriv = devm_kzalloc(&pdev->dev, sizeof *hpriv, GFP_KERNEL);
++ if (!hpriv)
++ return -ENOMEM;
++ spin_lock_init(&hpriv->hard_reset_lock);
++ host->private_data = hpriv;
+ host->iomap = pcim_iomap_table(pdev);
+
+ is_sataii_tx4 = pdc_is_sataii_tx4(pi->flags);
+From dcbeec264d73b7228ffdfe767eab69b2353099b1 Mon Sep 17 00:00:00 2001
+From: Mattia Dongili <malattia at linux.it>
+Date: Fri, 21 Dec 2012 07:21:09 +0900
+Subject: sony-laptop: fix SNC buffer calls when SN06 returns Integers
+
+From: Mattia Dongili <malattia at linux.it>
+
+commit dcbeec264d73b7228ffdfe767eab69b2353099b1 upstream.
+
+SN06 in some cases returns an Integer instead of a buffer. While the
+code handling the return value was trying to cope with the difference,
+the memcpy call was not making any difference between the two types of
+acpi_object union. This regression was introduced in 3.5.
+While there also rework the return value logic to improve readability.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=48671
+Cc: Fabrizio Narni <shibotto at gmail.com>
+Cc: <mus.svz at gmail.com>
+Signed-off-by: Mattia Dongili <malattia at linux.it>
+Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/platform/x86/sony-laptop.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/platform/x86/sony-laptop.c
++++ b/drivers/platform/x86/sony-laptop.c
+@@ -786,28 +786,29 @@ static int sony_nc_int_call(acpi_handle
+ static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value,
+ void *buffer, size_t buflen)
+ {
++ int ret = 0;
+ size_t len = len;
+ union acpi_object *object = __call_snc_method(handle, name, value);
+
+ if (!object)
+ return -EINVAL;
+
+- if (object->type == ACPI_TYPE_BUFFER)
++ if (object->type == ACPI_TYPE_BUFFER) {
+ len = MIN(buflen, object->buffer.length);
++ memcpy(buffer, object->buffer.pointer, len);
+
+- else if (object->type == ACPI_TYPE_INTEGER)
++ } else if (object->type == ACPI_TYPE_INTEGER) {
+ len = MIN(buflen, sizeof(object->integer.value));
++ memcpy(buffer, &object->integer.value, len);
+
+- else {
++ } else {
+ pr_warn("Invalid acpi_object: expected 0x%x got 0x%x\n",
+ ACPI_TYPE_BUFFER, object->type);
+- kfree(object);
+- return -EINVAL;
++ ret = -EINVAL;
+ }
+
+- memcpy(buffer, object->buffer.pointer, len);
+ kfree(object);
+- return 0;
++ return ret;
+ }
+
+ struct sony_nc_handles {
+From ceb7decb366591e9b67d70832e07f5d240572a3d Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm at dev.mellanox.co.il>
+Date: Tue, 27 Nov 2012 16:24:29 +0000
+Subject: IB/mlx4: Fix spinlock order to avoid lockdep warnings
+
+From: Jack Morgenstein <jackm at dev.mellanox.co.il>
+
+commit ceb7decb366591e9b67d70832e07f5d240572a3d upstream.
+
+lockdep warns about taking a hard-irq-unsafe lock (sriov->id_map_lock)
+inside a hard-irq-safe lock (sriov->going_down_lock).
+
+Since id_map_lock is never taken in the interrupt context, we can
+simply reverse the order of taking the two spinlocks, thus avoiding
+the warning and the depencency.
+
+Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>
+Signed-off-by: Or Gerlitz <ogerlitz at mellanox.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/mlx4/cm.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx4/cm.c
++++ b/drivers/infiniband/hw/mlx4/cm.c
+@@ -268,15 +268,15 @@ static void schedule_delayed(struct ib_d
+ struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov;
+ unsigned long flags;
+
+- spin_lock_irqsave(&sriov->going_down_lock, flags);
+ spin_lock(&sriov->id_map_lock);
++ spin_lock_irqsave(&sriov->going_down_lock, flags);
+ /*make sure that there is no schedule inside the scheduled work.*/
+ if (!sriov->is_going_down) {
+ id->scheduled_delete = 1;
+ schedule_delayed_work(&id->timeout, CM_CLEANUP_CACHE_TIMEOUT);
+ }
+- spin_unlock(&sriov->id_map_lock);
+ spin_unlock_irqrestore(&sriov->going_down_lock, flags);
++ spin_unlock(&sriov->id_map_lock);
+ }
+
+ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id,
+From 311f813a2daefcba03f706a692fe0c67888d7622 Mon Sep 17 00:00:00 2001
+From: Jack Morgenstein <jackm at dev.mellanox.co.il>
+Date: Tue, 27 Nov 2012 16:24:30 +0000
+Subject: mlx4_core: Fix potential deadlock in mlx4_eq_int()
+
+From: Jack Morgenstein <jackm at dev.mellanox.co.il>
+
+commit 311f813a2daefcba03f706a692fe0c67888d7622 upstream.
+
+The slave_state_lock spinlock is used in both interrupt context and
+process context, hence irq locking must be used. Found by lockdep.
+
+Signed-off-by: Jack Morgenstein <jackm at dev.mellanox.co.il>
+Signed-off-by: Or Gerlitz <ogerlitz at mellanox.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +++++----
+ drivers/net/ethernet/mellanox/mlx4/eq.c | 10 ++++++----
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
++++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
+@@ -1498,6 +1498,7 @@ static void mlx4_master_do_cmd(struct ml
+ u32 reply;
+ u8 is_going_down = 0;
+ int i;
++ unsigned long flags;
+
+ slave_state[slave].comm_toggle ^= 1;
+ reply = (u32) slave_state[slave].comm_toggle << 31;
+@@ -1576,12 +1577,12 @@ static void mlx4_master_do_cmd(struct ml
+ mlx4_warn(dev, "Bad comm cmd:%d from slave:%d\n", cmd, slave);
+ goto reset_slave;
+ }
+- spin_lock(&priv->mfunc.master.slave_state_lock);
++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags);
+ if (!slave_state[slave].is_slave_going_down)
+ slave_state[slave].last_cmd = cmd;
+ else
+ is_going_down = 1;
+- spin_unlock(&priv->mfunc.master.slave_state_lock);
++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
+ if (is_going_down) {
+ mlx4_warn(dev, "Slave is going down aborting command(%d)"
+ " executing from slave:%d\n",
+@@ -1597,10 +1598,10 @@ static void mlx4_master_do_cmd(struct ml
+ reset_slave:
+ /* cleanup any slave resources */
+ mlx4_delete_all_resources_for_slave(dev, slave);
+- spin_lock(&priv->mfunc.master.slave_state_lock);
++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags);
+ if (!slave_state[slave].is_slave_going_down)
+ slave_state[slave].last_cmd = MLX4_COMM_CMD_RESET;
+- spin_unlock(&priv->mfunc.master.slave_state_lock);
++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
+ /*with slave in the middle of flr, no need to clean resources again.*/
+ inform_slave_state:
+ memset(&slave_state[slave].event_eq, 0,
+--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
+@@ -401,6 +401,7 @@ void mlx4_master_handle_slave_flr(struct
+ struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
+ int i;
+ int err;
++ unsigned long flags;
+
+ mlx4_dbg(dev, "mlx4_handle_slave_flr\n");
+
+@@ -412,10 +413,10 @@ void mlx4_master_handle_slave_flr(struct
+
+ mlx4_delete_all_resources_for_slave(dev, i);
+ /*return the slave to running mode*/
+- spin_lock(&priv->mfunc.master.slave_state_lock);
++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags);
+ slave_state[i].last_cmd = MLX4_COMM_CMD_RESET;
+ slave_state[i].is_slave_going_down = 0;
+- spin_unlock(&priv->mfunc.master.slave_state_lock);
++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
+ /*notify the FW:*/
+ err = mlx4_cmd(dev, 0, i, 0, MLX4_CMD_INFORM_FLR_DONE,
+ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+@@ -440,6 +441,7 @@ static int mlx4_eq_int(struct mlx4_dev *
+ u8 update_slave_state;
+ int i;
+ enum slave_port_gen_event gen_event;
++ unsigned long flags;
+
+ while ((eqe = next_eqe_sw(eq))) {
+ /*
+@@ -647,13 +649,13 @@ static int mlx4_eq_int(struct mlx4_dev *
+ } else
+ update_slave_state = 1;
+
+- spin_lock(&priv->mfunc.master.slave_state_lock);
++ spin_lock_irqsave(&priv->mfunc.master.slave_state_lock, flags);
+ if (update_slave_state) {
+ priv->mfunc.master.slave_state[flr_slave].active = false;
+ priv->mfunc.master.slave_state[flr_slave].last_cmd = MLX4_COMM_CMD_FLR;
+ priv->mfunc.master.slave_state[flr_slave].is_slave_going_down = 1;
+ }
+- spin_unlock(&priv->mfunc.master.slave_state_lock);
++ spin_unlock_irqrestore(&priv->mfunc.master.slave_state_lock, flags);
+ queue_work(priv->mfunc.master.comm_wq,
+ &priv->mfunc.master.slave_flr_event_work);
+ break;
+From b042e47491ba5f487601b5141a3f1d8582304170 Mon Sep 17 00:00:00 2001
+From: Maxime Bizon <mbizon at freebox.fr>
+Date: Mon, 22 Oct 2012 11:19:28 +0200
+Subject: pstore/ram: Fix undefined usage of rounddown_pow_of_two(0)
+
+From: Maxime Bizon <mbizon at freebox.fr>
+
+commit b042e47491ba5f487601b5141a3f1d8582304170 upstream.
+
+record_size / console_size / ftrace_size can be 0 (this is how you disable
+the feature), but rounddown_pow_of_two(0) is undefined. As suggested by
+Kees Cook, use !is_power_of_2() as a condition to call
+rounddown_pow_of_two and avoid its undefined behavior on the value 0. This
+issue has been present since commit 1894a253 (ramoops: Move to
+fs/pstore/ram.c).
+
+Signed-off-by: Maxime Bizon <mbizon at freebox.fr>
+Signed-off-by: Florian Fainelli <ffainelli at freebox.fr>
+Acked-by: Kees Cook <keescook at chromium.org>
+Signed-off-by: Anton Vorontsov <anton.vorontsov at linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/pstore/ram.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -374,10 +374,14 @@ static int __devinit ramoops_probe(struc
+ goto fail_out;
+ }
+
+- pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
+- pdata->record_size = rounddown_pow_of_two(pdata->record_size);
+- pdata->console_size = rounddown_pow_of_two(pdata->console_size);
+- pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
++ if (!is_power_of_2(pdata->mem_size))
++ pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
++ if (!is_power_of_2(pdata->record_size))
++ pdata->record_size = rounddown_pow_of_two(pdata->record_size);
++ if (!is_power_of_2(pdata->console_size))
++ pdata->console_size = rounddown_pow_of_two(pdata->console_size);
++ if (!is_power_of_2(pdata->ftrace_size))
++ pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
+
+ cxt->dump_read_cnt = 0;
+ cxt->size = pdata->mem_size;
+From 5416912af75de9cba5d1c75b99a7888b0bbbd2fb Mon Sep 17 00:00:00 2001
+From: Aaron Lu <aaron.lu at intel.com>
+Date: Mon, 3 Dec 2012 11:35:02 +0800
+Subject: libata: set dma_mode to 0xff in reset
+
+From: Aaron Lu <aaron.lu at intel.com>
+
+commit 5416912af75de9cba5d1c75b99a7888b0bbbd2fb upstream.
+
+ata_device->dma_mode's initial value is zero, which is not a valid dma
+mode, but ata_dma_enabled will return true for this value. This patch
+sets dma_mode to 0xff in reset function, so that ata_dma_enabled will
+not return true for this case, or it will cause problem for pata_acpi.
+
+The corrsponding bugzilla page is at:
+https://bugzilla.kernel.org/show_bug.cgi?id=49151
+
+Reported-by: Phillip Wood <phillip.wood at dunelm.org.uk>
+Signed-off-by: Aaron Lu <aaron.lu at intel.com>
+Tested-by: Szymon Janc <szymon at janc.net.pl>
+Tested-by: Dutra Julio <dutra.julio at gmail.com>
+Acked-by: Alan Cox <alan at linux.intel.com>
+Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/ata/libata-core.c | 1 +
+ drivers/ata/libata-eh.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -2560,6 +2560,7 @@ int ata_bus_probe(struct ata_port *ap)
+ * bus as we may be talking too fast.
+ */
+ dev->pio_mode = XFER_PIO_0;
++ dev->dma_mode = 0xff;
+
+ /* If the controller has a pio mode setup function
+ * then use it to set the chipset to rights. Don't
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -2657,6 +2657,7 @@ int ata_eh_reset(struct ata_link *link,
+ * bus as we may be talking too fast.
+ */
+ dev->pio_mode = XFER_PIO_0;
++ dev->dma_mode = 0xff;
+
+ /* If the controller has a pio mode setup function
+ * then use it to set the chipset to rights. Don't
+From 26cd4d65deba587f3cf2329b6869ce02bcbe68ec Mon Sep 17 00:00:00 2001
+From: Xiaotian Feng <xtfeng at gmail.com>
+Date: Thu, 13 Dec 2012 16:12:18 +0800
+Subject: libata: fix Null pointer dereference on disk error
+
+From: Xiaotian Feng <xtfeng at gmail.com>
+
+commit 26cd4d65deba587f3cf2329b6869ce02bcbe68ec upstream.
+
+Following oops were observed when disk error happened:
+
+[ 4272.896937] sd 0:0:0:0: [sda] Unhandled error code
+[ 4272.896939] sd 0:0:0:0: [sda] Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
+[ 4272.896942] sd 0:0:0:0: [sda] CDB: Read(10): 28 00 00 5a de a7 00 00 08 00
+[ 4272.896951] end_request: I/O error, dev sda, sector 5955239
+[ 4291.574947] BUG: unable to handle kernel NULL pointer dereference at (null)
+[ 4291.658305] IP: [] ahci_activity_show+0x1/0x40
+[ 4291.730090] PGD 76dbbc067 PUD 6c4fba067 PMD 0
+[ 4291.783408] Oops: 0000 [#1] SMP
+[ 4291.822100] last sysfs file: /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/sw_activity
+[ 4291.934235] CPU 9
+[ 4291.958301] Pid: 27942, comm: hwinfo ......
+
+ata_scsi_find_dev could return NULL, so ata_scsi_activity_{show,store} should check if atadev is NULL.
+
+Signed-off-by: Xiaotian Feng <dannyfeng at tencent.com>
+Cc: James Bottomley <JBottomley at Parallels.com>
+Signed-off-by: Jeff Garzik <jgarzik at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/ata/libata-scsi.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -309,7 +309,8 @@ ata_scsi_activity_show(struct device *de
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
+
+- if (ap->ops->sw_activity_show && (ap->flags & ATA_FLAG_SW_ACTIVITY))
++ if (atadev && ap->ops->sw_activity_show &&
++ (ap->flags & ATA_FLAG_SW_ACTIVITY))
+ return ap->ops->sw_activity_show(atadev, buf);
+ return -EINVAL;
+ }
+@@ -324,7 +325,8 @@ ata_scsi_activity_store(struct device *d
+ enum sw_activity val;
+ int rc;
+
+- if (ap->ops->sw_activity_store && (ap->flags & ATA_FLAG_SW_ACTIVITY)) {
++ if (atadev && ap->ops->sw_activity_store &&
++ (ap->flags & ATA_FLAG_SW_ACTIVITY)) {
+ val = simple_strtoul(buf, NULL, 0);
+ switch (val) {
+ case OFF: case BLINK_ON: case BLINK_OFF:
+From 40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+Date: Wed, 5 Dec 2012 12:08:29 +0100
+Subject: target/file: Fix 32-bit highmem breakage for SGL -> iovec mapping
+
+From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+
+commit 40ff2c3b3da35dd3a00ac6722056a59b4b3f2caf upstream.
+
+This patch changes vectored file I/O to use kmap + kunmap when mapping
+incoming SGL memory -> struct iovec in order to properly support 32-bit
+highmem configurations. This is because an extra bounce buffer may be
+required when processing scatterlist pages allocated with GFP_KERNEL.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/target_core_file.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/target/target_core_file.c
++++ b/drivers/target/target_core_file.c
+@@ -260,7 +260,7 @@ static int fd_do_readv(struct se_cmd *cm
+
+ for_each_sg(sgl, sg, sgl_nents, i) {
+ iov[i].iov_len = sg->length;
+- iov[i].iov_base = sg_virt(sg);
++ iov[i].iov_base = kmap(sg_page(sg)) + sg->offset;
+ }
+
+ old_fs = get_fs();
+@@ -268,6 +268,8 @@ static int fd_do_readv(struct se_cmd *cm
+ ret = vfs_readv(fd, &iov[0], sgl_nents, &pos);
+ set_fs(old_fs);
+
++ for_each_sg(sgl, sg, sgl_nents, i)
++ kunmap(sg_page(sg));
+ kfree(iov);
+ /*
+ * Return zeros and GOOD status even if the READ did not return
+@@ -313,7 +315,7 @@ static int fd_do_writev(struct se_cmd *c
+
+ for_each_sg(sgl, sg, sgl_nents, i) {
+ iov[i].iov_len = sg->length;
+- iov[i].iov_base = sg_virt(sg);
++ iov[i].iov_base = kmap(sg_page(sg)) + sg->offset;
+ }
+
+ old_fs = get_fs();
+@@ -321,6 +323,9 @@ static int fd_do_writev(struct se_cmd *c
+ ret = vfs_writev(fd, &iov[0], sgl_nents, &pos);
+ set_fs(old_fs);
+
++ for_each_sg(sgl, sg, sgl_nents, i)
++ kunmap(sg_page(sg));
++
+ kfree(iov);
+
+ if (ret < 0 || ret != cmd->data_length) {
+From 9f4ad44b264f8bb61ffdd607148215566568430d Mon Sep 17 00:00:00 2001
+From: Yi Zou <yi.zou at intel.com>
+Date: Mon, 10 Dec 2012 17:04:00 -0800
+Subject: target/tcm_fc: fix the lockdep warning due to inconsistent lock state
+
+From: Yi Zou <yi.zou at intel.com>
+
+commit 9f4ad44b264f8bb61ffdd607148215566568430d upstream.
+
+The lockdep warning below is in theory correct but it will be in really weird
+rare situation that ends up that deadlock since the tcm fc session is hashed
+based the rport id. Nonetheless, the complaining below is about rcu callback
+that does the transport_deregister_session() is happening in softirq, where
+transport_register_session() that happens earlier is not. This triggers the
+lockdep warning below. So, just fix this to make lockdep happy by disabling
+the soft irq before calling transport_register_session() in ft_prli.
+
+BTW, this was found in FCoE VN2VN over two VMs, couple of create and destroy
+would get this triggered.
+
+v1: was enforcing register to be in softirq context which was not righ. See,
+http://www.spinics.net/lists/target-devel/msg03614.html
+
+v2: following comments from Roland&Nick (thanks), it seems we don't have to
+do transport_deregister_session() in rcu callback, so move it into ft_sess_free()
+but still do kfree() of the corresponding ft_sess struct in rcu callback to
+make sure the ft_sess is not freed till the rcu callback.
+
+...
+[ 1328.370592] scsi2 : FCoE Driver
+[ 1328.383429] fcoe: No FDMI support.
+[ 1328.384509] host2: libfc: Link up on port (000000)
+[ 1328.934229] host2: Assigned Port ID 00a292
+[ 1357.232132] host2: rport 00a393: Remove port
+[ 1357.232568] host2: rport 00a393: Port sending LOGO from Ready state
+[ 1357.233692] host2: rport 00a393: Delete port
+[ 1357.234472] host2: rport 00a393: work event 3
+[ 1357.234969] host2: rport 00a393: callback ev 3
+[ 1357.235979] host2: rport 00a393: Received a LOGO response closed
+[ 1357.236706] host2: rport 00a393: work delete
+[ 1357.237481]
+[ 1357.237631] =================================
+[ 1357.238064] [ INFO: inconsistent lock state ]
+[ 1357.238450] 3.7.0-rc7-yikvm+ #3 Tainted: G O
+[ 1357.238450] ---------------------------------
+[ 1357.238450] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
+[ 1357.238450] ksoftirqd/0/3 [HC0[0]:SC1[1]:HE0:SE0] takes:
+[ 1357.238450] (&(&se_tpg->session_lock)->rlock){+.?...}, at: [<ffffffffa01eacd4>] transport_deregister_session+0x41/0x148 [target_core_mod]
+[ 1357.238450] {SOFTIRQ-ON-W} state was registered at:
+[ 1357.238450] [<ffffffff810834f5>] mark_held_locks+0x6d/0x95
+[ 1357.238450] [<ffffffff8108364a>] trace_hardirqs_on_caller+0x12d/0x197
+[ 1357.238450] [<ffffffff810836c1>] trace_hardirqs_on+0xd/0xf
+[ 1357.238450] [<ffffffff8149caba>] _raw_spin_unlock_irq+0x2d/0x45
+[ 1357.238450] [<ffffffffa01e8d10>] __transport_register_session+0xb8/0x122 [target_core_mod]
+[ 1357.238450] [<ffffffffa01e8dbe>] transport_register_session+0x44/0x5a [target_core_mod]
+[ 1357.238450] [<ffffffffa018e32c>] ft_prli+0x1e3/0x275 [tcm_fc]
+[ 1357.238450] [<ffffffffa0160e8d>] fc_rport_recv_req+0x95e/0xdc5 [libfc]
+[ 1357.238450] [<ffffffffa015be88>] fc_lport_recv_els_req+0xc4/0xd5 [libfc]
+[ 1357.238450] [<ffffffffa015c778>] fc_lport_recv_req+0x12f/0x18f [libfc]
+[ 1357.238450] [<ffffffffa015a6d7>] fc_exch_recv+0x8ba/0x981 [libfc]
+[ 1357.238450] [<ffffffffa0176d7a>] fcoe_percpu_receive_thread+0x47a/0x4e2 [fcoe]
+[ 1357.238450] [<ffffffff810549f1>] kthread+0xb1/0xb9
+[ 1357.238450] [<ffffffff814a40ec>] ret_from_fork+0x7c/0xb0
+[ 1357.238450] irq event stamp: 275411
+[ 1357.238450] hardirqs last enabled at (275410): [<ffffffff810bb6a0>] rcu_process_callbacks+0x229/0x42a
+[ 1357.238450] hardirqs last disabled at (275411): [<ffffffff8149c2f7>] _raw_spin_lock_irqsave+0x22/0x8e
+[ 1357.238450] softirqs last enabled at (275394): [<ffffffff8103d669>] __do_softirq+0x246/0x26f
+[ 1357.238450] softirqs last disabled at (275399): [<ffffffff8103d6bb>] run_ksoftirqd+0x29/0x62
+[ 1357.238450]
+[ 1357.238450] other info that might help us debug this:
+[ 1357.238450] Possible unsafe locking scenario:
+[ 1357.238450]
+[ 1357.238450] CPU0
+[ 1357.238450] ----
+[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock);
+[ 1357.238450] <Interrupt>
+[ 1357.238450] lock(&(&se_tpg->session_lock)->rlock);
+[ 1357.238450]
+[ 1357.238450] *** DEADLOCK ***
+[ 1357.238450]
+[ 1357.238450] no locks held by ksoftirqd/0/3.
+[ 1357.238450]
+[ 1357.238450] stack backtrace:
+[ 1357.238450] Pid: 3, comm: ksoftirqd/0 Tainted: G O 3.7.0-rc7-yikvm+ #3
+[ 1357.238450] Call Trace:
+[ 1357.238450] [<ffffffff8149399a>] print_usage_bug+0x1f5/0x206
+[ 1357.238450] [<ffffffff8100da59>] ? save_stack_trace+0x2c/0x49
+[ 1357.238450] [<ffffffff81082aae>] ? print_irq_inversion_bug.part.14+0x1ae/0x1ae
+[ 1357.238450] [<ffffffff81083336>] mark_lock+0x106/0x258
+[ 1357.238450] [<ffffffff81084e34>] __lock_acquire+0x2e7/0xe53
+[ 1357.238450] [<ffffffff8102903d>] ? pvclock_clocksource_read+0x48/0xb4
+[ 1357.238450] [<ffffffff810ba6a3>] ? rcu_process_gp_end+0xc0/0xc9
+[ 1357.238450] [<ffffffffa01eacd4>] ? transport_deregister_session+0x41/0x148 [target_core_mod]
+[ 1357.238450] [<ffffffff81085ef1>] lock_acquire+0x119/0x143
+[ 1357.238450] [<ffffffffa01eacd4>] ? transport_deregister_session+0x41/0x148 [target_core_mod]
+[ 1357.238450] [<ffffffff8149c329>] _raw_spin_lock_irqsave+0x54/0x8e
+[ 1357.238450] [<ffffffffa01eacd4>] ? transport_deregister_session+0x41/0x148 [target_core_mod]
+[ 1357.238450] [<ffffffffa01eacd4>] transport_deregister_session+0x41/0x148 [target_core_mod]
+[ 1357.238450] [<ffffffff810bb6a0>] ? rcu_process_callbacks+0x229/0x42a
+[ 1357.238450] [<ffffffffa018ddc5>] ft_sess_rcu_free+0x17/0x24 [tcm_fc]
+[ 1357.238450] [<ffffffffa018ddae>] ? ft_sess_free+0x1b/0x1b [tcm_fc]
+[ 1357.238450] [<ffffffff810bb6d7>] rcu_process_callbacks+0x260/0x42a
+[ 1357.238450] [<ffffffff8103d55d>] __do_softirq+0x13a/0x26f
+[ 1357.238450] [<ffffffff8149b34e>] ? __schedule+0x65f/0x68e
+[ 1357.238450] [<ffffffff8103d6bb>] run_ksoftirqd+0x29/0x62
+[ 1357.238450] [<ffffffff8105c83c>] smpboot_thread_fn+0x1a5/0x1aa
+[ 1357.238450] [<ffffffff8105c697>] ? smpboot_unregister_percpu_thread+0x47/0x47
+[ 1357.238450] [<ffffffff810549f1>] kthread+0xb1/0xb9
+[ 1357.238450] [<ffffffff8149b49d>] ? wait_for_common+0xbb/0x10a
+[ 1357.238450] [<ffffffff81054940>] ? __init_kthread_worker+0x59/0x59
+[ 1357.238450] [<ffffffff814a40ec>] ret_from_fork+0x7c/0xb0
+[ 1357.238450] [<ffffffff81054940>] ? __init_kthread_worker+0x59/0x59
+[ 1417.440099] rport-2:0-0: blocked FC remote port time out: removing rport
+
+Signed-off-by: Yi Zou <yi.zou at intel.com>
+Cc: Open-FCoE <devel at open-fcoe.org>
+Cc: Nicholas A. Bellinger <nab at risingtidesystems.com>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/tcm_fc/tfc_sess.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/target/tcm_fc/tfc_sess.c
++++ b/drivers/target/tcm_fc/tfc_sess.c
+@@ -430,7 +430,6 @@ static void ft_sess_rcu_free(struct rcu_
+ {
+ struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu);
+
+- transport_deregister_session(sess->se_sess);
+ kfree(sess);
+ }
+
+@@ -438,6 +437,7 @@ static void ft_sess_free(struct kref *kr
+ {
+ struct ft_sess *sess = container_of(kref, struct ft_sess, kref);
+
++ transport_deregister_session(sess->se_sess);
+ call_rcu(&sess->rcu, ft_sess_rcu_free);
+ }
+
+From e1fe2060d7e8f58a69374135e32e90f0bb79a7fd Mon Sep 17 00:00:00 2001
+From: Chris Boot <bootc at bootc.net>
+Date: Tue, 11 Dec 2012 21:58:48 +0000
+Subject: sbp-target: fix error path in sbp_make_tpg()
+
+From: Chris Boot <bootc at bootc.net>
+
+commit e1fe2060d7e8f58a69374135e32e90f0bb79a7fd upstream.
+
+If the TPG memory is allocated successfully, but we fail further along
+in the function, a dangling pointer to freed memory is left in the TPort
+structure. This is mostly harmless, but does prevent re-trying the
+operation without first removing the TPort altogether.
+
+Reported-by: Chen Gang <gang.chen at asianux.com>
+Signed-off-by: Chris Boot <bootc at bootc.net>
+Cc: Andy Grover <agrover at redhat.com>
+Cc: Nicholas A. Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/target/sbp/sbp_target.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/target/sbp/sbp_target.c
++++ b/drivers/target/sbp/sbp_target.c
+@@ -2207,20 +2207,23 @@ static struct se_portal_group *sbp_make_
+ tport->mgt_agt = sbp_management_agent_register(tport);
+ if (IS_ERR(tport->mgt_agt)) {
+ ret = PTR_ERR(tport->mgt_agt);
+- kfree(tpg);
+- return ERR_PTR(ret);
++ goto out_free_tpg;
+ }
+
+ ret = core_tpg_register(&sbp_fabric_configfs->tf_ops, wwn,
+ &tpg->se_tpg, (void *)tpg,
+ TRANSPORT_TPG_TYPE_NORMAL);
+- if (ret < 0) {
+- sbp_management_agent_unregister(tport->mgt_agt);
+- kfree(tpg);
+- return ERR_PTR(ret);
+- }
++ if (ret < 0)
++ goto out_unreg_mgt_agt;
+
+ return &tpg->se_tpg;
++
++out_unreg_mgt_agt:
++ sbp_management_agent_unregister(tport->mgt_agt);
++out_free_tpg:
++ tport->tpg = NULL;
++ kfree(tpg);
++ return ERR_PTR(ret);
+ }
+
+ static void sbp_drop_tpg(struct se_portal_group *se_tpg)
+From fee546ce8cfd9dea1f53175f627e17ef5ff05df4 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Fri, 23 Nov 2012 12:05:33 +0900
+Subject: mfd: wm8994: Add support for WM1811 rev E
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit fee546ce8cfd9dea1f53175f627e17ef5ff05df4 upstream.
+
+This is supported identically to the previous revisions.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Samuel Ortiz <sameo at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/mfd/wm8994-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mfd/wm8994-core.c
++++ b/drivers/mfd/wm8994-core.c
+@@ -557,6 +557,7 @@ static __devinit int wm8994_device_init(
+ case 1:
+ case 2:
+ case 3:
++ case 4:
+ regmap_patch = wm1811_reva_patch;
+ patch_regs = ARRAY_SIZE(wm1811_reva_patch);
+ break;
+From b9fbb62eb61452d728c39b2e5020739c575aac53 Mon Sep 17 00:00:00 2001
+From: Charles Keepax <ckeepax at opensource.wolfsonmicro.com>
+Date: Fri, 9 Nov 2012 16:15:28 +0000
+Subject: mfd: Only unregister platform devices allocated by the mfd core
+
+From: Charles Keepax <ckeepax at opensource.wolfsonmicro.com>
+
+commit b9fbb62eb61452d728c39b2e5020739c575aac53 upstream.
+
+mfd_remove_devices would iterate over all devices sharing a parent with
+an mfd device regardless of whether they were allocated by the mfd core
+or not. This especially caused problems when the device structure was
+not contained within a platform_device, because to_platform_device is
+used on each device pointer.
+
+This patch defines a device_type for mfd devices and checks this is
+present from mfd_remove_devices_fn before processing the device.
+
+Signed-off-by: Charles Keepax <ckeepax at opensource.wolfsonmicro.com>
+Tested-by: Peter Tyser <ptyser at xes-inc.com>
+Reviewed-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Samuel Ortiz <sameo at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/mfd/mfd-core.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/drivers/mfd/mfd-core.c
++++ b/drivers/mfd/mfd-core.c
+@@ -21,6 +21,10 @@
+ #include <linux/irqdomain.h>
+ #include <linux/of.h>
+
++static struct device_type mfd_dev_type = {
++ .name = "mfd_device",
++};
++
+ int mfd_cell_enable(struct platform_device *pdev)
+ {
+ const struct mfd_cell *cell = mfd_get_cell(pdev);
+@@ -91,6 +95,7 @@ static int mfd_add_device(struct device
+ goto fail_device;
+
+ pdev->dev.parent = parent;
++ pdev->dev.type = &mfd_dev_type;
+
+ if (parent->of_node && cell->of_compatible) {
+ for_each_child_of_node(parent->of_node, np) {
+@@ -204,10 +209,16 @@ EXPORT_SYMBOL(mfd_add_devices);
+
+ static int mfd_remove_devices_fn(struct device *dev, void *c)
+ {
+- struct platform_device *pdev = to_platform_device(dev);
+- const struct mfd_cell *cell = mfd_get_cell(pdev);
++ struct platform_device *pdev;
++ const struct mfd_cell *cell;
+ atomic_t **usage_count = c;
+
++ if (dev->type != &mfd_dev_type)
++ return 0;
++
++ pdev = to_platform_device(dev);
++ cell = mfd_get_cell(pdev);
++
+ /* find the base address of usage_count pointers (for freeing) */
+ if (!*usage_count || (cell->usage_count < *usage_count))
+ *usage_count = cell->usage_count;
+From 90a38d999739f35f4fc925c875e6ee518546b66c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 15 Oct 2012 22:44:45 +0200
+Subject: mfd: Remove Unicode Byte Order Marks from da9055
+
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+
+commit 90a38d999739f35f4fc925c875e6ee518546b66c upstream.
+
+Older gcc (< 4.4) doesn't like files starting with Unicode BOMs:
+
+include/linux/mfd/da9055/core.h:1: error: stray ‘\357’ in program
+include/linux/mfd/da9055/core.h:1: error: stray ‘\273’ in program
+include/linux/mfd/da9055/core.h:1: error: stray ‘\277’ in program
+include/linux/mfd/da9055/pdata.h:1: error: stray ‘\357’ in program
+include/linux/mfd/da9055/pdata.h:1: error: stray ‘\273’ in program
+include/linux/mfd/da9055/pdata.h:1: error: stray ‘\277’ in program
+include/linux/mfd/da9055/reg.h:1: error: stray ‘\357’ in program
+include/linux/mfd/da9055/reg.h:1: error: stray ‘\273’ in program
+include/linux/mfd/da9055/reg.h:1: error: stray ‘\277’ in program
+
+Remove the BOMs, the rest of the files is plain ASCII anyway.
+
+Output of "file" before:
+
+include/linux/mfd/da9055/core.h: UTF-8 Unicode (with BOM) C program text
+include/linux/mfd/da9055/pdata.h: UTF-8 Unicode (with BOM) C program text
+include/linux/mfd/da9055/reg.h: UTF-8 Unicode (with BOM) C program text
+
+Output of "file" after:
+
+include/linux/mfd/da9055/core.h: ASCII C program text
+include/linux/mfd/da9055/pdata.h: ASCII C program text
+include/linux/mfd/da9055/reg.h: ASCII C program text
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+Signed-off-by: Samuel Ortiz <sameo at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ include/linux/mfd/da9055/core.h | 2 +-
+ include/linux/mfd/da9055/pdata.h | 2 +-
+ include/linux/mfd/da9055/reg.h | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/include/linux/mfd/da9055/core.h
++++ b/include/linux/mfd/da9055/core.h
+@@ -1,4 +1,4 @@
+-/*
++/*
+ * da9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+--- a/include/linux/mfd/da9055/pdata.h
++++ b/include/linux/mfd/da9055/pdata.h
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2012 Dialog Semiconductor Ltd.
++/* Copyright (C) 2012 Dialog Semiconductor Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+--- a/include/linux/mfd/da9055/reg.h
++++ b/include/linux/mfd/da9055/reg.h
+@@ -1,4 +1,4 @@
+-/*
++/*
+ * DA9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+From 24ec19b0ae83a385ad9c55520716da671274b96c Mon Sep 17 00:00:00 2001
+From: Eugene Shatokhin <eugene.shatokhin at rosalab.ru>
+Date: Thu, 8 Nov 2012 15:11:11 -0500
+Subject: ext4: fix memory leak in ext4_xattr_set_acl()'s error path
+
+From: Eugene Shatokhin <eugene.shatokhin at rosalab.ru>
+
+commit 24ec19b0ae83a385ad9c55520716da671274b96c upstream.
+
+In ext4_xattr_set_acl(), if ext4_journal_start() returns an error,
+posix_acl_release() will not be called for 'acl' which may result in a
+memory leak.
+
+This patch fixes that.
+
+Reviewed-by: Lukas Czerner <lczerner at redhat.com>
+Signed-off-by: Eugene Shatokhin <eugene.shatokhin at rosalab.ru>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/acl.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/acl.c
++++ b/fs/ext4/acl.c
+@@ -423,8 +423,10 @@ ext4_xattr_set_acl(struct dentry *dentry
+
+ retry:
+ handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
+- if (IS_ERR(handle))
+- return PTR_ERR(handle);
++ if (IS_ERR(handle)) {
++ error = PTR_ERR(handle);
++ goto release_and_out;
++ }
+ error = ext4_set_acl(handle, inode, type, acl);
+ ext4_journal_stop(handle);
+ if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
+From aeb1e5d69a5be592e86a926be73efb38c55af404 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso at mit.edu>
+Date: Thu, 29 Nov 2012 21:21:22 -0500
+Subject: ext4: fix possible use after free with metadata csum
+
+From: Theodore Ts'o <tytso at mit.edu>
+
+commit aeb1e5d69a5be592e86a926be73efb38c55af404 upstream.
+
+Commit fa77dcfafeaa introduces block bitmap checksum calculation into
+ext4_new_inode() in the case that block group was uninitialized.
+However we brelse() the bitmap buffer before we attempt to checksum it
+so we have no guarantee that the buffer is still there.
+
+Fix this by releasing the buffer after the possible checksum
+computation.
+
+Signed-off-by: Lukas Czerner <lczerner at redhat.com>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Acked-by: Darrick J. Wong <darrick.wong at oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/ialloc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -762,7 +762,6 @@ got:
+
+ BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
+ err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh);
+- brelse(block_bitmap_bh);
+
+ /* recheck and clear flag under lock if we still need to */
+ ext4_lock_group(sb, group);
+@@ -775,6 +774,7 @@ got:
+ ext4_group_desc_csum_set(sb, group, gdp);
+ }
+ ext4_unlock_group(sb, group);
++ brelse(block_bitmap_bh);
+
+ if (err)
+ goto fail;
+From d1f3b65d2d6fdb4bf0edd4b67e86e191af48daee Mon Sep 17 00:00:00 2001
+From: Nathan Williams <nathan at traverse.com.au>
+Date: Thu, 22 Nov 2012 10:42:52 +1100
+Subject: mtd cs553x_nand: Initialise ecc.strength before nand_scan()
+
+From: Nathan Williams <nathan at traverse.com.au>
+
+commit d1f3b65d2d6fdb4bf0edd4b67e86e191af48daee upstream.
+
+Loading cs553x_nand with Hynix H27U1G8F2BTR NAND flash causes this bug:
+
+kernel BUG at drivers/mtd/nand/nand_base.c:3345!
+invalid opcode: 0000 [#1]
+Modules linked in: cs553x_nand(+) vfat fat usb_storage ehci_hcd usbcore usb_comr
+Pid: 436, comm: modprobe Not tainted 3.6.7 #1
+EIP: 0060:[<c118d205>] EFLAGS: 00010296 CPU: 0
+EIP is at nand_scan_tail+0x64c/0x69c
+EAX: 00000034 EBX: cea6ed98 ECX: 00000000 EDX: 00000000
+ESI: cea6ec00 EDI: cea6ec00 EBP: 20000000 ESP: cdd17e48
+ DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068
+CR0: 8005003b CR2: 0804e119 CR3: 0d850000 CR4: 00000090
+DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
+DR6: ffff0ff0 DR7: 00000400
+Process modprobe (pid: 436, ti=cdd16000 task=cdd1c320 task.ti=cdd16000)
+Stack:
+ c12e962c c118f7ef 00000003 cea6ed98 d014b25c 20000000 fffff007 00000001
+ 00000000 cdd53b00 d014b000 c1001021 cdd53b00 d01493c0 cdd53b00 cdd53b00
+ d01493c0 c1047f83 d014b4a0 00000000 cdd17f9c ce4be454 cdd17f48 cdd1c320
+Call Trace:
+ [<c118f7ef>] ? nand_scan+0x1b/0x4d
+ [<d014b25c>] ? init_module+0x25c/0x2de [cs553x_nand]
+ [<d014b000>] ? 0xd014afff
+ [<c1001021>] ? do_one_initcall+0x21/0x111
+ [<c1047f83>] ? sys_init_module+0xe4/0x1261
+ [<c1031207>] ? task_work_run+0x36/0x43
+ [<c1265ced>] ? syscall_call+0x7/0xb
+Code: fa ff ff c7 86 d8 00 00 00 01 00 00 00 e9 5f fc ff ff 68 f8 26 2e c1 e8 a7
+EIP: [<c118d205>] nand_scan_tail+0x64c/0x69c SS:ESP 0068:cdd17e48
+
+Initialising ecc.strength before the call to nand_scan() fixes this.
+
+Signed-off-by: Nathan Williams <nathan at traverse.com.au>
+Acked-by: Brian Norris <computersforpeace at gmail.com>
+Acked-by: Mike Dunn <mikedunn at newsguy.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/mtd/nand/cs553x_nand.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/mtd/nand/cs553x_nand.c
++++ b/drivers/mtd/nand/cs553x_nand.c
+@@ -237,6 +237,7 @@ static int __init cs553x_init_one(int cs
+ this->ecc.hwctl = cs_enable_hwecc;
+ this->ecc.calculate = cs_calculate_ecc;
+ this->ecc.correct = nand_correct_data;
++ this->ecc.strength = 1;
+
+ /* Enable the following for a flash based bad block table */
+ this->bbt_options = NAND_BBT_USE_FLASH;
+@@ -247,8 +248,6 @@ static int __init cs553x_init_one(int cs
+ goto out_ior;
+ }
+
+- this->ecc.strength = 1;
+-
+ new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs);
+
+ cs553x_mtd[cs] = new_mtd;
+From 6f2a6a52560ad8d85710aabd92b7a3239b3a6b07 Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <w.sang at pengutronix.de>
+Date: Wed, 5 Dec 2012 21:46:02 +0100
+Subject: mtd: nand: gpmi: reset BCH earlier, too, to avoid NAND startup problems
+
+From: Wolfram Sang <w.sang at pengutronix.de>
+
+commit 6f2a6a52560ad8d85710aabd92b7a3239b3a6b07 upstream.
+
+It could happen (1 out of 100 times) that NAND did not start up
+correctly after warm rebooting, so the kernel could not find the UBI or
+DMA timed out due to a stalled BCH. When resetting BCH together with
+GPMI, the issue could not be observed anymore (after 10000+ reboots). We
+probably need the consistent state already before sending any command to
+NAND, even when no ECC is needed. I chose to keep the extra reset for
+BCH when changing the flash layout to be on the safe side.
+
+Signed-off-by: Wolfram Sang <w.sang at pengutronix.de>
+Acked-by: Huang Shijie <b32955 at freescale.com>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
++++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+@@ -166,6 +166,15 @@ int gpmi_init(struct gpmi_nand_data *thi
+ if (ret)
+ goto err_out;
+
++ /*
++ * Reset BCH here, too. We got failures otherwise :(
++ * See later BCH reset for explanation of MX23 handling
++ */
++ ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
++ if (ret)
++ goto err_out;
++
++
+ /* Choose NAND mode. */
+ writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR);
+
+From bd1ee804af8bdf2fd5131234330615f8aecbd9ed Mon Sep 17 00:00:00 2001
+From: Pawel Moll <pawel.moll at arm.com>
+Date: Mon, 29 Oct 2012 11:23:02 +0000
+Subject: kbuild: Do not remove vmlinux when cleaning external module
+
+From: Pawel Moll <pawel.moll at arm.com>
+
+commit bd1ee804af8bdf2fd5131234330615f8aecbd9ed upstream.
+
+Since commit 1f2bfbd00e466ff3489b2ca5cc75b1cccd14c123 "kbuild:
+link of vmlinux moved to a script" make clean with M=<dir>
+argument (so cleaning external module) removes vmlinux,
+System.map and couple of other files from the *main* kernel
+build directory! This not what was happening before and almost
+certainly not what one would expect.
+
+This patch moves makes the clean target of the script called
+only when !KBUILD_EXTMOD.
+
+Signed-off-by: Pawel Moll <pawel.moll at arm.com>
+Signed-off-by: Michal Marek <mmarek at suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ Makefile | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -1021,11 +1021,14 @@ clean: rm-dirs := $(CLEAN_DIRS)
+ clean: rm-files := $(CLEAN_FILES)
+ clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation samples)
+
+-PHONY += $(clean-dirs) clean archclean
++PHONY += $(clean-dirs) clean archclean vmlinuxclean
+ $(clean-dirs):
+ $(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
+
+-clean: archclean
++vmlinuxclean:
++ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
++
++clean: archclean vmlinuxclean
+
+ # mrproper - Delete all generated files, including .config
+ #
+@@ -1252,7 +1255,6 @@ scripts: ;
+ endif # KBUILD_EXTMOD
+
+ clean: $(clean-dirs)
+- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean
+ $(call cmd,rmdirs)
+ $(call cmd,rmfiles)
+ @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
+From ca2e16faa7378878c1522a7c1b6c38211de3331d Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen at ti.com>
+Date: Thu, 22 Nov 2012 10:39:56 +0200
+Subject: OMAP: board-files: fix i2c_bus for tfp410
+
+From: Tomi Valkeinen <tomi.valkeinen at ti.com>
+
+commit ca2e16faa7378878c1522a7c1b6c38211de3331d upstream.
+
+The i2c handling in tfp410 driver, which handles converting parallel RGB
+to DVI, was changed in 958f2717b84e88bf833d996997fda8f73276f2af
+(OMAPDSS: TFP410: pdata rewrite). The patch changed what value the
+driver considers as invalid/undefined. Before the patch, 0 was the
+invalid value, but as 0 is a valid bus number, the patch changed this to
+-1.
+
+However, the fact was missed that many board files do not define the bus
+number at all, thus it's left to 0. This causes the driver to fail to
+get the i2c bus, exiting from the driver's probe with an error, meaning
+that the DVI output does not work for those boards.
+
+This patch fixes the issue by changing the i2c_bus number field in the
+driver's platform data from u16 to int, and setting the bus number to -1
+in the board files for the boards that did not define the bus. The
+exception is devkit8000, for which the bus is set to 1, which is the
+correct bus for that board.
+
+The bug exists in v3.5+ kernels.
+
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
+Reported-by: Thomas Weber <thomas at tomweber.eu>
+Cc: Thomas Weber <thomas at tomweber.eu>
+Signed-off-by: Tony Lindgren <tony at atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/board-3430sdp.c | 1 +
+ arch/arm/mach-omap2/board-am3517evm.c | 1 +
+ arch/arm/mach-omap2/board-cm-t35.c | 1 +
+ arch/arm/mach-omap2/board-devkit8000.c | 1 +
+ arch/arm/mach-omap2/board-omap3evm.c | 1 +
+ arch/arm/mach-omap2/board-omap3stalker.c | 1 +
+ include/video/omap-panel-tfp410.h | 2 +-
+ 7 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-omap2/board-3430sdp.c
++++ b/arch/arm/mach-omap2/board-3430sdp.c
+@@ -157,6 +157,7 @@ static struct omap_dss_device sdp3430_lc
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = -1,
++ .i2c_bus_num = -1,
+ };
+
+ static struct omap_dss_device sdp3430_dvi_device = {
+--- a/arch/arm/mach-omap2/board-am3517evm.c
++++ b/arch/arm/mach-omap2/board-am3517evm.c
+@@ -208,6 +208,7 @@ static struct omap_dss_device am3517_evm
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = -1,
++ .i2c_bus_num = -1,
+ };
+
+ static struct omap_dss_device am3517_evm_dvi_device = {
+--- a/arch/arm/mach-omap2/board-cm-t35.c
++++ b/arch/arm/mach-omap2/board-cm-t35.c
+@@ -243,6 +243,7 @@ static struct omap_dss_device cm_t35_lcd
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = CM_T35_DVI_EN_GPIO,
++ .i2c_bus_num = -1,
+ };
+
+ static struct omap_dss_device cm_t35_dvi_device = {
+--- a/arch/arm/mach-omap2/board-devkit8000.c
++++ b/arch/arm/mach-omap2/board-devkit8000.c
+@@ -139,6 +139,7 @@ static struct omap_dss_device devkit8000
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = -1,
++ .i2c_bus_num = 1,
+ };
+
+ static struct omap_dss_device devkit8000_dvi_device = {
+--- a/arch/arm/mach-omap2/board-omap3evm.c
++++ b/arch/arm/mach-omap2/board-omap3evm.c
+@@ -236,6 +236,7 @@ static struct omap_dss_device omap3_evm_
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = OMAP3EVM_DVI_PANEL_EN_GPIO,
++ .i2c_bus_num = -1,
+ };
+
+ static struct omap_dss_device omap3_evm_dvi_device = {
+--- a/arch/arm/mach-omap2/board-omap3stalker.c
++++ b/arch/arm/mach-omap2/board-omap3stalker.c
+@@ -119,6 +119,7 @@ static struct omap_dss_device omap3_stal
+
+ static struct tfp410_platform_data dvi_panel = {
+ .power_down_gpio = DSS_ENABLE_GPIO,
++ .i2c_bus_num = -1,
+ };
+
+ static struct omap_dss_device omap3_stalker_dvi_device = {
+--- a/include/video/omap-panel-tfp410.h
++++ b/include/video/omap-panel-tfp410.h
+@@ -28,7 +28,7 @@ struct omap_dss_device;
+ * @power_down_gpio: gpio number for PD pin (or -1 if not available)
+ */
+ struct tfp410_platform_data {
+- u16 i2c_bus_num;
++ int i2c_bus_num;
+ int power_down_gpio;
+ };
+
+From 642fe4d00db56d65060ce2fd4c105884414acb16 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+Date: Thu, 8 Nov 2012 10:01:26 -0500
+Subject: SUNRPC: Fix validity issues with rpc_pipefs sb->s_fs_info
+
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+commit 642fe4d00db56d65060ce2fd4c105884414acb16 upstream.
+
+rpc_kill_sb() must defer calling put_net() until after the notifier
+has been called, since most (all?) of the notifier callbacks assume
+that sb->s_fs_info points to a valid net namespace. It also must not
+call put_net() if the call to rpc_fill_super was unsuccessful.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=48421
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Cc: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/sunrpc/rpc_pipe.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/sunrpc/rpc_pipe.c
++++ b/net/sunrpc/rpc_pipe.c
+@@ -1152,14 +1152,19 @@ static void rpc_kill_sb(struct super_blo
+ struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+ mutex_lock(&sn->pipefs_sb_lock);
++ if (sn->pipefs_sb != sb) {
++ mutex_unlock(&sn->pipefs_sb_lock);
++ goto out;
++ }
+ sn->pipefs_sb = NULL;
+ mutex_unlock(&sn->pipefs_sb_lock);
+- put_net(net);
+ dprintk("RPC: sending pipefs UMOUNT notification for net %p%s\n",
+ net, NET_NAME(net));
+ blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+ RPC_PIPEFS_UMOUNT,
+ sb);
++ put_net(net);
++out:
+ kill_litter_super(sb);
+ }
+
+From cd6c5968582a273561464fe6b1e8cc8214be02df Mon Sep 17 00:00:00 2001
+From: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Date: Mon, 17 Dec 2012 20:18:52 +0300
+Subject: SUNRPC: continue run over clients list on PipeFS event instead of break
+
+From: Stanislav Kinsbursky <skinsbursky at parallels.com>
+
+commit cd6c5968582a273561464fe6b1e8cc8214be02df upstream.
+
+There are SUNRPC clients, which program doesn't have pipe_dir_name. These
+clients can be skipped on PipeFS events, because nothing have to be created or
+destroyed. But instead of breaking in case of such a client was found, search
+for suitable client over clients list have to be continued. Otherwise some
+clients could not be covered by PipeFS event handler.
+
+Signed-off-by: Stanislav Kinsbursky <skinsbursky at parallels.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/sunrpc/clnt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -234,7 +234,7 @@ static struct rpc_clnt *rpc_get_client_f
+ spin_lock(&sn->rpc_client_lock);
+ list_for_each_entry(clnt, &sn->all_clients, cl_clients) {
+ if (clnt->cl_program->pipe_dir_name == NULL)
+- break;
++ continue;
+ if (rpc_clnt_skip_event(clnt, event))
+ continue;
+ if (atomic_inc_not_zero(&clnt->cl_count) == 0)
+From 621eb19ce1ec216e03ad354cb0c4061736b2a436 Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields at redhat.com>
+Date: Wed, 14 Nov 2012 10:48:05 -0500
+Subject: svcrpc: Revert "sunrpc/cache.h: replace simple_strtoul"
+
+From: "J. Bruce Fields" <bfields at redhat.com>
+
+commit 621eb19ce1ec216e03ad354cb0c4061736b2a436 upstream.
+
+Commit bbf43dc888833ac0539e437dbaeb28bfd4fbab9f "sunrpc/cache.h: replace
+simple_strtoul" introduced new range-checking which could cause get_int
+to fail on unsigned integers too large to be represented as an int.
+
+We could parse them as unsigned instead--but it turns out svcgssd is
+actually passing down "-1" in some cases. Which is perhaps stupid, but
+there's nothing we can do about it now.
+
+So just revert back to the previous "sloppy" behavior that accepts
+either representation.
+
+Reported-by: Sven Geggus <lists at fuchsschwanzdomain.de>
+Signed-off-by: J. Bruce Fields <bfields at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ include/linux/sunrpc/cache.h | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/linux/sunrpc/cache.h
++++ b/include/linux/sunrpc/cache.h
+@@ -217,6 +217,8 @@ extern int qword_get(char **bpp, char *d
+ static inline int get_int(char **bpp, int *anint)
+ {
+ char buf[50];
++ char *ep;
++ int rv;
+ int len = qword_get(bpp, buf, sizeof(buf));
+
+ if (len < 0)
+@@ -224,9 +226,11 @@ static inline int get_int(char **bpp, in
+ if (len == 0)
+ return -ENOENT;
+
+- if (kstrtoint(buf, 0, anint))
++ rv = simple_strtol(buf, &ep, 0);
++ if (*ep)
+ return -EINVAL;
+
++ *anint = rv;
+ return 0;
+ }
+
+From c6567ed1402c55e19b012e66a8398baec2a726f3 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+Date: Fri, 4 Jan 2013 12:23:21 -0500
+Subject: SUNRPC: Ensure that we free the rpc_task after cleanups are done
+
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+commit c6567ed1402c55e19b012e66a8398baec2a726f3 upstream.
+
+This patch ensures that we free the rpc_task after the cleanup callbacks
+are done in order to avoid a deadlock problem that can be triggered if
+the callback needs to wait for another workqueue item to complete.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Cc: Weston Andros Adamson <dros at netapp.com>
+Cc: Tejun Heo <tj at kernel.org>
+Cc: Bruce Fields <bfields at fieldses.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/sunrpc/sched.c | 27 +++++++++++++++++++++++----
+ 1 file changed, 23 insertions(+), 4 deletions(-)
+
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -919,16 +919,35 @@ struct rpc_task *rpc_new_task(const stru
+ return task;
+ }
+
++/*
++ * rpc_free_task - release rpc task and perform cleanups
++ *
++ * Note that we free up the rpc_task _after_ rpc_release_calldata()
++ * in order to work around a workqueue dependency issue.
++ *
++ * Tejun Heo states:
++ * "Workqueue currently considers two work items to be the same if they're
++ * on the same address and won't execute them concurrently - ie. it
++ * makes a work item which is queued again while being executed wait
++ * for the previous execution to complete.
++ *
++ * If a work function frees the work item, and then waits for an event
++ * which should be performed by another work item and *that* work item
++ * recycles the freed work item, it can create a false dependency loop.
++ * There really is no reliable way to detect this short of verifying
++ * every memory free."
++ *
++ */
+ static void rpc_free_task(struct rpc_task *task)
+ {
+- const struct rpc_call_ops *tk_ops = task->tk_ops;
+- void *calldata = task->tk_calldata;
++ unsigned short tk_flags = task->tk_flags;
+
+- if (task->tk_flags & RPC_TASK_DYNAMIC) {
++ rpc_release_calldata(task->tk_ops, task->tk_calldata);
++
++ if (tk_flags & RPC_TASK_DYNAMIC) {
+ dprintk("RPC: %5u freeing task\n", task->tk_pid);
+ mempool_free(task, rpc_task_mempool);
+ }
+- rpc_release_calldata(tk_ops, calldata);
+ }
+
+ static void rpc_async_release(struct work_struct *work)
+From 87ed50036b866db2ec2ba16b2a7aec4a2b0b7c39 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+Date: Mon, 7 Jan 2013 14:30:46 -0500
+Subject: SUNRPC: Ensure we release the socket write lock if the rpc_task exits early
+
+From: Trond Myklebust <Trond.Myklebust at netapp.com>
+
+commit 87ed50036b866db2ec2ba16b2a7aec4a2b0b7c39 upstream.
+
+If the rpc_task exits while holding the socket write lock before it has
+allocated an rpc slot, then the usual mechanism for releasing the write
+lock in xprt_release() is defeated.
+
+The problem occurs if the call to xprt_lock_write() initially fails, so
+that the rpc_task is put on the xprt->sending wait queue. If the task
+exits after being assigned the lock by __xprt_lock_write_func, but
+before it has retried the call to xprt_lock_and_alloc_slot(), then
+it calls xprt_release() while holding the write lock, but will
+immediately exit due to the test for task->tk_rqstp != NULL.
+
+Reported-by: Chris Perl <chris.perl at gmail.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/sunrpc/sched.c | 3 +--
+ net/sunrpc/xprt.c | 12 ++++++++++--
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+--- a/net/sunrpc/sched.c
++++ b/net/sunrpc/sched.c
+@@ -957,8 +957,7 @@ static void rpc_async_release(struct wor
+
+ static void rpc_release_resources_task(struct rpc_task *task)
+ {
+- if (task->tk_rqstp)
+- xprt_release(task);
++ xprt_release(task);
+ if (task->tk_msg.rpc_cred) {
+ put_rpccred(task->tk_msg.rpc_cred);
+ task->tk_msg.rpc_cred = NULL;
+--- a/net/sunrpc/xprt.c
++++ b/net/sunrpc/xprt.c
+@@ -1136,10 +1136,18 @@ static void xprt_request_init(struct rpc
+ void xprt_release(struct rpc_task *task)
+ {
+ struct rpc_xprt *xprt;
+- struct rpc_rqst *req;
++ struct rpc_rqst *req = task->tk_rqstp;
+
+- if (!(req = task->tk_rqstp))
++ if (req == NULL) {
++ if (task->tk_client) {
++ rcu_read_lock();
++ xprt = rcu_dereference(task->tk_client->cl_xprt);
++ if (xprt->snd_task == task)
++ xprt_release_write(xprt, task);
++ rcu_read_unlock();
++ }
+ return;
++ }
+
+ xprt = req->rq_xprt;
+ if (task->tk_ops->rpc_count_stats != NULL)
+From 2cbba75a56ea78e6876b4e2547a882f10b3fe72b Mon Sep 17 00:00:00 2001
+From: Alexey Khoroshilov <khoroshilov at ispras.ru>
+Date: Mon, 5 Nov 2012 22:40:14 +0400
+Subject: jffs2: hold erase_completion_lock on exit
+
+From: Alexey Khoroshilov <khoroshilov at ispras.ru>
+
+commit 2cbba75a56ea78e6876b4e2547a882f10b3fe72b upstream.
+
+Users of jffs2_do_reserve_space() expect they still held
+erase_completion_lock after call to it. But there is a path
+where jffs2_do_reserve_space() leaves erase_completion_lock unlocked.
+The patch fixes it.
+
+Found by Linux Driver Verification project (linuxtesting.org).
+
+Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
+Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/jffs2/nodemgmt.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/jffs2/nodemgmt.c
++++ b/fs/jffs2/nodemgmt.c
+@@ -417,14 +417,16 @@ static int jffs2_do_reserve_space(struct
+ spin_unlock(&c->erase_completion_lock);
+
+ ret = jffs2_prealloc_raw_node_refs(c, jeb, 1);
+- if (ret)
+- return ret;
++
+ /* Just lock it again and continue. Nothing much can change because
+ we hold c->alloc_sem anyway. In fact, it's not entirely clear why
+ we hold c->erase_completion_lock in the majority of this function...
+ but that's a question for another (more caffeine-rich) day. */
+ spin_lock(&c->erase_completion_lock);
+
++ if (ret)
++ return ret;
++
+ waste = jeb->free_size;
+ jffs2_link_node_ref(c, jeb,
+ (jeb->offset + c->sector_size - waste) | REF_OBSOLETE,
+From 999a7c5776a0ed2133645fa7e008bec05bda9254 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dcbw at redhat.com>
+Date: Fri, 14 Dec 2012 13:10:50 +0000
+Subject: i2400m: add Intel 6150 device IDs
+
+From: Dan Williams <dcbw at redhat.com>
+
+commit 999a7c5776a0ed2133645fa7e008bec05bda9254 upstream.
+
+Add device IDs for WiMAX function of Intel 6150 cards.
+
+Signed-off-by: Dan Williams <dcbw at redhat.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wimax/i2400m/i2400m-usb.h | 3 +++
+ drivers/net/wimax/i2400m/usb.c | 6 ++++++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/net/wimax/i2400m/i2400m-usb.h
++++ b/drivers/net/wimax/i2400m/i2400m-usb.h
+@@ -152,6 +152,9 @@ enum {
+ /* Device IDs */
+ USB_DEVICE_ID_I6050 = 0x0186,
+ USB_DEVICE_ID_I6050_2 = 0x0188,
++ USB_DEVICE_ID_I6150 = 0x07d6,
++ USB_DEVICE_ID_I6150_2 = 0x07d7,
++ USB_DEVICE_ID_I6150_3 = 0x07d9,
+ USB_DEVICE_ID_I6250 = 0x0187,
+ };
+
+--- a/drivers/net/wimax/i2400m/usb.c
++++ b/drivers/net/wimax/i2400m/usb.c
+@@ -510,6 +510,9 @@ int i2400mu_probe(struct usb_interface *
+ switch (id->idProduct) {
+ case USB_DEVICE_ID_I6050:
+ case USB_DEVICE_ID_I6050_2:
++ case USB_DEVICE_ID_I6150:
++ case USB_DEVICE_ID_I6150_2:
++ case USB_DEVICE_ID_I6150_3:
+ case USB_DEVICE_ID_I6250:
+ i2400mu->i6050 = 1;
+ break;
+@@ -759,6 +762,9 @@ static
+ struct usb_device_id i2400mu_id_table[] = {
+ { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) },
+ { USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) },
++ { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150) },
++ { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_2) },
++ { USB_DEVICE(0x8087, USB_DEVICE_ID_I6150_3) },
+ { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) },
+ { USB_DEVICE(0x8086, 0x0181) },
+ { USB_DEVICE(0x8086, 0x1403) },
+From 6491d4d02893d9787ba67279595990217177b351 Mon Sep 17 00:00:00 2001
+From: "Woodhouse, David" <david.woodhouse at intel.com>
+Date: Wed, 19 Dec 2012 13:25:35 +0000
+Subject: intel-iommu: Free old page tables before creating superpage
+
+From: "Woodhouse, David" <david.woodhouse at intel.com>
+
+commit 6491d4d02893d9787ba67279595990217177b351 upstream.
+
+The dma_pte_free_pagetable() function will only free a page table page
+if it is asked to free the *entire* 2MiB range that it covers. So if a
+page table page was used for one or more small mappings, it's likely to
+end up still present in the page tables... but with no valid PTEs.
+
+This was fine when we'd only be repopulating it with 4KiB PTEs anyway
+but the same virtual address range can end up being reused for a
+*large-page* mapping. And in that case were were trying to insert the
+large page into the second-level page table, and getting a complaint
+from the sanity check in __domain_mapping() because there was already a
+corresponding entry. This was *relatively* harmless; it led to a memory
+leak of the old page table page, but no other ill-effects.
+
+Fix it by calling dma_pte_clear_range (hopefully redundant) and
+dma_pte_free_pagetable() before setting up the new large page.
+
+Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
+Tested-by: Ravi Murty <Ravi.Murty at intel.com>
+Tested-by: Sudeep Dutt <sudeep.dutt at intel.com>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/iommu/intel-iommu.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -1827,10 +1827,17 @@ static int __domain_mapping(struct dmar_
+ if (!pte)
+ return -ENOMEM;
+ /* It is large page*/
+- if (largepage_lvl > 1)
++ if (largepage_lvl > 1) {
+ pteval |= DMA_PTE_LARGE_PAGE;
+- else
++ /* Ensure that old small page tables are removed to make room
++ for superpage, if they exist. */
++ dma_pte_clear_range(domain, iov_pfn,
++ iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
++ dma_pte_free_pagetable(domain, iov_pfn,
++ iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1);
++ } else {
+ pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
++ }
+
+ }
+ /* We don't need lock here, nobody else
+From ae133a1129790ec288b429b5f08ab4701633844a Mon Sep 17 00:00:00 2001
+From: Christian König <deathsimple at vodafone.de>
+Date: Tue, 18 Sep 2012 15:30:44 -0400
+Subject: drm/radeon: stop page faults from hanging the system (v2)
+
+From: Christian König <deathsimple at vodafone.de>
+
+commit ae133a1129790ec288b429b5f08ab4701633844a upstream.
+
+Redirect invalid memory accesses to the default page
+instead of locking up the memory controller. Also
+enable the invalid memory access interrupts and
+start spamming system log with it.
+
+v2 (agd5f): fix up against 2 level PT changes
+
+Signed-off-by: Christian König <deathsimple at vodafone.de>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c | 10 ++++++++++
+ drivers/gpu/drm/radeon/evergreend.h | 3 +++
+ drivers/gpu/drm/radeon/ni.c | 16 +++++++++++++---
+ drivers/gpu/drm/radeon/nid.h | 11 +++++++++++
+ drivers/gpu/drm/radeon/si.c | 25 +++++++++++++++++++++++--
+ drivers/gpu/drm/radeon/sid.h | 14 ++++++++++++++
+ 6 files changed, 74 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -3093,6 +3093,16 @@ restart_ih:
+ break;
+ }
+ break;
++ case 146:
++ case 147:
++ dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
++ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
++ RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
++ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
++ RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
++ /* reset addr and status */
++ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
++ break;
+ case 176: /* CP_INT in ring buffer */
+ case 177: /* CP_INT in IB1 */
+ case 178: /* CP_INT in IB2 */
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -651,6 +651,7 @@
+ #define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1)
+ #define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
+ #define VM_CONTEXT1_CNTL 0x1414
++#define VM_CONTEXT1_CNTL2 0x1434
+ #define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C
+ #define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C
+ #define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C
+@@ -672,6 +673,8 @@
+ #define CACHE_UPDATE_MODE(x) ((x) << 6)
+ #define VM_L2_STATUS 0x140C
+ #define L2_BUSY (1 << 0)
++#define VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
++#define VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
+
+ #define WAIT_UNTIL 0x8040
+
+--- a/drivers/gpu/drm/radeon/ni.c
++++ b/drivers/gpu/drm/radeon/ni.c
+@@ -784,10 +784,20 @@ static int cayman_pcie_gart_enable(struc
+ /* enable context1-7 */
+ WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
+ (u32)(rdev->dummy_page.addr >> 12));
+- WREG32(VM_CONTEXT1_CNTL2, 0);
+- WREG32(VM_CONTEXT1_CNTL, 0);
++ WREG32(VM_CONTEXT1_CNTL2, 4);
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
+- RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
++ RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
++ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
++ PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
++ VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
++ READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ READ_PROTECTION_FAULT_ENABLE_DEFAULT |
++ WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
+
+ cayman_pcie_gart_tlb_flush(rdev);
+ DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
+--- a/drivers/gpu/drm/radeon/nid.h
++++ b/drivers/gpu/drm/radeon/nid.h
+@@ -80,7 +80,18 @@
+ #define VM_CONTEXT0_CNTL 0x1410
+ #define ENABLE_CONTEXT (1 << 0)
+ #define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1)
++#define RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 3)
+ #define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
++#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 6)
++#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 7)
++#define PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 9)
++#define PDE0_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 10)
++#define VALID_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 12)
++#define VALID_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 13)
++#define READ_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 15)
++#define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16)
++#define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18)
++#define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19)
+ #define VM_CONTEXT1_CNTL 0x1414
+ #define VM_CONTEXT0_CNTL2 0x1430
+ #define VM_CONTEXT1_CNTL2 0x1434
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -2426,9 +2426,20 @@ static int si_pcie_gart_enable(struct ra
+ /* enable context1-15 */
+ WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
+ (u32)(rdev->dummy_page.addr >> 12));
+- WREG32(VM_CONTEXT1_CNTL2, 0);
++ WREG32(VM_CONTEXT1_CNTL2, 4);
+ WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
+- RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
++ RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
++ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
++ PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
++ VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
++ READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ READ_PROTECTION_FAULT_ENABLE_DEFAULT |
++ WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
++ WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
+
+ si_pcie_gart_tlb_flush(rdev);
+ DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
+@@ -3684,6 +3695,16 @@ restart_ih:
+ break;
+ }
+ break;
++ case 146:
++ case 147:
++ dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
++ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
++ RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
++ dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
++ RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
++ /* reset addr and status */
++ WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
++ break;
+ case 176: /* RINGID0 CP_INT */
+ radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
+ break;
+--- a/drivers/gpu/drm/radeon/sid.h
++++ b/drivers/gpu/drm/radeon/sid.h
+@@ -91,7 +91,18 @@
+ #define VM_CONTEXT0_CNTL 0x1410
+ #define ENABLE_CONTEXT (1 << 0)
+ #define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1)
++#define RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 3)
+ #define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4)
++#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 6)
++#define DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 7)
++#define PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 9)
++#define PDE0_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 10)
++#define VALID_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 12)
++#define VALID_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 13)
++#define READ_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 15)
++#define READ_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 16)
++#define WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT (1 << 18)
++#define WRITE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 19)
+ #define VM_CONTEXT1_CNTL 0x1414
+ #define VM_CONTEXT0_CNTL2 0x1430
+ #define VM_CONTEXT1_CNTL2 0x1434
+@@ -104,6 +115,9 @@
+ #define VM_CONTEXT14_PAGE_TABLE_BASE_ADDR 0x1450
+ #define VM_CONTEXT15_PAGE_TABLE_BASE_ADDR 0x1454
+
++#define VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x14FC
++#define VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x14DC
++
+ #define VM_INVALIDATE_REQUEST 0x1478
+ #define VM_INVALIDATE_RESPONSE 0x147c
+
+From a02dc74b317d78298cb0587b9b1f6f741fd5c139 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher at amd.com>
+Date: Tue, 13 Nov 2012 18:03:41 -0500
+Subject: drm/radeon/dce32+: use fractional fb dividers for high clocks
+
+From: Alex Deucher <alexander.deucher at amd.com>
+
+commit a02dc74b317d78298cb0587b9b1f6f741fd5c139 upstream.
+
+Fixes flickering with some high res montiors.
+
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_crtc.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/atombios_crtc.c
++++ b/drivers/gpu/drm/radeon/atombios_crtc.c
+@@ -561,6 +561,8 @@ static u32 atombios_adjust_pll(struct dr
+ /* use frac fb div on APUs */
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
++ if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
++ radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
+ } else {
+ radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
+
+From 93927f9c1db5f55085457e820f0631064c7bfa34 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher at amd.com>
+Date: Tue, 4 Dec 2012 16:50:28 -0500
+Subject: drm/radeon: fix eDP clk and lane setup for scaled modes
+
+From: Alex Deucher <alexander.deucher at amd.com>
+
+commit 93927f9c1db5f55085457e820f0631064c7bfa34 upstream.
+
+Need to use the adjusted mode since we are sending native
+timing and using the scaler for non-native modes.
+
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Reviewed-by: Jerome Glisse <jglisse at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/atombios_encoders.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/atombios_encoders.c
++++ b/drivers/gpu/drm/radeon/atombios_encoders.c
+@@ -340,7 +340,7 @@ static bool radeon_atom_mode_fixup(struc
+ ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
+ (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+- radeon_dp_set_link_config(connector, mode);
++ radeon_dp_set_link_config(connector, adjusted_mode);
+ }
+
+ return true;
+From bd25f0783dc3fb72e1e2779c2b99b2d34b67fa8a Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse at redhat.com>
+Date: Tue, 11 Dec 2012 11:56:52 -0500
+Subject: drm/radeon: fix amd afusion gpu setup aka sumo v2
+
+From: Jerome Glisse <jglisse at redhat.com>
+
+commit bd25f0783dc3fb72e1e2779c2b99b2d34b67fa8a upstream.
+
+Set the proper number of tile pipe that should be a multiple of
+pipe depending on the number of se engine.
+
+Fix:
+https://bugs.freedesktop.org/show_bug.cgi?id=56405
+https://bugs.freedesktop.org/show_bug.cgi?id=56720
+
+v2: Don't change sumo2
+
+Signed-off-by: Jerome Glisse <jglisse at redhat.com>
+Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen.c | 8 ++++----
+ drivers/gpu/drm/radeon/evergreend.h | 2 ++
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/evergreen.c
++++ b/drivers/gpu/drm/radeon/evergreen.c
+@@ -1821,7 +1821,7 @@ static void evergreen_gpu_init(struct ra
+ case CHIP_SUMO:
+ rdev->config.evergreen.num_ses = 1;
+ rdev->config.evergreen.max_pipes = 4;
+- rdev->config.evergreen.max_tile_pipes = 2;
++ rdev->config.evergreen.max_tile_pipes = 4;
+ if (rdev->pdev->device == 0x9648)
+ rdev->config.evergreen.max_simds = 3;
+ else if ((rdev->pdev->device == 0x9647) ||
+@@ -1844,7 +1844,7 @@ static void evergreen_gpu_init(struct ra
+ rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+ rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+ rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+- gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
++ gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_SUMO2:
+ rdev->config.evergreen.num_ses = 1;
+@@ -1866,7 +1866,7 @@ static void evergreen_gpu_init(struct ra
+ rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+ rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+ rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+- gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
++ gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
+ break;
+ case CHIP_BARTS:
+ rdev->config.evergreen.num_ses = 2;
+@@ -1914,7 +1914,7 @@ static void evergreen_gpu_init(struct ra
+ break;
+ case CHIP_CAICOS:
+ rdev->config.evergreen.num_ses = 1;
+- rdev->config.evergreen.max_pipes = 4;
++ rdev->config.evergreen.max_pipes = 2;
+ rdev->config.evergreen.max_tile_pipes = 2;
+ rdev->config.evergreen.max_simds = 2;
+ rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
+--- a/drivers/gpu/drm/radeon/evergreend.h
++++ b/drivers/gpu/drm/radeon/evergreend.h
+@@ -45,6 +45,8 @@
+ #define TURKS_GB_ADDR_CONFIG_GOLDEN 0x02010002
+ #define CEDAR_GB_ADDR_CONFIG_GOLDEN 0x02010001
+ #define CAICOS_GB_ADDR_CONFIG_GOLDEN 0x02010001
++#define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002
++#define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002
+
+ /* Registers */
+
+From d3493574e267c203836bfdcb9c58d8af46fc0da1 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse at redhat.com>
+Date: Fri, 14 Dec 2012 16:20:46 -0500
+Subject: drm/radeon: restore modeset late in GPU reset path
+
+From: Jerome Glisse <jglisse at redhat.com>
+
+commit d3493574e267c203836bfdcb9c58d8af46fc0da1 upstream.
+
+Modeset path seems to conflict sometimes with the memory management
+leading to kernel deadlock. This move modesetting reset after GPU
+acceleration reset.
+
+Signed-off-by: Jerome Glisse <jglisse at redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_device.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -1337,7 +1337,6 @@ retry:
+ }
+
+ radeon_restore_bios_scratch_regs(rdev);
+- drm_helper_resume_force_mode(rdev->ddev);
+
+ if (!r) {
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+@@ -1362,6 +1361,8 @@ retry:
+ }
+ }
+
++ drm_helper_resume_force_mode(rdev->ddev);
++
+ ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
+ if (r) {
+ /* bad news, how to tell it to userspace ? */
+From 76903b96adbfbb38b049765add21e02e44c387a5 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse at redhat.com>
+Date: Mon, 17 Dec 2012 10:29:06 -0500
+Subject: drm/radeon: don't leave fence blocked process on failed GPU reset
+
+From: Jerome Glisse <jglisse at redhat.com>
+
+commit 76903b96adbfbb38b049765add21e02e44c387a5 upstream.
+
+Force all fence to signal if GPU reset failed so no process get stuck
+on waiting fence.
+
+Signed-off-by: Jerome Glisse <jglisse at redhat.com>
+Reviewed-by: Christian König <christian.koenig at amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon.h | 1 +
+ drivers/gpu/drm/radeon/radeon_device.c | 1 +
+ drivers/gpu/drm/radeon/radeon_fence.c | 19 +++++++++++++++++++
+ 3 files changed, 21 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -220,6 +220,7 @@ struct radeon_fence {
+ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
+ int radeon_fence_driver_init(struct radeon_device *rdev);
+ void radeon_fence_driver_fini(struct radeon_device *rdev);
++void radeon_fence_driver_force_completion(struct radeon_device *rdev);
+ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring);
+ void radeon_fence_process(struct radeon_device *rdev, int ring);
+ bool radeon_fence_signaled(struct radeon_fence *fence);
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -1356,6 +1356,7 @@ retry:
+ }
+ }
+ } else {
++ radeon_fence_driver_force_completion(rdev);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ kfree(ring_data[i]);
+ }
+--- a/drivers/gpu/drm/radeon/radeon_fence.c
++++ b/drivers/gpu/drm/radeon/radeon_fence.c
+@@ -868,6 +868,25 @@ void radeon_fence_driver_fini(struct rad
+ mutex_unlock(&rdev->ring_lock);
+ }
+
++/**
++ * radeon_fence_driver_force_completion - force all fence waiter to complete
++ *
++ * @rdev: radeon device pointer
++ *
++ * In case of GPU reset failure make sure no process keep waiting on fence
++ * that will never complete.
++ */
++void radeon_fence_driver_force_completion(struct radeon_device *rdev)
++{
++ int ring;
++
++ for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
++ if (!rdev->fence_drv[ring].initialized)
++ continue;
++ radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
++ }
++}
++
+
+ /*
+ * Fence debugfs
+From 5f8f635edd8ad5a6416bff4c5ff486500357f473 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse at redhat.com>
+Date: Mon, 17 Dec 2012 11:04:32 -0500
+Subject: drm/radeon: avoid deadlock in pm path when waiting for fence
+
+From: Jerome Glisse <jglisse at redhat.com>
+
+commit 5f8f635edd8ad5a6416bff4c5ff486500357f473 upstream.
+
+radeon_fence_wait_empty_locked should not trigger GPU reset as no
+place where it's call from would benefit from such thing and it
+actually lead to a kernel deadlock in case the reset is triggered
+from pm codepath. Instead force ring completion in place where it
+makes sense or return early in others.
+
+Signed-off-by: Jerome Glisse <jglisse at redhat.com>
+Reviewed-by: Christian König <christian.koenig at amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon.h | 2 +-
+ drivers/gpu/drm/radeon/radeon_device.c | 13 +++++++++++--
+ drivers/gpu/drm/radeon/radeon_fence.c | 30 ++++++++++++++----------------
+ drivers/gpu/drm/radeon/radeon_pm.c | 15 ++++++++++++---
+ 4 files changed, 38 insertions(+), 22 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon.h
++++ b/drivers/gpu/drm/radeon/radeon.h
+@@ -226,7 +226,7 @@ void radeon_fence_process(struct radeon_
+ bool radeon_fence_signaled(struct radeon_fence *fence);
+ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
+ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);
+-void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
++int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
+ int radeon_fence_wait_any(struct radeon_device *rdev,
+ struct radeon_fence **fences,
+ bool intr);
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -1163,6 +1163,7 @@ int radeon_suspend_kms(struct drm_device
+ struct drm_crtc *crtc;
+ struct drm_connector *connector;
+ int i, r;
++ bool force_completion = false;
+
+ if (dev == NULL || dev->dev_private == NULL) {
+ return -ENODEV;
+@@ -1205,8 +1206,16 @@ int radeon_suspend_kms(struct drm_device
+
+ mutex_lock(&rdev->ring_lock);
+ /* wait for gpu to finish processing current batch */
+- for (i = 0; i < RADEON_NUM_RINGS; i++)
+- radeon_fence_wait_empty_locked(rdev, i);
++ for (i = 0; i < RADEON_NUM_RINGS; i++) {
++ r = radeon_fence_wait_empty_locked(rdev, i);
++ if (r) {
++ /* delay GPU reset to resume */
++ force_completion = true;
++ }
++ }
++ if (force_completion) {
++ radeon_fence_driver_force_completion(rdev);
++ }
+ mutex_unlock(&rdev->ring_lock);
+
+ radeon_save_bios_scratch_regs(rdev);
+--- a/drivers/gpu/drm/radeon/radeon_fence.c
++++ b/drivers/gpu/drm/radeon/radeon_fence.c
+@@ -609,26 +609,20 @@ int radeon_fence_wait_next_locked(struct
+ * Returns 0 if the fences have passed, error for all other cases.
+ * Caller must hold ring lock.
+ */
+-void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
++int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
+ {
+ uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
++ int r;
+
+- while(1) {
+- int r;
+- r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
++ r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
++ if (r) {
+ if (r == -EDEADLK) {
+- mutex_unlock(&rdev->ring_lock);
+- r = radeon_gpu_reset(rdev);
+- mutex_lock(&rdev->ring_lock);
+- if (!r)
+- continue;
+- }
+- if (r) {
+- dev_err(rdev->dev, "error waiting for ring to become"
+- " idle (%d)\n", r);
++ return -EDEADLK;
+ }
+- return;
++ dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n",
++ ring, r);
+ }
++ return 0;
+ }
+
+ /**
+@@ -854,13 +848,17 @@ int radeon_fence_driver_init(struct rade
+ */
+ void radeon_fence_driver_fini(struct radeon_device *rdev)
+ {
+- int ring;
++ int ring, r;
+
+ mutex_lock(&rdev->ring_lock);
+ for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
+ if (!rdev->fence_drv[ring].initialized)
+ continue;
+- radeon_fence_wait_empty_locked(rdev, ring);
++ r = radeon_fence_wait_empty_locked(rdev, ring);
++ if (r) {
++ /* no need to trigger GPU reset as we are unloading */
++ radeon_fence_driver_force_completion(rdev);
++ }
+ wake_up_all(&rdev->fence_queue);
+ radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
+ rdev->fence_drv[ring].initialized = false;
+--- a/drivers/gpu/drm/radeon/radeon_pm.c
++++ b/drivers/gpu/drm/radeon/radeon_pm.c
+@@ -234,7 +234,7 @@ static void radeon_set_power_state(struc
+
+ static void radeon_pm_set_clocks(struct radeon_device *rdev)
+ {
+- int i;
++ int i, r;
+
+ /* no need to take locks, etc. if nothing's going to change */
+ if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
+@@ -248,8 +248,17 @@ static void radeon_pm_set_clocks(struct
+ /* wait for the rings to drain */
+ for (i = 0; i < RADEON_NUM_RINGS; i++) {
+ struct radeon_ring *ring = &rdev->ring[i];
+- if (ring->ready)
+- radeon_fence_wait_empty_locked(rdev, i);
++ if (!ring->ready) {
++ continue;
++ }
++ r = radeon_fence_wait_empty_locked(rdev, i);
++ if (r) {
++ /* needs a GPU reset dont reset here */
++ mutex_unlock(&rdev->ring_lock);
++ up_write(&rdev->pm.mclk_lock);
++ mutex_unlock(&rdev->ddev->struct_mutex);
++ return;
++ }
+ }
+
+ radeon_unmap_vram_bos(rdev);
+From 668bbc81baf0f34df832d8aca5c7d5e19a493c68 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher at amd.com>
+Date: Thu, 20 Dec 2012 21:19:32 -0500
+Subject: drm/radeon: add WAIT_UNTIL to evergreen VM safe reg list
+
+From: Alex Deucher <alexander.deucher at amd.com>
+
+commit 668bbc81baf0f34df832d8aca5c7d5e19a493c68 upstream.
+
+It's used in a recent mesa commit:
+http://cgit.freedesktop.org/mesa/mesa/commit/?id=24b1206ab2dcd506aaac3ef656aebc8bc20cd27a
+and there may be some other cases in the future where it's required.
+
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Reviewed-by: Jerome Glisse <jglisse at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/evergreen_cs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/gpu/drm/radeon/evergreen_cs.c
++++ b/drivers/gpu/drm/radeon/evergreen_cs.c
+@@ -2724,6 +2724,7 @@ static bool evergreen_vm_reg_valid(u32 r
+
+ /* check config regs */
+ switch (reg) {
++ case WAIT_UNTIL:
+ case GRBM_GFX_INDEX:
+ case CP_STRMOUT_CNTL:
+ case CP_COHER_CNTL:
+From cafa59b9011a7790be4ddd5979419259844a165d Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher at amd.com>
+Date: Thu, 20 Dec 2012 16:35:47 -0500
+Subject: drm/radeon: add connector table for Mac G4 Silver
+
+From: Alex Deucher <alexander.deucher at amd.com>
+
+commit cafa59b9011a7790be4ddd5979419259844a165d upstream.
+
+Apple cards do not provide data tables in the vbios
+so we have to hard code the connector parameters
+in the driver.
+
+Reported-by: Albrecht Dreß <albrecht.dress at arcor.de>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_combios.c | 51 ++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/radeon/radeon_mode.h | 3 +
+ 2 files changed, 53 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_combios.c
++++ b/drivers/gpu/drm/radeon/radeon_combios.c
+@@ -1548,6 +1548,9 @@ bool radeon_get_legacy_connector_info_fr
+ of_machine_is_compatible("PowerBook6,7")) {
+ /* ibook */
+ rdev->mode_info.connector_table = CT_IBOOK;
++ } else if (of_machine_is_compatible("PowerMac3,5")) {
++ /* PowerMac G4 Silver radeon 7500 */
++ rdev->mode_info.connector_table = CT_MAC_G4_SILVER;
+ } else if (of_machine_is_compatible("PowerMac4,4")) {
+ /* emac */
+ rdev->mode_info.connector_table = CT_EMAC;
+@@ -2210,6 +2213,54 @@ bool radeon_get_legacy_connector_info_fr
+ DRM_MODE_CONNECTOR_SVIDEO,
+ &ddc_i2c,
+ CONNECTOR_OBJECT_ID_SVIDEO,
++ &hpd);
++ break;
++ case CT_MAC_G4_SILVER:
++ DRM_INFO("Connector Table: %d (mac g4 silver)\n",
++ rdev->mode_info.connector_table);
++ /* DVI-I - tv dac, int tmds */
++ ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
++ hpd.hpd = RADEON_HPD_1; /* ??? */
++ radeon_add_legacy_encoder(dev,
++ radeon_get_encoder_enum(dev,
++ ATOM_DEVICE_DFP1_SUPPORT,
++ 0),
++ ATOM_DEVICE_DFP1_SUPPORT);
++ radeon_add_legacy_encoder(dev,
++ radeon_get_encoder_enum(dev,
++ ATOM_DEVICE_CRT2_SUPPORT,
++ 2),
++ ATOM_DEVICE_CRT2_SUPPORT);
++ radeon_add_legacy_connector(dev, 0,
++ ATOM_DEVICE_DFP1_SUPPORT |
++ ATOM_DEVICE_CRT2_SUPPORT,
++ DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
++ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
++ &hpd);
++ /* VGA - primary dac */
++ ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
++ hpd.hpd = RADEON_HPD_NONE;
++ radeon_add_legacy_encoder(dev,
++ radeon_get_encoder_enum(dev,
++ ATOM_DEVICE_CRT1_SUPPORT,
++ 1),
++ ATOM_DEVICE_CRT1_SUPPORT);
++ radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT,
++ DRM_MODE_CONNECTOR_VGA, &ddc_i2c,
++ CONNECTOR_OBJECT_ID_VGA,
++ &hpd);
++ /* TV - TV DAC */
++ ddc_i2c.valid = false;
++ hpd.hpd = RADEON_HPD_NONE;
++ radeon_add_legacy_encoder(dev,
++ radeon_get_encoder_enum(dev,
++ ATOM_DEVICE_TV1_SUPPORT,
++ 2),
++ ATOM_DEVICE_TV1_SUPPORT);
++ radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT,
++ DRM_MODE_CONNECTOR_SVIDEO,
++ &ddc_i2c,
++ CONNECTOR_OBJECT_ID_SVIDEO,
+ &hpd);
+ break;
+ default:
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -209,7 +209,8 @@ enum radeon_connector_table {
+ CT_RN50_POWER,
+ CT_MAC_X800,
+ CT_MAC_G5_9600,
+- CT_SAM440EP
++ CT_SAM440EP,
++ CT_MAC_G4_SILVER
+ };
+
+ enum radeon_dvo_chip {
+From 0a9069d34918659bc8a89e21e69e60b2b83291a3 Mon Sep 17 00:00:00 2001
+From: Niels Ole Salscheider <niels_ole at salscheider-online.de>
+Date: Thu, 3 Jan 2013 19:09:28 +0100
+Subject: drm/radeon: Properly handle DDC probe for DP bridges
+
+From: Niels Ole Salscheider <niels_ole at salscheider-online.de>
+
+commit 0a9069d34918659bc8a89e21e69e60b2b83291a3 upstream.
+
+DDC information can be accessed using AUX CH
+
+Fixes failure to probe monitors on some systems with
+DP bridge chips.
+
+agd5f: minor fixes
+
+Signed-off-by: Niels Ole Salscheider <niels_ole at salscheider-online.de>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_connectors.c | 10 ++++++----
+ drivers/gpu/drm/radeon/radeon_display.c | 13 +++++++++----
+ drivers/gpu/drm/radeon/radeon_i2c.c | 10 ++++++++--
+ drivers/gpu/drm/radeon/radeon_mode.h | 2 +-
+ 4 files changed, 24 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_connectors.c
++++ b/drivers/gpu/drm/radeon/radeon_connectors.c
+@@ -741,7 +741,7 @@ radeon_vga_detect(struct drm_connector *
+ ret = connector_status_disconnected;
+
+ if (radeon_connector->ddc_bus)
+- dret = radeon_ddc_probe(radeon_connector);
++ dret = radeon_ddc_probe(radeon_connector, false);
+ if (dret) {
+ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+@@ -947,7 +947,7 @@ radeon_dvi_detect(struct drm_connector *
+ return connector->status;
+
+ if (radeon_connector->ddc_bus)
+- dret = radeon_ddc_probe(radeon_connector);
++ dret = radeon_ddc_probe(radeon_connector, false);
+ if (dret) {
+ radeon_connector->detected_by_load = false;
+ if (radeon_connector->edid) {
+@@ -1401,7 +1401,8 @@ radeon_dp_detect(struct drm_connector *c
+ if (encoder) {
+ /* setup ddc on the bridge */
+ radeon_atom_ext_encoder_setup_ddc(encoder);
+- if (radeon_ddc_probe(radeon_connector)) /* try DDC */
++ /* bridge chips are always aux */
++ if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */
+ ret = connector_status_connected;
+ else if (radeon_connector->dac_load_detect) { /* try load detection */
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+@@ -1419,7 +1420,8 @@ radeon_dp_detect(struct drm_connector *c
+ if (radeon_dp_getdpcd(radeon_connector))
+ ret = connector_status_connected;
+ } else {
+- if (radeon_ddc_probe(radeon_connector))
++ /* try non-aux ddc (DP to DVI/HMDI/etc. adapter) */
++ if (radeon_ddc_probe(radeon_connector, false))
+ ret = connector_status_connected;
+ }
+ }
+--- a/drivers/gpu/drm/radeon/radeon_display.c
++++ b/drivers/gpu/drm/radeon/radeon_display.c
+@@ -695,10 +695,15 @@ int radeon_ddc_get_modes(struct radeon_c
+ if (radeon_connector->router.ddc_valid)
+ radeon_router_select_ddc_port(radeon_connector);
+
+- if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+- (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) ||
+- (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
+- ENCODER_OBJECT_ID_NONE)) {
++ if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
++ ENCODER_OBJECT_ID_NONE) {
++ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
++
++ if (dig->dp_i2c_bus)
++ radeon_connector->edid = drm_get_edid(&radeon_connector->base,
++ &dig->dp_i2c_bus->adapter);
++ } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
++ (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+
+ if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
+--- a/drivers/gpu/drm/radeon/radeon_i2c.c
++++ b/drivers/gpu/drm/radeon/radeon_i2c.c
+@@ -39,7 +39,7 @@ extern u32 radeon_atom_hw_i2c_func(struc
+ * radeon_ddc_probe
+ *
+ */
+-bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
++bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux)
+ {
+ u8 out = 0x0;
+ u8 buf[8];
+@@ -63,7 +63,13 @@ bool radeon_ddc_probe(struct radeon_conn
+ if (radeon_connector->router.ddc_valid)
+ radeon_router_select_ddc_port(radeon_connector);
+
+- ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
++ if (use_aux) {
++ struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
++ ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2);
++ } else {
++ ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
++ }
++
+ if (ret != 2)
+ /* Couldn't find an accessible DDC on this connector */
+ return false;
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -559,7 +559,7 @@ extern void radeon_i2c_put_byte(struct r
+ u8 val);
+ extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
+ extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
+-extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
++extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux);
+ extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
+
+ extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
+From eda85d6ad490923152544fba0473798b6cc0edf6 Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen at iki.fi>
+Date: Mon, 31 Dec 2012 03:34:59 +0200
+Subject: drm/nouveau: fix init with agpgart-uninorth
+
+From: Aaro Koskinen <aaro.koskinen at iki.fi>
+
+commit eda85d6ad490923152544fba0473798b6cc0edf6 upstream.
+
+Check that the AGP aperture can be mapped. This follows a similar change
+done for Radeon (commit 365048ff, drm/radeon: AGP memory is only I/O if
+the aperture can be mapped by the CPU.).
+
+The patch fixes the following error seen on G5 iMac:
+
+ nouveau E[ DRM] failed to create kernel channel, -12
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58806
+Reviewed-by: Michel Dänzer <michel at daenzer.net>
+Signed-off-by: Aaro Koskinen <aaro.koskinen at iki.fi>
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -1279,7 +1279,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo
+ if (drm->agp.stat == ENABLED) {
+ mem->bus.offset = mem->start << PAGE_SHIFT;
+ mem->bus.base = drm->agp.base;
+- mem->bus.is_iomem = true;
++ mem->bus.is_iomem = !dev->agp->cant_use_aperture;
+ }
+ #endif
+ break;
+From 13888d78c664a1f61d7b09d282f5916993827a40 Mon Sep 17 00:00:00 2001
+From: Paulo Zanoni <paulo.r.zanoni at intel.com>
+Date: Tue, 20 Nov 2012 13:27:41 -0200
+Subject: drm/i915: make the panel fitter work on pipes B and C on IVB
+
+From: Paulo Zanoni <paulo.r.zanoni at intel.com>
+
+commit 13888d78c664a1f61d7b09d282f5916993827a40 upstream.
+
+I actually found this problem on Haswell, but then discovered Ivy
+Bridge also has it by reading the spec.
+
+I don't have the hardware to test this.
+
+Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
+Reviewed-by: Damien Lespiau <damien.lespiau at intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_reg.h | 2 ++
+ drivers/gpu/drm/i915/intel_display.c | 6 +++++-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_reg.h
++++ b/drivers/gpu/drm/i915/i915_reg.h
+@@ -3315,6 +3315,8 @@
+ #define _PFA_CTL_1 0x68080
+ #define _PFB_CTL_1 0x68880
+ #define PF_ENABLE (1<<31)
++#define PF_PIPE_SEL_MASK_IVB (3<<29)
++#define PF_PIPE_SEL_IVB(pipe) ((pipe)<<29)
+ #define PF_FILTER_MASK (3<<23)
+ #define PF_FILTER_PROGRAMMED (0<<23)
+ #define PF_FILTER_MED_3x3 (1<<23)
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -3225,7 +3225,11 @@ static void ironlake_crtc_enable(struct
+ * as some pre-programmed values are broken,
+ * e.g. x201.
+ */
+- I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
++ if (IS_IVYBRIDGE(dev))
++ I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3 |
++ PF_PIPE_SEL_IVB(pipe));
++ else
++ I915_WRITE(PF_CTL(pipe), PF_ENABLE | PF_FILTER_MED_3x3);
+ I915_WRITE(PF_WIN_POS(pipe), dev_priv->pch_pf_pos);
+ I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size);
+ }
+From 8fb74b9fb2b182d54beee592350d9ea1f325917a Mon Sep 17 00:00:00 2001
+From: Mel Gorman <mgorman at suse.de>
+Date: Fri, 11 Jan 2013 14:32:16 -0800
+Subject: mm: compaction: partially revert capture of suitable high-order page
+
+From: Mel Gorman <mgorman at suse.de>
+
+commit 8fb74b9fb2b182d54beee592350d9ea1f325917a upstream.
+
+Eric Wong reported on 3.7 and 3.8-rc2 that ppoll() got stuck when
+waiting for POLLIN on a local TCP socket. It was easier to trigger if
+there was disk IO and dirty pages at the same time and he bisected it to
+commit 1fb3f8ca0e92 ("mm: compaction: capture a suitable high-order page
+immediately when it is made available").
+
+The intention of that patch was to improve high-order allocations under
+memory pressure after changes made to reclaim in 3.6 drastically hurt
+THP allocations but the approach was flawed. For Eric, the problem was
+that page->pfmemalloc was not being cleared for captured pages leading
+to a poor interaction with swap-over-NFS support causing the packets to
+be dropped. However, I identified a few more problems with the patch
+including the fact that it can increase contention on zone->lock in some
+cases which could result in async direct compaction being aborted early.
+
+In retrospect the capture patch took the wrong approach. What it should
+have done is mark the pageblock being migrated as MIGRATE_ISOLATE if it
+was allocating for THP and avoided races that way. While the patch was
+showing to improve allocation success rates at the time, the benefit is
+marginal given the relative complexity and it should be revisited from
+scratch in the context of the other reclaim-related changes that have
+taken place since the patch was first written and tested. This patch
+partially reverts commit 1fb3f8ca0e92 ("mm: compaction: capture a
+suitable high-order page immediately when it is made available").
+
+Reported-and-tested-by: Eric Wong <normalperson at yhbt.net>
+Tested-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: Mel Gorman <mgorman at suse.de>
+Cc: David Miller <davem at davemloft.net>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ include/linux/compaction.h | 4 -
+ include/linux/mm.h | 1
+ mm/compaction.c | 92 ++++++---------------------------------------
+ mm/internal.h | 1
+ mm/page_alloc.c | 35 +++--------------
+ 5 files changed, 23 insertions(+), 110 deletions(-)
+
+--- a/include/linux/compaction.h
++++ b/include/linux/compaction.h
+@@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct
+ extern int fragmentation_index(struct zone *zone, unsigned int order);
+ extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
+ int order, gfp_t gfp_mask, nodemask_t *mask,
+- bool sync, bool *contended, struct page **page);
++ bool sync, bool *contended);
+ extern int compact_pgdat(pg_data_t *pgdat, int order);
+ extern void reset_isolation_suitable(pg_data_t *pgdat);
+ extern unsigned long compaction_suitable(struct zone *zone, int order);
+@@ -75,7 +75,7 @@ static inline bool compaction_restarting
+ #else
+ static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
+ int order, gfp_t gfp_mask, nodemask_t *nodemask,
+- bool sync, bool *contended, struct page **page)
++ bool sync, bool *contended)
+ {
+ return COMPACT_CONTINUE;
+ }
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -455,7 +455,6 @@ void put_pages_list(struct list_head *pa
+
+ void split_page(struct page *page, unsigned int order);
+ int split_free_page(struct page *page);
+-int capture_free_page(struct page *page, int alloc_order, int migratetype);
+
+ /*
+ * Compound pages have a destructor function. Provide a
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -214,60 +214,6 @@ static bool suitable_migration_target(st
+ return false;
+ }
+
+-static void compact_capture_page(struct compact_control *cc)
+-{
+- unsigned long flags;
+- int mtype, mtype_low, mtype_high;
+-
+- if (!cc->page || *cc->page)
+- return;
+-
+- /*
+- * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP
+- * regardless of the migratetype of the freelist is is captured from.
+- * This is fine because the order for a high-order MIGRATE_MOVABLE
+- * allocation is typically at least a pageblock size and overall
+- * fragmentation is not impaired. Other allocation types must
+- * capture pages from their own migratelist because otherwise they
+- * could pollute other pageblocks like MIGRATE_MOVABLE with
+- * difficult to move pages and making fragmentation worse overall.
+- */
+- if (cc->migratetype == MIGRATE_MOVABLE) {
+- mtype_low = 0;
+- mtype_high = MIGRATE_PCPTYPES;
+- } else {
+- mtype_low = cc->migratetype;
+- mtype_high = cc->migratetype + 1;
+- }
+-
+- /* Speculatively examine the free lists without zone lock */
+- for (mtype = mtype_low; mtype < mtype_high; mtype++) {
+- int order;
+- for (order = cc->order; order < MAX_ORDER; order++) {
+- struct page *page;
+- struct free_area *area;
+- area = &(cc->zone->free_area[order]);
+- if (list_empty(&area->free_list[mtype]))
+- continue;
+-
+- /* Take the lock and attempt capture of the page */
+- if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc))
+- return;
+- if (!list_empty(&area->free_list[mtype])) {
+- page = list_entry(area->free_list[mtype].next,
+- struct page, lru);
+- if (capture_free_page(page, cc->order, mtype)) {
+- spin_unlock_irqrestore(&cc->zone->lock,
+- flags);
+- *cc->page = page;
+- return;
+- }
+- }
+- spin_unlock_irqrestore(&cc->zone->lock, flags);
+- }
+- }
+-}
+-
+ /*
+ * Isolate free pages onto a private freelist. Caller must hold zone->lock.
+ * If @strict is true, will abort returning 0 on any invalid PFNs or non-free
+@@ -831,6 +777,7 @@ static isolate_migrate_t isolate_migrate
+ static int compact_finished(struct zone *zone,
+ struct compact_control *cc)
+ {
++ unsigned int order;
+ unsigned long watermark;
+
+ if (fatal_signal_pending(current))
+@@ -865,22 +812,16 @@ static int compact_finished(struct zone
+ return COMPACT_CONTINUE;
+
+ /* Direct compactor: Is a suitable page free? */
+- if (cc->page) {
+- /* Was a suitable page captured? */
+- if (*cc->page)
++ for (order = cc->order; order < MAX_ORDER; order++) {
++ struct free_area *area = &zone->free_area[order];
++
++ /* Job done if page is free of the right migratetype */
++ if (!list_empty(&area->free_list[cc->migratetype]))
++ return COMPACT_PARTIAL;
++
++ /* Job done if allocation would set block type */
++ if (cc->order >= pageblock_order && area->nr_free)
+ return COMPACT_PARTIAL;
+- } else {
+- unsigned int order;
+- for (order = cc->order; order < MAX_ORDER; order++) {
+- struct free_area *area = &zone->free_area[cc->order];
+- /* Job done if page is free of the right migratetype */
+- if (!list_empty(&area->free_list[cc->migratetype]))
+- return COMPACT_PARTIAL;
+-
+- /* Job done if allocation would set block type */
+- if (cc->order >= pageblock_order && area->nr_free)
+- return COMPACT_PARTIAL;
+- }
+ }
+
+ return COMPACT_CONTINUE;
+@@ -1018,9 +959,6 @@ static int compact_zone(struct zone *zon
+ goto out;
+ }
+ }
+-
+- /* Capture a page now if it is a suitable size */
+- compact_capture_page(cc);
+ }
+
+ out:
+@@ -1033,8 +971,7 @@ out:
+
+ static unsigned long compact_zone_order(struct zone *zone,
+ int order, gfp_t gfp_mask,
+- bool sync, bool *contended,
+- struct page **page)
++ bool sync, bool *contended)
+ {
+ unsigned long ret;
+ struct compact_control cc = {
+@@ -1044,7 +981,6 @@ static unsigned long compact_zone_order(
+ .migratetype = allocflags_to_migratetype(gfp_mask),
+ .zone = zone,
+ .sync = sync,
+- .page = page,
+ };
+ INIT_LIST_HEAD(&cc.freepages);
+ INIT_LIST_HEAD(&cc.migratepages);
+@@ -1074,7 +1010,7 @@ int sysctl_extfrag_threshold = 500;
+ */
+ unsigned long try_to_compact_pages(struct zonelist *zonelist,
+ int order, gfp_t gfp_mask, nodemask_t *nodemask,
+- bool sync, bool *contended, struct page **page)
++ bool sync, bool *contended)
+ {
+ enum zone_type high_zoneidx = gfp_zone(gfp_mask);
+ int may_enter_fs = gfp_mask & __GFP_FS;
+@@ -1100,7 +1036,7 @@ unsigned long try_to_compact_pages(struc
+ int status;
+
+ status = compact_zone_order(zone, order, gfp_mask, sync,
+- contended, page);
++ contended);
+ rc = max(status, rc);
+
+ /* If a normal allocation would succeed, stop compacting */
+@@ -1156,7 +1092,6 @@ int compact_pgdat(pg_data_t *pgdat, int
+ struct compact_control cc = {
+ .order = order,
+ .sync = false,
+- .page = NULL,
+ };
+
+ return __compact_pgdat(pgdat, &cc);
+@@ -1167,7 +1102,6 @@ static int compact_node(int nid)
+ struct compact_control cc = {
+ .order = -1,
+ .sync = true,
+- .page = NULL,
+ };
+
+ return __compact_pgdat(NODE_DATA(nid), &cc);
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -130,7 +130,6 @@ struct compact_control {
+ int migratetype; /* MOVABLE, RECLAIMABLE etc */
+ struct zone *zone;
+ bool contended; /* True if a lock was contended */
+- struct page **page; /* Page captured of requested size */
+ };
+
+ unsigned long
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1376,14 +1376,8 @@ void split_page(struct page *page, unsig
+ set_page_refcounted(page + i);
+ }
+
+-/*
+- * Similar to the split_page family of functions except that the page
+- * required at the given order and being isolated now to prevent races
+- * with parallel allocators
+- */
+-int capture_free_page(struct page *page, int alloc_order, int migratetype)
++static int __isolate_free_page(struct page *page, unsigned int order)
+ {
+- unsigned int order;
+ unsigned long watermark;
+ struct zone *zone;
+ int mt;
+@@ -1391,7 +1385,6 @@ int capture_free_page(struct page *page,
+ BUG_ON(!PageBuddy(page));
+
+ zone = page_zone(page);
+- order = page_order(page);
+
+ /* Obey watermarks as if the page was being allocated */
+ watermark = low_wmark_pages(zone) + (1 << order);
+@@ -1405,13 +1398,9 @@ int capture_free_page(struct page *page,
+
+ mt = get_pageblock_migratetype(page);
+ if (unlikely(mt != MIGRATE_ISOLATE))
+- __mod_zone_freepage_state(zone, -(1UL << alloc_order), mt);
+-
+- if (alloc_order != order)
+- expand(zone, page, alloc_order, order,
+- &zone->free_area[order], migratetype);
++ __mod_zone_freepage_state(zone, -(1UL << order), mt);
+
+- /* Set the pageblock if the captured page is at least a pageblock */
++ /* Set the pageblock if the isolated page is at least a pageblock */
+ if (order >= pageblock_order - 1) {
+ struct page *endpage = page + (1 << order) - 1;
+ for (; page < endpage; page += pageblock_nr_pages) {
+@@ -1422,7 +1411,7 @@ int capture_free_page(struct page *page,
+ }
+ }
+
+- return 1UL << alloc_order;
++ return 1UL << order;
+ }
+
+ /*
+@@ -1440,10 +1429,9 @@ int split_free_page(struct page *page)
+ unsigned int order;
+ int nr_pages;
+
+- BUG_ON(!PageBuddy(page));
+ order = page_order(page);
+
+- nr_pages = capture_free_page(page, order, 0);
++ nr_pages = __isolate_free_page(page, order);
+ if (!nr_pages)
+ return 0;
+
+@@ -2148,8 +2136,6 @@ __alloc_pages_direct_compact(gfp_t gfp_m
+ bool *contended_compaction, bool *deferred_compaction,
+ unsigned long *did_some_progress)
+ {
+- struct page *page = NULL;
+-
+ if (!order)
+ return NULL;
+
+@@ -2161,16 +2147,12 @@ __alloc_pages_direct_compact(gfp_t gfp_m
+ current->flags |= PF_MEMALLOC;
+ *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask,
+ nodemask, sync_migration,
+- contended_compaction, &page);
++ contended_compaction);
+ current->flags &= ~PF_MEMALLOC;
+
+- /* If compaction captured a page, prep and use it */
+- if (page) {
+- prep_new_page(page, order, gfp_mask);
+- goto got_page;
+- }
+-
+ if (*did_some_progress != COMPACT_SKIPPED) {
++ struct page *page;
++
+ /* Page migration frees to the PCP lists but we want merging */
+ drain_pages(get_cpu());
+ put_cpu();
+@@ -2180,7 +2162,6 @@ __alloc_pages_direct_compact(gfp_t gfp_m
+ alloc_flags & ~ALLOC_NO_WATERMARKS,
+ preferred_zone, migratetype);
+ if (page) {
+-got_page:
+ preferred_zone->compact_blockskip_flush = false;
+ preferred_zone->compact_considered = 0;
+ preferred_zone->compact_defer_shift = 0;
+From e7d841ca03b7ab668620045cd7b428eda9f41601 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Mon, 3 Dec 2012 11:36:30 +0000
+Subject: drm/i915: Close race between processing unpin task and queueing the flip
+
+From: Chris Wilson <chris at chris-wilson.co.uk>
+
+commit e7d841ca03b7ab668620045cd7b428eda9f41601 upstream.
+
+Before queuing the flip but crucially after attaching the unpin-work to
+the crtc, we continue to setup the unpin-work. However, should the
+hardware fire early, we see the connected unpin-work and queue the task.
+The task then promptly runs and unpins the fb before we finish taking
+the required references or even pinning it... Havoc.
+
+To close the race, we use the flip-pending atomic to indicate when the
+flip is finally setup and enqueued. So during the flip-done processing,
+we can check more accurately whether the flip was expected.
+
+v2: Add the appropriate mb() to ensure that the writes to the page-flip
+worker are complete prior to marking it active and emitting the MI_FLIP.
+On the read side, the mb should be enforced by the spinlocks.
+
+Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
+[danvet: Review the barriers a bit, we need a write barrier both
+before and after updating ->pending. Similarly we need a read barrier
+in the interrupt handler both before and after reading ->pending. With
+well-ordered irqs only one barrier in each place should be required,
+but since this patch explicitly sets out to combat spurious interrupts
+with is staged activation of the unpin work we need to go full-bore on
+the barriers, too. Discussed with Chris Wilson on irc and changes
+acked by him.]
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_debugfs.c | 4 +--
+ drivers/gpu/drm/i915/i915_irq.c | 4 ++-
+ drivers/gpu/drm/i915/intel_display.c | 39 ++++++++++++++++++++++++++++-------
+ drivers/gpu/drm/i915/intel_drv.h | 5 +++-
+ 4 files changed, 41 insertions(+), 11 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_debugfs.c
++++ b/drivers/gpu/drm/i915/i915_debugfs.c
+@@ -317,7 +317,7 @@ static int i915_gem_pageflip_info(struct
+ seq_printf(m, "No flip due on pipe %c (plane %c)\n",
+ pipe, plane);
+ } else {
+- if (!work->pending) {
++ if (atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
+ seq_printf(m, "Flip queued on pipe %c (plane %c)\n",
+ pipe, plane);
+ } else {
+@@ -328,7 +328,7 @@ static int i915_gem_pageflip_info(struct
+ seq_printf(m, "Stall check enabled, ");
+ else
+ seq_printf(m, "Stall check waiting for page flip ioctl, ");
+- seq_printf(m, "%d prepares\n", work->pending);
++ seq_printf(m, "%d prepares\n", atomic_read(&work->pending));
+
+ if (work->old_fb_obj) {
+ struct drm_i915_gem_object *obj = work->old_fb_obj;
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1464,7 +1464,9 @@ static void i915_pageflip_stall_check(st
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = intel_crtc->unpin_work;
+
+- if (work == NULL || work->pending || !work->enable_stall_check) {
++ if (work == NULL ||
++ atomic_read(&work->pending) >= INTEL_FLIP_COMPLETE ||
++ !work->enable_stall_check) {
+ /* Either the pending flip IRQ arrived, or we're too early. Don't check */
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ return;
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -6215,11 +6215,18 @@ static void do_intel_finish_page_flip(st
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ work = intel_crtc->unpin_work;
+- if (work == NULL || !work->pending) {
++
++ /* Ensure we don't miss a work->pending update ... */
++ smp_rmb();
++
++ if (work == NULL || atomic_read(&work->pending) < INTEL_FLIP_COMPLETE) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ return;
+ }
+
++ /* and that the unpin work is consistent wrt ->pending. */
++ smp_rmb();
++
+ intel_crtc->unpin_work = NULL;
+
+ if (work->event) {
+@@ -6272,16 +6279,25 @@ void intel_prepare_page_flip(struct drm_
+ to_intel_crtc(dev_priv->plane_to_crtc_mapping[plane]);
+ unsigned long flags;
+
++ /* NB: An MMIO update of the plane base pointer will also
++ * generate a page-flip completion irq, i.e. every modeset
++ * is also accompanied by a spurious intel_prepare_page_flip().
++ */
+ spin_lock_irqsave(&dev->event_lock, flags);
+- if (intel_crtc->unpin_work) {
+- if ((++intel_crtc->unpin_work->pending) > 1)
+- DRM_ERROR("Prepared flip multiple times\n");
+- } else {
+- DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
+- }
++ if (intel_crtc->unpin_work)
++ atomic_inc_not_zero(&intel_crtc->unpin_work->pending);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
+
++inline static void intel_mark_page_flip_active(struct intel_crtc *intel_crtc)
++{
++ /* Ensure that the work item is consistent when activating it ... */
++ smp_wmb();
++ atomic_set(&intel_crtc->unpin_work->pending, INTEL_FLIP_PENDING);
++ /* and that it is marked active as soon as the irq could fire. */
++ smp_wmb();
++}
++
+ static int intel_gen2_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+@@ -6315,6 +6331,8 @@ static int intel_gen2_queue_flip(struct
+ intel_ring_emit(ring, fb->pitches[0]);
+ intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
+ intel_ring_emit(ring, 0); /* aux display base address, unused */
++
++ intel_mark_page_flip_active(intel_crtc);
+ intel_ring_advance(ring);
+ return 0;
+
+@@ -6355,6 +6373,7 @@ static int intel_gen3_queue_flip(struct
+ intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
+ intel_ring_emit(ring, MI_NOOP);
+
++ intel_mark_page_flip_active(intel_crtc);
+ intel_ring_advance(ring);
+ return 0;
+
+@@ -6401,6 +6420,8 @@ static int intel_gen4_queue_flip(struct
+ pf = 0;
+ pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+ intel_ring_emit(ring, pf | pipesrc);
++
++ intel_mark_page_flip_active(intel_crtc);
+ intel_ring_advance(ring);
+ return 0;
+
+@@ -6443,6 +6464,8 @@ static int intel_gen6_queue_flip(struct
+ pf = 0;
+ pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+ intel_ring_emit(ring, pf | pipesrc);
++
++ intel_mark_page_flip_active(intel_crtc);
+ intel_ring_advance(ring);
+ return 0;
+
+@@ -6497,6 +6520,8 @@ static int intel_gen7_queue_flip(struct
+ intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
+ intel_ring_emit(ring, obj->gtt_offset + intel_crtc->dspaddr_offset);
+ intel_ring_emit(ring, (MI_NOOP));
++
++ intel_mark_page_flip_active(intel_crtc);
+ intel_ring_advance(ring);
+ return 0;
+
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -384,7 +384,10 @@ struct intel_unpin_work {
+ struct drm_i915_gem_object *old_fb_obj;
+ struct drm_i915_gem_object *pending_flip_obj;
+ struct drm_pending_vblank_event *event;
+- int pending;
++ atomic_t pending;
++#define INTEL_FLIP_INACTIVE 0
++#define INTEL_FLIP_PENDING 1
++#define INTEL_FLIP_COMPLETE 2
+ bool enable_stall_check;
+ };
+
+From b4a98e57fc27854b5938fc8b08b68e5e68b91e1f Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Thu, 1 Nov 2012 09:26:26 +0000
+Subject: drm/i915: Flush outstanding unpin tasks before pageflipping
+
+From: Chris Wilson <chris at chris-wilson.co.uk>
+
+commit b4a98e57fc27854b5938fc8b08b68e5e68b91e1f upstream.
+
+If we accumulate unpin tasks because we are pageflipping faster than the
+system can schedule its workers, we can effectively create a
+pin-leak. The solution taken here is to limit the number of unpin tasks
+we have per-crtc and to flush those outstanding tasks if we accumulate
+too many. This should prevent any jitter in the normal case, and also
+prevent the hang if we should run too fast.
+
+Note: It is important that we switch from the system workqueue to our
+own dev_priv->wq since all work items on that queue are guaranteed to
+only need the dev->struct_mutex and not any modeset resources. For
+otherwise if we have a work item ahead in the queue which needs the
+modeset lock (like the output detect work used by both polling or
+hpd), this work and so the unpin work will never execute since the
+pageflip code already holds that lock. Unfortunately there's no
+lockdep support for this scenario in the workqueue code.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46991
+Reported-and-tested-by: Tvrtko Ursulin <tvrtko.ursulin at onelan.co.uk>
+Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
+[danvet: Added note about workqueu deadlock.]
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56337
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Tested-by: Daniel Gnoutcheff <daniel at gnoutcheff.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++++------
+ drivers/gpu/drm/i915/intel_drv.h | 4 +++-
+ 2 files changed, 19 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -6187,14 +6187,19 @@ static void intel_unpin_work_fn(struct w
+ {
+ struct intel_unpin_work *work =
+ container_of(__work, struct intel_unpin_work, work);
++ struct drm_device *dev = work->crtc->dev;
+
+- mutex_lock(&work->dev->struct_mutex);
++ mutex_lock(&dev->struct_mutex);
+ intel_unpin_fb_obj(work->old_fb_obj);
+ drm_gem_object_unreference(&work->pending_flip_obj->base);
+ drm_gem_object_unreference(&work->old_fb_obj->base);
+
+- intel_update_fbc(work->dev);
+- mutex_unlock(&work->dev->struct_mutex);
++ intel_update_fbc(dev);
++ mutex_unlock(&dev->struct_mutex);
++
++ BUG_ON(atomic_read(&to_intel_crtc(work->crtc)->unpin_work_count) == 0);
++ atomic_dec(&to_intel_crtc(work->crtc)->unpin_work_count);
++
+ kfree(work);
+ }
+
+@@ -6249,9 +6254,9 @@ static void do_intel_finish_page_flip(st
+
+ atomic_clear_mask(1 << intel_crtc->plane,
+ &obj->pending_flip.counter);
+-
+ wake_up(&dev_priv->pending_flip_queue);
+- schedule_work(&work->work);
++
++ queue_work(dev_priv->wq, &work->work);
+
+ trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
+ }
+@@ -6570,7 +6575,7 @@ static int intel_crtc_page_flip(struct d
+ return -ENOMEM;
+
+ work->event = event;
+- work->dev = crtc->dev;
++ work->crtc = crtc;
+ intel_fb = to_intel_framebuffer(crtc->fb);
+ work->old_fb_obj = intel_fb->obj;
+ INIT_WORK(&work->work, intel_unpin_work_fn);
+@@ -6595,6 +6600,9 @@ static int intel_crtc_page_flip(struct d
+ intel_fb = to_intel_framebuffer(fb);
+ obj = intel_fb->obj;
+
++ if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
++ flush_workqueue(dev_priv->wq);
++
+ ret = i915_mutex_lock_interruptible(dev);
+ if (ret)
+ goto cleanup;
+@@ -6613,6 +6621,7 @@ static int intel_crtc_page_flip(struct d
+ * the flip occurs and the object is no longer visible.
+ */
+ atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
++ atomic_inc(&intel_crtc->unpin_work_count);
+
+ ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
+ if (ret)
+@@ -6627,6 +6636,7 @@ static int intel_crtc_page_flip(struct d
+ return 0;
+
+ cleanup_pending:
++ atomic_dec(&intel_crtc->unpin_work_count);
+ atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
+ drm_gem_object_unreference(&work->old_fb_obj->base);
+ drm_gem_object_unreference(&obj->base);
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -198,6 +198,8 @@ struct intel_crtc {
+ struct intel_unpin_work *unpin_work;
+ int fdi_lanes;
+
++ atomic_t unpin_work_count;
++
+ /* Display surface base address adjustement for pageflips. Note that on
+ * gen4+ this only adjusts up to a tile, offsets within a tile are
+ * handled in the hw itself (with the TILEOFF register). */
+@@ -380,7 +382,7 @@ intel_get_crtc_for_plane(struct drm_devi
+
+ struct intel_unpin_work {
+ struct work_struct work;
+- struct drm_device *dev;
++ struct drm_crtc *crtc;
+ struct drm_i915_gem_object *old_fb_obj;
+ struct drm_i915_gem_object *pending_flip_obj;
+ struct drm_pending_vblank_event *event;
+From b0a2658acb5bf9ca86b4aab011b7106de3af0add Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Tue, 18 Dec 2012 09:37:54 +0100
+Subject: drm/i915: don't disable disconnected outputs
+
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+
+commit b0a2658acb5bf9ca86b4aab011b7106de3af0add upstream.
+
+This piece of neat lore has been ported painstakingly and bug-for-bug
+compatible from the old crtc helper code.
+
+Imo it's utter nonsense.
+
+If you disconnected a cable and before you reconnect it, userspace (or
+the kernel) does an set_crtc call, this will result in that connector
+getting disabled. Which will result in a nice black screen when
+plugging in the cable again.
+
+There's absolutely no reason the kernel does such policy enforcements
+- if userspace tries to set up a mode on something disconnected we
+might fail loudly (since the dp link training fails), but silently
+adjusting the output configuration behind userspace's back is a recipe
+for disaster. Specifically I think that this could explain some of our
+MI_WAIT hangs around suspend, where userspace issues a scanline wait
+on a disable pipe. This mechanisims here could explain how that pipe
+got disabled without userspace noticing.
+
+Note that this fixes a NULL deref at BIOS takeover when the firmware
+sets up a disconnected output in a clone configuration with a
+connected output on the 2nd pipe: When doing the full modeset we don't
+have a mode for the 2nd pipe and OOPS. On the first pipe this doesn't
+matter, since at boot-up the fbdev helpers will set up the choosen
+configuration on that on first. Since this is now the umptenth bug
+around handling this imo brain-dead semantics correctly, I think it's
+time to kill it and see whether there's any userspace out there which
+relies on this.
+
+It also nicely demonstrates that we have a tiny window where DP
+hotplug can still kill the driver.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58396
+Tested-by: Peter Ujfalusi <peter.ujfalusi at gmail.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi at gmail.com>
+Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -7298,10 +7298,6 @@ intel_modeset_stage_output_state(struct
+ DRM_DEBUG_KMS("encoder changed, full mode switch\n");
+ config->mode_changed = true;
+ }
+-
+- /* Disable all disconnected encoders. */
+- if (connector->base.status == connector_status_disconnected)
+- connector->new_encoder = NULL;
+ }
+ /* connector->new_encoder is now updated for all connectors. */
+
+From 5b42427fc38ecb9056c4e64deaff36d6d6ba1b67 Mon Sep 17 00:00:00 2001
+From: Dave Airlie <airlied at redhat.com>
+Date: Thu, 20 Dec 2012 10:51:09 +1000
+Subject: drm/i915: fix flags in dma buf exporting
+
+From: Dave Airlie <airlied at redhat.com>
+
+commit 5b42427fc38ecb9056c4e64deaff36d6d6ba1b67 upstream.
+
+As pointed out by Seung-Woo Kim this should have been
+passing flags like nouveau/radeon have.
+
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+@@ -226,7 +226,7 @@ struct dma_buf *i915_gem_prime_export(st
+ {
+ struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
+
+- return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, 0600);
++ return dma_buf_export(obj, &i915_dmabuf_ops, obj->base.size, flags);
+ }
+
+ static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+From be8a42ae60addd8b6092535c11b42d099d6470ec Mon Sep 17 00:00:00 2001
+From: Seung-Woo Kim <sw0312.kim at samsung.com>
+Date: Thu, 27 Sep 2012 15:30:06 +0900
+Subject: drm/prime: drop reference on imported dma-buf come from gem
+
+From: Seung-Woo Kim <sw0312.kim at samsung.com>
+
+commit be8a42ae60addd8b6092535c11b42d099d6470ec upstream.
+
+Increasing ref counts of both dma-buf and gem for imported dma-buf come from gem
+makes memory leak. release function of dma-buf cannot be called because f_count
+of dma-buf increased by importing gem and gem ref count cannot be decrease
+because of exported dma-buf.
+
+So I add dma_buf_put() for imported gem come from its own gem into each drivers
+having prime_import and prime_export capabilities. With this, only gem ref
+count is increased if importing gem exported from gem of same driver.
+
+Signed-off-by: Seung-Woo Kim <sw0312.kim at samsung.com>
+Signed-off-by: Kyungmin.park <kyungmin.park at samsung.com>
+Cc: Inki Dae <inki.dae at samsung.com>
+Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
+Cc: Rob Clark <rob.clark at linaro.org>
+Cc: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 5 +++++
+ drivers/gpu/drm/i915/i915_gem_dmabuf.c | 5 +++++
+ drivers/gpu/drm/nouveau/nouveau_prime.c | 1 +
+ drivers/gpu/drm/radeon/radeon_prime.c | 1 +
+ drivers/staging/omapdrm/omap_gem_dmabuf.c | 5 +++++
+ 5 files changed, 17 insertions(+)
+
+--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+@@ -210,7 +210,12 @@ struct drm_gem_object *exynos_dmabuf_pri
+
+ /* is it from our device? */
+ if (obj->dev == drm_dev) {
++ /*
++ * Importing dmabuf exported from out own gem increases
++ * refcount on gem itself instead of f_count of dmabuf.
++ */
+ drm_gem_object_reference(obj);
++ dma_buf_put(dma_buf);
+ return obj;
+ }
+ }
+--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
++++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+@@ -266,7 +266,12 @@ struct drm_gem_object *i915_gem_prime_im
+ obj = dma_buf->priv;
+ /* is it from our device? */
+ if (obj->base.dev == dev) {
++ /*
++ * Importing dmabuf exported from out own gem increases
++ * refcount on gem itself instead of f_count of dmabuf.
++ */
+ drm_gem_object_reference(&obj->base);
++ dma_buf_put(dma_buf);
+ return &obj->base;
+ }
+ }
+--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
++++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
+@@ -197,6 +197,7 @@ struct drm_gem_object *nouveau_gem_prime
+ if (nvbo->gem) {
+ if (nvbo->gem->dev == dev) {
+ drm_gem_object_reference(nvbo->gem);
++ dma_buf_put(dma_buf);
+ return nvbo->gem;
+ }
+ }
+--- a/drivers/gpu/drm/radeon/radeon_prime.c
++++ b/drivers/gpu/drm/radeon/radeon_prime.c
+@@ -194,6 +194,7 @@ struct drm_gem_object *radeon_gem_prime_
+ bo = dma_buf->priv;
+ if (bo->gem_base.dev == dev) {
+ drm_gem_object_reference(&bo->gem_base);
++ dma_buf_put(dma_buf);
+ return &bo->gem_base;
+ }
+ }
+--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
++++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
+@@ -207,7 +207,12 @@ struct drm_gem_object * omap_gem_prime_i
+ obj = buffer->priv;
+ /* is it from our device? */
+ if (obj->dev == dev) {
++ /*
++ * Importing dmabuf exported from out own gem increases
++ * refcount on gem itself instead of f_count of dmabuf.
++ */
+ drm_gem_object_reference(obj);
++ dma_buf_put(buffer);
+ return obj;
+ }
+ }
+From 901593f2bf221659a605bdc1dcb11376ea934163 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Wed, 19 Dec 2012 16:51:06 +0000
+Subject: drm: Only evict the blocks required to create the requested hole
+
+From: Chris Wilson <chris at chris-wilson.co.uk>
+
+commit 901593f2bf221659a605bdc1dcb11376ea934163 upstream.
+
+Avoid clobbering adjacent blocks if they happen to expire earlier and
+amalgamate together to form the requested hole.
+
+In passing this fixes a regression from
+commit ea7b1dd44867e9cd6bac67e7c9fc3f128b5b255c
+Author: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Fri Feb 18 17:59:12 2011 +0100
+
+ drm: mm: track free areas implicitly
+
+which swaps the end address for size (with a potential overflow) and
+effectively causes the eviction code to clobber almost all earlier
+buffers above the evictee.
+
+v2: Check the original hole not the adjusted as the coloring may confuse
+us when later searching for the overlapping nodes. Also make sure that
+we do apply the range restriction and color adjustment in the same
+order for both scanning, searching and insertion.
+
+v3: Send the version that was actually tested.
+
+Note that this seems to be ducttape of decent quality ot paper over
+some of our unbind related gpu hangs reported since 3.7. It is not
+fully effective though, and certainly doesn't fix the underlying bug.
+
+Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
+Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
+[danvet: Added note plus bugzilla link and tested-by.]
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55984
+Tested-by: Norbert Preining <preining at logic.at>
+Acked-by: Dave Airlie <airlied at gmail.com
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_mm.c | 45 +++++++++++++++++----------------------------
+ include/drm/drm_mm.h | 2 +-
+ 2 files changed, 18 insertions(+), 29 deletions(-)
+
+--- a/drivers/gpu/drm/drm_mm.c
++++ b/drivers/gpu/drm/drm_mm.c
+@@ -213,11 +213,13 @@ static void drm_mm_insert_helper_range(s
+
+ BUG_ON(!hole_node->hole_follows || node->allocated);
+
+- if (mm->color_adjust)
+- mm->color_adjust(hole_node, color, &adj_start, &adj_end);
+-
+ if (adj_start < start)
+ adj_start = start;
++ if (adj_end > end)
++ adj_end = end;
++
++ if (mm->color_adjust)
++ mm->color_adjust(hole_node, color, &adj_start, &adj_end);
+
+ if (alignment) {
+ unsigned tmp = adj_start % alignment;
+@@ -489,7 +491,7 @@ void drm_mm_init_scan(struct drm_mm *mm,
+ mm->scan_size = size;
+ mm->scanned_blocks = 0;
+ mm->scan_hit_start = 0;
+- mm->scan_hit_size = 0;
++ mm->scan_hit_end = 0;
+ mm->scan_check_range = 0;
+ mm->prev_scanned_node = NULL;
+ }
+@@ -516,7 +518,7 @@ void drm_mm_init_scan_with_range(struct
+ mm->scan_size = size;
+ mm->scanned_blocks = 0;
+ mm->scan_hit_start = 0;
+- mm->scan_hit_size = 0;
++ mm->scan_hit_end = 0;
+ mm->scan_start = start;
+ mm->scan_end = end;
+ mm->scan_check_range = 1;
+@@ -535,8 +537,7 @@ int drm_mm_scan_add_block(struct drm_mm_
+ struct drm_mm *mm = node->mm;
+ struct drm_mm_node *prev_node;
+ unsigned long hole_start, hole_end;
+- unsigned long adj_start;
+- unsigned long adj_end;
++ unsigned long adj_start, adj_end;
+
+ mm->scanned_blocks++;
+
+@@ -553,14 +554,8 @@ int drm_mm_scan_add_block(struct drm_mm_
+ node->node_list.next = &mm->prev_scanned_node->node_list;
+ mm->prev_scanned_node = node;
+
+- hole_start = drm_mm_hole_node_start(prev_node);
+- hole_end = drm_mm_hole_node_end(prev_node);
+-
+- adj_start = hole_start;
+- adj_end = hole_end;
+-
+- if (mm->color_adjust)
+- mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end);
++ adj_start = hole_start = drm_mm_hole_node_start(prev_node);
++ adj_end = hole_end = drm_mm_hole_node_end(prev_node);
+
+ if (mm->scan_check_range) {
+ if (adj_start < mm->scan_start)
+@@ -569,11 +564,14 @@ int drm_mm_scan_add_block(struct drm_mm_
+ adj_end = mm->scan_end;
+ }
+
++ if (mm->color_adjust)
++ mm->color_adjust(prev_node, mm->scan_color,
++ &adj_start, &adj_end);
++
+ if (check_free_hole(adj_start, adj_end,
+ mm->scan_size, mm->scan_alignment)) {
+ mm->scan_hit_start = hole_start;
+- mm->scan_hit_size = hole_end;
+-
++ mm->scan_hit_end = hole_end;
+ return 1;
+ }
+
+@@ -609,19 +607,10 @@ int drm_mm_scan_remove_block(struct drm_
+ node_list);
+
+ prev_node->hole_follows = node->scanned_preceeds_hole;
+- INIT_LIST_HEAD(&node->node_list);
+ list_add(&node->node_list, &prev_node->node_list);
+
+- /* Only need to check for containement because start&size for the
+- * complete resulting free block (not just the desired part) is
+- * stored. */
+- if (node->start >= mm->scan_hit_start &&
+- node->start + node->size
+- <= mm->scan_hit_start + mm->scan_hit_size) {
+- return 1;
+- }
+-
+- return 0;
++ return (drm_mm_hole_node_end(node) > mm->scan_hit_start &&
++ node->start < mm->scan_hit_end);
+ }
+ EXPORT_SYMBOL(drm_mm_scan_remove_block);
+
+--- a/include/drm/drm_mm.h
++++ b/include/drm/drm_mm.h
+@@ -70,7 +70,7 @@ struct drm_mm {
+ unsigned long scan_color;
+ unsigned long scan_size;
+ unsigned long scan_hit_start;
+- unsigned scan_hit_size;
++ unsigned long scan_hit_end;
+ unsigned scanned_blocks;
+ unsigned long scan_start;
+ unsigned long scan_end;
+From 93be8788e648817d62fda33e2998eb6ca6ebf3a3 Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Wed, 2 Jan 2013 10:31:22 +0000
+Subject: drm/i915; Only increment the user-pin-count after successfully pinning the bo
+
+From: Chris Wilson <chris at chris-wilson.co.uk>
+
+commit 93be8788e648817d62fda33e2998eb6ca6ebf3a3 upstream.
+
+As along the error path we do not correct the user pin-count for the
+failure, we may end up with userspace believing that it has a pinned
+object at offset 0 (when interrupted by a signal for example).
+
+Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_gem.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -3511,14 +3511,15 @@ i915_gem_pin_ioctl(struct drm_device *de
+ goto out;
+ }
+
+- obj->user_pin_count++;
+- obj->pin_filp = file;
+- if (obj->user_pin_count == 1) {
++ if (obj->user_pin_count == 0) {
+ ret = i915_gem_object_pin(obj, args->alignment, true, false);
+ if (ret)
+ goto out;
+ }
+
++ obj->user_pin_count++;
++ obj->pin_filp = file;
++
+ /* XXX - flush the CPU caches for pinned objects
+ * as the X server doesn't manage domains yet
+ */
+From 93927ca52a55c23e0a6a305e7e9082e8411ac9fa Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Thu, 10 Jan 2013 18:03:00 +0100
+Subject: drm/i915: Revert shrinker changes from "Track unbound pages"
+
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+
+commit 93927ca52a55c23e0a6a305e7e9082e8411ac9fa upstream.
+
+This partially reverts
+
+commit 6c085a728cf000ac1865d66f8c9b52935558b328
+Author: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Mon Aug 20 11:40:46 2012 +0200
+
+ drm/i915: Track unbound pages
+
+Closer inspection of that patch revealed a bunch of unrelated changes
+in the shrinker:
+- The shrinker count is now in pages instead of objects.
+- For counting the shrinkable objects the old code only looked at the
+ inactive list, the new code looks at all bounds objects (including
+ pinned ones). That is obviously in addition to the new unbound list.
+- The shrinker cound is no longer scaled with
+ sysctl_vfs_cache_pressure. Note though that with the default tuning
+ value of vfs_cache_pressue = 100 this doesn't affect the shrinker
+ behaviour.
+- When actually shrinking objects, the old code first dropped
+ purgeable objects, then normal (inactive) objects. Only then did it,
+ in a last-ditch effort idle the gpu and evict everything. The new
+ code omits the intermediate step of evicting normal inactive
+ objects.
+
+Safe for the first change, which seems benign, and the shrinker count
+scaling, which is a bit a different story, the endresult of all these
+changes is that the shrinker is _much_ more likely to fall back to the
+last-ditch resort of idling the gpu and evicting everything. The old
+code could only do that if something else evicted lots of objects
+meanwhile (since without any other changes the nr_to_scan will be
+smaller than the object count).
+
+Reverting the vfs_cache_pressure behaviour itself is a bit bogus: Only
+dentry/inode object caches should scale their shrinker counts with
+vfs_cache_pressure. Originally I've had that change reverted, too. But
+Chris Wilson insisted that it's too bogus and shouldn't again see the
+light of day.
+
+Hence revert all these other changes and restore the old shrinker
+behaviour, with the minor adjustment that we now first scan the
+unbound list, then the inactive list for each object category
+(purgeable or normal).
+
+A similar patch has been tested by a few people affected by the gen4/5
+hangs which started to appear in 3.7, which some people bisected to
+the "drm/i915: Track unbound pages" commit. But just disabling the
+unbound logic alone didn't change things at all.
+
+Note that this patch doesn't fix the referenced bugs, it only hides
+the underlying bug(s) well enough to restore pre-3.7 behaviour. The
+key to achieve that is to massively reduce the likelyhood of going
+into a full gpu stall and evicting everything.
+
+v2: Reword commit message a bit, taking Chris Wilson's comment into
+account.
+
+v3: On Chris Wilson's insistency, do not reinstate the rather bogus
+vfs_cache_pressure change.
+
+Tested-by: Greg KH <gregkh at linuxfoundation.org>
+Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>
+References: https://bugs.freedesktop.org/show_bug.cgi?id=55984
+References: https://bugs.freedesktop.org/show_bug.cgi?id=57122
+References: https://bugs.freedesktop.org/show_bug.cgi?id=56916
+References: https://bugs.freedesktop.org/show_bug.cgi?id=57136
+Cc: Chris Wilson <chris at chris-wilson.co.uk>
+Acked-by: Chris Wilson <chris at chris-wilson.co.uk>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_gem.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -1718,7 +1718,8 @@ i915_gem_object_put_pages(struct drm_i91
+ }
+
+ static long
+-i915_gem_purge(struct drm_i915_private *dev_priv, long target)
++__i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
++ bool purgeable_only)
+ {
+ struct drm_i915_gem_object *obj, *next;
+ long count = 0;
+@@ -1726,7 +1727,7 @@ i915_gem_purge(struct drm_i915_private *
+ list_for_each_entry_safe(obj, next,
+ &dev_priv->mm.unbound_list,
+ gtt_list) {
+- if (i915_gem_object_is_purgeable(obj) &&
++ if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
+ i915_gem_object_put_pages(obj) == 0) {
+ count += obj->base.size >> PAGE_SHIFT;
+ if (count >= target)
+@@ -1737,7 +1738,7 @@ i915_gem_purge(struct drm_i915_private *
+ list_for_each_entry_safe(obj, next,
+ &dev_priv->mm.inactive_list,
+ mm_list) {
+- if (i915_gem_object_is_purgeable(obj) &&
++ if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
+ i915_gem_object_unbind(obj) == 0 &&
+ i915_gem_object_put_pages(obj) == 0) {
+ count += obj->base.size >> PAGE_SHIFT;
+@@ -1749,6 +1750,12 @@ i915_gem_purge(struct drm_i915_private *
+ return count;
+ }
+
++static long
++i915_gem_purge(struct drm_i915_private *dev_priv, long target)
++{
++ return __i915_gem_shrink(dev_priv, target, true);
++}
++
+ static void
+ i915_gem_shrink_all(struct drm_i915_private *dev_priv)
+ {
+@@ -4426,6 +4433,9 @@ i915_gem_inactive_shrink(struct shrinker
+ if (nr_to_scan) {
+ nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
+ if (nr_to_scan > 0)
++ nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan,
++ false);
++ if (nr_to_scan > 0)
+ i915_gem_shrink_all(dev_priv);
+ }
+
+@@ -4433,7 +4443,7 @@ i915_gem_inactive_shrink(struct shrinker
+ list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
+ if (obj->pages_pin_count == 0)
+ cnt += obj->base.size >> PAGE_SHIFT;
+- list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
++ list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list)
+ if (obj->pin_count == 0 && obj->pages_pin_count == 0)
+ cnt += obj->base.size >> PAGE_SHIFT;
+
+From 7d9c199a55200c9b9fcad08e150470d02fb385be Mon Sep 17 00:00:00 2001
+From: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+Date: Thu, 6 Dec 2012 20:05:02 +0000
+Subject: RDMA/nes: Fix for crash when registering zero length MR for CQ
+
+From: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+
+commit 7d9c199a55200c9b9fcad08e150470d02fb385be upstream.
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: CAI Qian <caiqian at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/nes/nes_verbs.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -2559,6 +2559,11 @@ static struct ib_mr *nes_reg_user_mr(str
+ return ibmr;
+ case IWNES_MEMREG_TYPE_QP:
+ case IWNES_MEMREG_TYPE_CQ:
++ if (!region->length) {
++ nes_debug(NES_DBG_MR, "Unable to register zero length region for CQ\n");
++ ib_umem_release(region);
++ return ERR_PTR(-EINVAL);
++ }
+ nespbl = kzalloc(sizeof(*nespbl), GFP_KERNEL);
+ if (!nespbl) {
+ nes_debug(NES_DBG_MR, "Unable to allocate PBL\n");
+From 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 Mon Sep 17 00:00:00 2001
+From: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+Date: Thu, 6 Dec 2012 19:58:27 +0000
+Subject: RDMA/nes: Fix for terminate timer crash
+
+From: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+
+commit 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 upstream.
+
+The terminate timer needs to be initialized just once.
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+Signed-off-by: Roland Dreier <roland at purestorage.com>
+Signed-off-by: CAI Qian <caiqian at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/nes/nes.h | 1 +
+ drivers/infiniband/hw/nes/nes_hw.c | 9 ++-------
+ drivers/infiniband/hw/nes/nes_verbs.c | 4 +++-
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/infiniband/hw/nes/nes.h
++++ b/drivers/infiniband/hw/nes/nes.h
+@@ -532,6 +532,7 @@ void nes_iwarp_ce_handler(struct nes_dev
+ int nes_destroy_cqp(struct nes_device *);
+ int nes_nic_cm_xmit(struct sk_buff *, struct net_device *);
+ void nes_recheck_link_status(struct work_struct *work);
++void nes_terminate_timeout(unsigned long context);
+
+ /* nes_nic.c */
+ struct net_device *nes_netdev_init(struct nes_device *, void __iomem *);
+--- a/drivers/infiniband/hw/nes/nes_hw.c
++++ b/drivers/infiniband/hw/nes/nes_hw.c
+@@ -75,7 +75,6 @@ static void nes_process_iwarp_aeqe(struc
+ static void process_critical_error(struct nes_device *nesdev);
+ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number);
+ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_Mode);
+-static void nes_terminate_timeout(unsigned long context);
+ static void nes_terminate_start_timer(struct nes_qp *nesqp);
+
+ #ifdef CONFIG_INFINIBAND_NES_DEBUG
+@@ -3520,7 +3519,7 @@ static void nes_terminate_received(struc
+ }
+
+ /* Timeout routine in case terminate fails to complete */
+-static void nes_terminate_timeout(unsigned long context)
++void nes_terminate_timeout(unsigned long context)
+ {
+ struct nes_qp *nesqp = (struct nes_qp *)(unsigned long)context;
+
+@@ -3530,11 +3529,7 @@ static void nes_terminate_timeout(unsign
+ /* Set a timer in case hw cannot complete the terminate sequence */
+ static void nes_terminate_start_timer(struct nes_qp *nesqp)
+ {
+- init_timer(&nesqp->terminate_timer);
+- nesqp->terminate_timer.function = nes_terminate_timeout;
+- nesqp->terminate_timer.expires = jiffies + HZ;
+- nesqp->terminate_timer.data = (unsigned long)nesqp;
+- add_timer(&nesqp->terminate_timer);
++ mod_timer(&nesqp->terminate_timer, (jiffies + HZ));
+ }
+
+ /**
+--- a/drivers/infiniband/hw/nes/nes_verbs.c
++++ b/drivers/infiniband/hw/nes/nes_verbs.c
+@@ -1404,6 +1404,9 @@ static struct ib_qp *nes_create_qp(struc
+ }
+
+ nesqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR);
++ init_timer(&nesqp->terminate_timer);
++ nesqp->terminate_timer.function = nes_terminate_timeout;
++ nesqp->terminate_timer.data = (unsigned long)nesqp;
+
+ /* update the QP table */
+ nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp;
+@@ -1413,7 +1416,6 @@ static struct ib_qp *nes_create_qp(struc
+ return &nesqp->ibqp;
+ }
+
+-
+ /**
+ * nes_clean_cq
+ */
+From c1a94672a830e01d58c7c7e8de530c3f136d6ff2 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer at redhat.com>
+Date: Fri, 21 Dec 2012 20:23:30 +0000
+Subject: dm: disable WRITE SAME
+
+From: Mike Snitzer <snitzer at redhat.com>
+
+commit c1a94672a830e01d58c7c7e8de530c3f136d6ff2 upstream.
+
+WRITE SAME bios are not yet handled correctly by device-mapper so
+disable their use on device-mapper devices by setting
+max_write_same_sectors to zero.
+
+As an example, a ciphertext device is incompatible because the data
+gets changed according to the location at which it written and so the
+dm crypt target cannot support it.
+
+Signed-off-by: Mike Snitzer <snitzer at redhat.com>
+Cc: Milan Broz <mbroz at redhat.com>
+Signed-off-by: Alasdair G Kergon <agk at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/md/dm-table.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -1445,6 +1445,8 @@ void dm_table_set_restrictions(struct dm
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
+
++ q->limits.max_write_same_sectors = 0;
++
+ dm_table_set_integrity(t);
+
+ /*
+From 550929faf89e2e2cdb3e9945ea87d383989274cf Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka at redhat.com>
+Date: Fri, 21 Dec 2012 20:23:30 +0000
+Subject: dm persistent data: rename node to btree_node
+
+From: Mikulas Patocka <mpatocka at redhat.com>
+
+commit 550929faf89e2e2cdb3e9945ea87d383989274cf upstream.
+
+This patch fixes a compilation failure on sparc32 by renaming struct node.
+
+struct node is already defined in include/linux/node.h. On sparc32, it
+happens to be included through other dependencies and persistent-data
+doesn't compile because of conflicting declarations.
+
+Signed-off-by: Mikulas Patocka <mpatocka at redhat.com>
+Signed-off-by: Alasdair G Kergon <agk at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/md/persistent-data/dm-btree-internal.h | 16 ++++----
+ drivers/md/persistent-data/dm-btree-remove.c | 50 ++++++++++++-------------
+ drivers/md/persistent-data/dm-btree-spine.c | 6 +--
+ drivers/md/persistent-data/dm-btree.c | 22 +++++------
+ 4 files changed, 47 insertions(+), 47 deletions(-)
+
+--- a/drivers/md/persistent-data/dm-btree-internal.h
++++ b/drivers/md/persistent-data/dm-btree-internal.h
+@@ -36,13 +36,13 @@ struct node_header {
+ __le32 padding;
+ } __packed;
+
+-struct node {
++struct btree_node {
+ struct node_header header;
+ __le64 keys[0];
+ } __packed;
+
+
+-void inc_children(struct dm_transaction_manager *tm, struct node *n,
++void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
+ struct dm_btree_value_type *vt);
+
+ int new_block(struct dm_btree_info *info, struct dm_block **result);
+@@ -64,7 +64,7 @@ struct ro_spine {
+ void init_ro_spine(struct ro_spine *s, struct dm_btree_info *info);
+ int exit_ro_spine(struct ro_spine *s);
+ int ro_step(struct ro_spine *s, dm_block_t new_child);
+-struct node *ro_node(struct ro_spine *s);
++struct btree_node *ro_node(struct ro_spine *s);
+
+ struct shadow_spine {
+ struct dm_btree_info *info;
+@@ -98,17 +98,17 @@ int shadow_root(struct shadow_spine *s);
+ /*
+ * Some inlines.
+ */
+-static inline __le64 *key_ptr(struct node *n, uint32_t index)
++static inline __le64 *key_ptr(struct btree_node *n, uint32_t index)
+ {
+ return n->keys + index;
+ }
+
+-static inline void *value_base(struct node *n)
++static inline void *value_base(struct btree_node *n)
+ {
+ return &n->keys[le32_to_cpu(n->header.max_entries)];
+ }
+
+-static inline void *value_ptr(struct node *n, uint32_t index)
++static inline void *value_ptr(struct btree_node *n, uint32_t index)
+ {
+ uint32_t value_size = le32_to_cpu(n->header.value_size);
+ return value_base(n) + (value_size * index);
+@@ -117,7 +117,7 @@ static inline void *value_ptr(struct nod
+ /*
+ * Assumes the values are suitably-aligned and converts to core format.
+ */
+-static inline uint64_t value64(struct node *n, uint32_t index)
++static inline uint64_t value64(struct btree_node *n, uint32_t index)
+ {
+ __le64 *values_le = value_base(n);
+
+@@ -127,7 +127,7 @@ static inline uint64_t value64(struct no
+ /*
+ * Searching for a key within a single node.
+ */
+-int lower_bound(struct node *n, uint64_t key);
++int lower_bound(struct btree_node *n, uint64_t key);
+
+ extern struct dm_block_validator btree_node_validator;
+
+--- a/drivers/md/persistent-data/dm-btree-remove.c
++++ b/drivers/md/persistent-data/dm-btree-remove.c
+@@ -53,7 +53,7 @@
+ /*
+ * Some little utilities for moving node data around.
+ */
+-static void node_shift(struct node *n, int shift)
++static void node_shift(struct btree_node *n, int shift)
+ {
+ uint32_t nr_entries = le32_to_cpu(n->header.nr_entries);
+ uint32_t value_size = le32_to_cpu(n->header.value_size);
+@@ -79,7 +79,7 @@ static void node_shift(struct node *n, i
+ }
+ }
+
+-static void node_copy(struct node *left, struct node *right, int shift)
++static void node_copy(struct btree_node *left, struct btree_node *right, int shift)
+ {
+ uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+ uint32_t value_size = le32_to_cpu(left->header.value_size);
+@@ -108,7 +108,7 @@ static void node_copy(struct node *left,
+ /*
+ * Delete a specific entry from a leaf node.
+ */
+-static void delete_at(struct node *n, unsigned index)
++static void delete_at(struct btree_node *n, unsigned index)
+ {
+ unsigned nr_entries = le32_to_cpu(n->header.nr_entries);
+ unsigned nr_to_copy = nr_entries - (index + 1);
+@@ -128,7 +128,7 @@ static void delete_at(struct node *n, un
+ n->header.nr_entries = cpu_to_le32(nr_entries - 1);
+ }
+
+-static unsigned merge_threshold(struct node *n)
++static unsigned merge_threshold(struct btree_node *n)
+ {
+ return le32_to_cpu(n->header.max_entries) / 3;
+ }
+@@ -136,7 +136,7 @@ static unsigned merge_threshold(struct n
+ struct child {
+ unsigned index;
+ struct dm_block *block;
+- struct node *n;
++ struct btree_node *n;
+ };
+
+ static struct dm_btree_value_type le64_type = {
+@@ -147,7 +147,7 @@ static struct dm_btree_value_type le64_t
+ .equal = NULL
+ };
+
+-static int init_child(struct dm_btree_info *info, struct node *parent,
++static int init_child(struct dm_btree_info *info, struct btree_node *parent,
+ unsigned index, struct child *result)
+ {
+ int r, inc;
+@@ -177,7 +177,7 @@ static int exit_child(struct dm_btree_in
+ return dm_tm_unlock(info->tm, c->block);
+ }
+
+-static void shift(struct node *left, struct node *right, int count)
++static void shift(struct btree_node *left, struct btree_node *right, int count)
+ {
+ uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+ uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+@@ -203,11 +203,11 @@ static void shift(struct node *left, str
+ right->header.nr_entries = cpu_to_le32(nr_right + count);
+ }
+
+-static void __rebalance2(struct dm_btree_info *info, struct node *parent,
++static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent,
+ struct child *l, struct child *r)
+ {
+- struct node *left = l->n;
+- struct node *right = r->n;
++ struct btree_node *left = l->n;
++ struct btree_node *right = r->n;
+ uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+ uint32_t nr_right = le32_to_cpu(right->header.nr_entries);
+ unsigned threshold = 2 * merge_threshold(left) + 1;
+@@ -239,7 +239,7 @@ static int rebalance2(struct shadow_spin
+ unsigned left_index)
+ {
+ int r;
+- struct node *parent;
++ struct btree_node *parent;
+ struct child left, right;
+
+ parent = dm_block_data(shadow_current(s));
+@@ -270,9 +270,9 @@ static int rebalance2(struct shadow_spin
+ * in right, then rebalance2. This wastes some cpu, but I want something
+ * simple atm.
+ */
+-static void delete_center_node(struct dm_btree_info *info, struct node *parent,
++static void delete_center_node(struct dm_btree_info *info, struct btree_node *parent,
+ struct child *l, struct child *c, struct child *r,
+- struct node *left, struct node *center, struct node *right,
++ struct btree_node *left, struct btree_node *center, struct btree_node *right,
+ uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+ {
+ uint32_t max_entries = le32_to_cpu(left->header.max_entries);
+@@ -301,9 +301,9 @@ static void delete_center_node(struct dm
+ /*
+ * Redistributes entries among 3 sibling nodes.
+ */
+-static void redistribute3(struct dm_btree_info *info, struct node *parent,
++static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
+ struct child *l, struct child *c, struct child *r,
+- struct node *left, struct node *center, struct node *right,
++ struct btree_node *left, struct btree_node *center, struct btree_node *right,
+ uint32_t nr_left, uint32_t nr_center, uint32_t nr_right)
+ {
+ int s;
+@@ -343,12 +343,12 @@ static void redistribute3(struct dm_btre
+ *key_ptr(parent, r->index) = right->keys[0];
+ }
+
+-static void __rebalance3(struct dm_btree_info *info, struct node *parent,
++static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent,
+ struct child *l, struct child *c, struct child *r)
+ {
+- struct node *left = l->n;
+- struct node *center = c->n;
+- struct node *right = r->n;
++ struct btree_node *left = l->n;
++ struct btree_node *center = c->n;
++ struct btree_node *right = r->n;
+
+ uint32_t nr_left = le32_to_cpu(left->header.nr_entries);
+ uint32_t nr_center = le32_to_cpu(center->header.nr_entries);
+@@ -371,7 +371,7 @@ static int rebalance3(struct shadow_spin
+ unsigned left_index)
+ {
+ int r;
+- struct node *parent = dm_block_data(shadow_current(s));
++ struct btree_node *parent = dm_block_data(shadow_current(s));
+ struct child left, center, right;
+
+ /*
+@@ -421,7 +421,7 @@ static int get_nr_entries(struct dm_tran
+ {
+ int r;
+ struct dm_block *block;
+- struct node *n;
++ struct btree_node *n;
+
+ r = dm_tm_read_lock(tm, b, &btree_node_validator, &block);
+ if (r)
+@@ -438,7 +438,7 @@ static int rebalance_children(struct sha
+ {
+ int i, r, has_left_sibling, has_right_sibling;
+ uint32_t child_entries;
+- struct node *n;
++ struct btree_node *n;
+
+ n = dm_block_data(shadow_current(s));
+
+@@ -483,7 +483,7 @@ static int rebalance_children(struct sha
+ return r;
+ }
+
+-static int do_leaf(struct node *n, uint64_t key, unsigned *index)
++static int do_leaf(struct btree_node *n, uint64_t key, unsigned *index)
+ {
+ int i = lower_bound(n, key);
+
+@@ -506,7 +506,7 @@ static int remove_raw(struct shadow_spin
+ uint64_t key, unsigned *index)
+ {
+ int i = *index, r;
+- struct node *n;
++ struct btree_node *n;
+
+ for (;;) {
+ r = shadow_step(s, root, vt);
+@@ -556,7 +556,7 @@ int dm_btree_remove(struct dm_btree_info
+ unsigned level, last_level = info->levels - 1;
+ int index = 0, r = 0;
+ struct shadow_spine spine;
+- struct node *n;
++ struct btree_node *n;
+
+ init_shadow_spine(&spine, info);
+ for (level = 0; level < info->levels; level++) {
+--- a/drivers/md/persistent-data/dm-btree-spine.c
++++ b/drivers/md/persistent-data/dm-btree-spine.c
+@@ -23,7 +23,7 @@ static void node_prepare_for_write(struc
+ struct dm_block *b,
+ size_t block_size)
+ {
+- struct node *n = dm_block_data(b);
++ struct btree_node *n = dm_block_data(b);
+ struct node_header *h = &n->header;
+
+ h->blocknr = cpu_to_le64(dm_block_location(b));
+@@ -38,7 +38,7 @@ static int node_check(struct dm_block_va
+ struct dm_block *b,
+ size_t block_size)
+ {
+- struct node *n = dm_block_data(b);
++ struct btree_node *n = dm_block_data(b);
+ struct node_header *h = &n->header;
+ size_t value_size;
+ __le32 csum_disk;
+@@ -164,7 +164,7 @@ int ro_step(struct ro_spine *s, dm_block
+ return r;
+ }
+
+-struct node *ro_node(struct ro_spine *s)
++struct btree_node *ro_node(struct ro_spine *s)
+ {
+ struct dm_block *block;
+
+--- a/drivers/md/persistent-data/dm-btree.c
++++ b/drivers/md/persistent-data/dm-btree.c
+@@ -38,7 +38,7 @@ static void array_insert(void *base, siz
+ /*----------------------------------------------------------------*/
+
+ /* makes the assumption that no two keys are the same. */
+-static int bsearch(struct node *n, uint64_t key, int want_hi)
++static int bsearch(struct btree_node *n, uint64_t key, int want_hi)
+ {
+ int lo = -1, hi = le32_to_cpu(n->header.nr_entries);
+
+@@ -58,12 +58,12 @@ static int bsearch(struct node *n, uint6
+ return want_hi ? hi : lo;
+ }
+
+-int lower_bound(struct node *n, uint64_t key)
++int lower_bound(struct btree_node *n, uint64_t key)
+ {
+ return bsearch(n, key, 0);
+ }
+
+-void inc_children(struct dm_transaction_manager *tm, struct node *n,
++void inc_children(struct dm_transaction_manager *tm, struct btree_node *n,
+ struct dm_btree_value_type *vt)
+ {
+ unsigned i;
+@@ -77,7 +77,7 @@ void inc_children(struct dm_transaction_
+ vt->inc(vt->context, value_ptr(n, i));
+ }
+
+-static int insert_at(size_t value_size, struct node *node, unsigned index,
++static int insert_at(size_t value_size, struct btree_node *node, unsigned index,
+ uint64_t key, void *value)
+ __dm_written_to_disk(value)
+ {
+@@ -122,7 +122,7 @@ int dm_btree_empty(struct dm_btree_info
+ {
+ int r;
+ struct dm_block *b;
+- struct node *n;
++ struct btree_node *n;
+ size_t block_size;
+ uint32_t max_entries;
+
+@@ -154,7 +154,7 @@ EXPORT_SYMBOL_GPL(dm_btree_empty);
+ #define MAX_SPINE_DEPTH 64
+ struct frame {
+ struct dm_block *b;
+- struct node *n;
++ struct btree_node *n;
+ unsigned level;
+ unsigned nr_children;
+ unsigned current_child;
+@@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(dm_btree_del);
+ /*----------------------------------------------------------------*/
+
+ static int btree_lookup_raw(struct ro_spine *s, dm_block_t block, uint64_t key,
+- int (*search_fn)(struct node *, uint64_t),
++ int (*search_fn)(struct btree_node *, uint64_t),
+ uint64_t *result_key, void *v, size_t value_size)
+ {
+ int i, r;
+@@ -406,7 +406,7 @@ static int btree_split_sibling(struct sh
+ size_t size;
+ unsigned nr_left, nr_right;
+ struct dm_block *left, *right, *parent;
+- struct node *ln, *rn, *pn;
++ struct btree_node *ln, *rn, *pn;
+ __le64 location;
+
+ left = shadow_current(s);
+@@ -491,7 +491,7 @@ static int btree_split_beneath(struct sh
+ size_t size;
+ unsigned nr_left, nr_right;
+ struct dm_block *left, *right, *new_parent;
+- struct node *pn, *ln, *rn;
++ struct btree_node *pn, *ln, *rn;
+ __le64 val;
+
+ new_parent = shadow_current(s);
+@@ -576,7 +576,7 @@ static int btree_insert_raw(struct shado
+ uint64_t key, unsigned *index)
+ {
+ int r, i = *index, top = 1;
+- struct node *node;
++ struct btree_node *node;
+
+ for (;;) {
+ r = shadow_step(s, root, vt);
+@@ -643,7 +643,7 @@ static int insert(struct dm_btree_info *
+ unsigned level, index = -1, last_level = info->levels - 1;
+ dm_block_t block = root;
+ struct shadow_spine spine;
+- struct node *n;
++ struct btree_node *n;
+ struct dm_btree_value_type le64_type;
+
+ le64_type.context = NULL;
+From e910d7ebecd1aac43125944a8641b6cb1a0dfabe Mon Sep 17 00:00:00 2001
+From: Alasdair G Kergon <agk at redhat.com>
+Date: Fri, 21 Dec 2012 20:23:30 +0000
+Subject: dm ioctl: prevent unsafe change to dm_ioctl data_size
+
+From: Alasdair G Kergon <agk at redhat.com>
+
+commit e910d7ebecd1aac43125944a8641b6cb1a0dfabe upstream.
+
+Abort dm ioctl processing if userspace changes the data_size parameter
+after we validated it but before we finished copying the data buffer
+from userspace.
+
+The dm ioctl parameters are processed in the following sequence:
+ 1. ctl_ioctl() calls copy_params();
+ 2. copy_params() makes a first copy of the fixed-sized portion of the
+ userspace parameters into the local variable "tmp";
+ 3. copy_params() then validates tmp.data_size and allocates a new
+ structure big enough to hold the complete data and copies the whole
+ userspace buffer there;
+ 4. ctl_ioctl() reads userspace data the second time and copies the whole
+ buffer into the pointer "param";
+ 5. ctl_ioctl() reads param->data_size without any validation and stores it
+ in the variable "input_param_size";
+ 6. "input_param_size" is further used as the authoritative size of the
+ kernel buffer.
+
+The problem is that userspace code could change the contents of user
+memory between steps 2 and 4. In particular, the data_size parameter
+can be changed to an invalid value after the kernel has validated it.
+This lets userspace force the kernel to access invalid kernel memory.
+
+The fix is to ensure that the size has not changed at step 4.
+
+This patch shouldn't have a security impact because CAP_SYS_ADMIN is
+required to run this code, but it should be fixed anyway.
+
+Reported-by: Mikulas Patocka <mpatocka at redhat.com>
+Signed-off-by: Alasdair G Kergon <agk at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/md/dm-ioctl.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1566,6 +1566,14 @@ static int copy_params(struct dm_ioctl _
+ if (copy_from_user(dmi, user, tmp.data_size))
+ goto bad;
+
++ /*
++ * Abort if something changed the ioctl data while it was being copied.
++ */
++ if (dmi->data_size != tmp.data_size) {
++ DMERR("rejecting ioctl: data size modified while processing parameters");
++ goto bad;
++ }
++
+ /* Wipe the user buffer so we do not return it to userspace */
+ if (secure_data && clear_user(user, tmp.data_size))
+ goto bad;
+From b7ca9c9273e5eebd63880dd8a6e4e5c18fc7901d Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt at redhat.com>
+Date: Fri, 21 Dec 2012 20:23:31 +0000
+Subject: dm thin: replace dm_cell_release_singleton with cell_defer_except
+
+From: Joe Thornber <ejt at redhat.com>
+
+commit b7ca9c9273e5eebd63880dd8a6e4e5c18fc7901d upstream.
+
+Change existing users of the function dm_cell_release_singleton to share
+cell_defer_except instead, and then remove the now-unused function.
+
+Everywhere that calls dm_cell_release_singleton, the bio in question
+is the holder of the cell.
+
+If there are no non-holder entries in the cell then cell_defer_except
+behaves exactly like dm_cell_release_singleton. Conversely, if there
+*are* non-holder entries then dm_cell_release_singleton must not be used
+because those entries would need to be deferred.
+
+Consequently, it is safe to replace use of dm_cell_release_singleton
+with cell_defer_except.
+
+This patch is a pre-requisite for "dm thin: fix race between
+simultaneous io and discards to same block".
+
+Signed-off-by: Joe Thornber <ejt at redhat.com>
+Signed-off-by: Mike Snitzer <snitzer at redhat.com>
+Signed-off-by: Alasdair G Kergon <agk at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/md/dm-bio-prison.c | 25 -------------------------
+ drivers/md/dm-bio-prison.h | 1 -
+ drivers/md/dm-thin.c | 25 ++++++++++++-------------
+ 3 files changed, 12 insertions(+), 39 deletions(-)
+
+--- a/drivers/md/dm-bio-prison.c
++++ b/drivers/md/dm-bio-prison.c
+@@ -208,31 +208,6 @@ void dm_cell_release(struct dm_bio_priso
+ EXPORT_SYMBOL_GPL(dm_cell_release);
+
+ /*
+- * There are a couple of places where we put a bio into a cell briefly
+- * before taking it out again. In these situations we know that no other
+- * bio may be in the cell. This function releases the cell, and also does
+- * a sanity check.
+- */
+-static void __cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
+-{
+- BUG_ON(cell->holder != bio);
+- BUG_ON(!bio_list_empty(&cell->bios));
+-
+- __cell_release(cell, NULL);
+-}
+-
+-void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio)
+-{
+- unsigned long flags;
+- struct dm_bio_prison *prison = cell->prison;
+-
+- spin_lock_irqsave(&prison->lock, flags);
+- __cell_release_singleton(cell, bio);
+- spin_unlock_irqrestore(&prison->lock, flags);
+-}
+-EXPORT_SYMBOL_GPL(dm_cell_release_singleton);
+-
+-/*
+ * Sometimes we don't want the holder, just the additional bios.
+ */
+ static void __cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates)
+--- a/drivers/md/dm-bio-prison.h
++++ b/drivers/md/dm-bio-prison.h
+@@ -44,7 +44,6 @@ int dm_bio_detain(struct dm_bio_prison *
+ struct bio *inmate, struct dm_bio_prison_cell **ref);
+
+ void dm_cell_release(struct dm_bio_prison_cell *cell, struct bio_list *bios);
+-void dm_cell_release_singleton(struct dm_bio_prison_cell *cell, struct bio *bio); // FIXME: bio arg not needed
+ void dm_cell_release_no_holder(struct dm_bio_prison_cell *cell, struct bio_list *inmates);
+ void dm_cell_error(struct dm_bio_prison_cell *cell);
+
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -513,8 +513,7 @@ static void cell_defer(struct thin_c *tc
+ }
+
+ /*
+- * Same as cell_defer above, except it omits one particular detainee,
+- * a write bio that covers the block and has already been processed.
++ * Same as cell_defer except it omits the original holder of the cell.
+ */
+ static void cell_defer_except(struct thin_c *tc, struct dm_bio_prison_cell *cell)
+ {
+@@ -936,7 +935,7 @@ static void process_discard(struct thin_
+ */
+ build_data_key(tc->td, lookup_result.block, &key2);
+ if (dm_bio_detain(tc->pool->prison, &key2, bio, &cell2)) {
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ break;
+ }
+
+@@ -967,8 +966,8 @@ static void process_discard(struct thin_
+ * a block boundary. So we submit the discard of a
+ * partial block appropriately.
+ */
+- dm_cell_release_singleton(cell, bio);
+- dm_cell_release_singleton(cell2, bio);
++ cell_defer_except(tc, cell);
++ cell_defer_except(tc, cell2);
+ if ((!lookup_result.shared) && pool->pf.discard_passdown)
+ remap_and_issue(tc, bio, lookup_result.block);
+ else
+@@ -980,13 +979,13 @@ static void process_discard(struct thin_
+ /*
+ * It isn't provisioned, just forget it.
+ */
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ bio_endio(bio, 0);
+ break;
+
+ default:
+ DMERR("discard: find block unexpectedly returned %d", r);
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ bio_io_error(bio);
+ break;
+ }
+@@ -1041,7 +1040,7 @@ static void process_shared_bio(struct th
+
+ h->shared_read_entry = dm_deferred_entry_inc(pool->shared_read_ds);
+
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ remap_and_issue(tc, bio, lookup_result->block);
+ }
+ }
+@@ -1056,7 +1055,7 @@ static void provision_block(struct thin_
+ * Remap empty bios (flushes) immediately, without provisioning.
+ */
+ if (!bio->bi_size) {
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ remap_and_issue(tc, bio, 0);
+ return;
+ }
+@@ -1066,7 +1065,7 @@ static void provision_block(struct thin_
+ */
+ if (bio_data_dir(bio) == READ) {
+ zero_fill_bio(bio);
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ bio_endio(bio, 0);
+ return;
+ }
+@@ -1120,7 +1119,7 @@ static void process_bio(struct thin_c *t
+ * TODO: this will probably have to change when discard goes
+ * back in.
+ */
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+
+ if (lookup_result.shared)
+ process_shared_bio(tc, bio, block, &lookup_result);
+@@ -1130,7 +1129,7 @@ static void process_bio(struct thin_c *t
+
+ case -ENODATA:
+ if (bio_data_dir(bio) == READ && tc->origin_dev) {
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ remap_to_origin_and_issue(tc, bio);
+ } else
+ provision_block(tc, bio, block, cell);
+@@ -1138,7 +1137,7 @@ static void process_bio(struct thin_c *t
+
+ default:
+ DMERR("dm_thin_find_block() failed, error = %d", r);
+- dm_cell_release_singleton(cell, bio);
++ cell_defer_except(tc, cell);
+ bio_io_error(bio);
+ break;
+ }
+From ab1dd9963137a1e122004d5378a581bf16ae9bc8 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 7 Oct 2012 08:27:00 +0100
+Subject: staging: vt6656: [BUG] out of bound array reference in RFbSetPower.
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit ab1dd9963137a1e122004d5378a581bf16ae9bc8 upstream.
+
+Calling RFbSetPower with uCH zero value will cause out of bound array reference.
+
+This causes 64 bit kernels to oops on boot.
+
+Note: Driver does not function on 64 bit kernels and should be
+blacklisted on them.
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/rf.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/vt6656/rf.c
++++ b/drivers/staging/vt6656/rf.c
+@@ -769,6 +769,9 @@ BYTE byPwr = pDevice->byCCKPwr;
+ return TRUE;
+ }
+
++ if (uCH == 0)
++ return -EINVAL;
++
+ switch (uRATE) {
+ case RATE_1M:
+ case RATE_2M:
+From a552397d5e4ef0cc0bd3e9595d6acc9a3b381171 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 11 Nov 2012 15:32:05 +0000
+Subject: staging: vt6656: 64 bit fixes: use u32 for QWORD definition.
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit a552397d5e4ef0cc0bd3e9595d6acc9a3b381171 upstream.
+
+Size of long issues replace with u32.
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/ttype.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/vt6656/ttype.h
++++ b/drivers/staging/vt6656/ttype.h
+@@ -29,6 +29,8 @@
+ #ifndef __TTYPE_H__
+ #define __TTYPE_H__
+
++#include <linux/types.h>
++
+ /******* Common definitions and typedefs ***********************************/
+
+ typedef int BOOL;
+@@ -51,8 +53,8 @@ typedef unsigned long DWORD;
+ // which is NOT really a floating point number.
+ typedef union tagUQuadWord {
+ struct {
+- DWORD dwLowDword;
+- DWORD dwHighDword;
++ u32 dwLowDword;
++ u32 dwHighDword;
+ } u;
+ double DoNotUseThisField;
+ } UQuadWord;
+From 7730492855a2f9c828599bcd8d62760f96d319e4 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 11 Nov 2012 15:41:25 +0000
+Subject: staging: vt6656: 64 bit fixes : correct all type sizes
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit 7730492855a2f9c828599bcd8d62760f96d319e4 upstream.
+
+After this patch all BYTE/WORD/DWORD types can be replaced with the appropriate u sizes.
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/ttype.h | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/vt6656/ttype.h
++++ b/drivers/staging/vt6656/ttype.h
+@@ -44,9 +44,9 @@ typedef int BOOL;
+
+ /****** Simple typedefs ***************************************************/
+
+-typedef unsigned char BYTE; // 8-bit
+-typedef unsigned short WORD; // 16-bit
+-typedef unsigned long DWORD; // 32-bit
++typedef u8 BYTE;
++typedef u16 WORD;
++typedef u32 DWORD;
+
+ // QWORD is for those situation that we want
+ // an 8-byte-aligned 8 byte long structure
+@@ -62,8 +62,8 @@ typedef UQuadWord QWORD;
+
+ /****** Common pointer types ***********************************************/
+
+-typedef unsigned long ULONG_PTR; // 32-bit
+-typedef unsigned long DWORD_PTR; // 32-bit
++typedef u32 ULONG_PTR;
++typedef u32 DWORD_PTR;
+
+ // boolean pointer
+
+From b4dc03af5513774277c9c36b12a25cd3f25f4404 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 11 Nov 2012 15:45:52 +0000
+Subject: staging: vt6656: 64 bit fixes: fix long warning messages.
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit b4dc03af5513774277c9c36b12a25cd3f25f4404 upstream.
+
+Fixes long warning messages from patch
+[PATCH 08/14] staging: vt6656: 64 bit fixes : correct all type sizes
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/dpc.c | 4 +--
+ drivers/staging/vt6656/key.c | 47 +++++++++++++++++++++++++++++-------------
+ drivers/staging/vt6656/mac.c | 6 +++--
+ drivers/staging/vt6656/rxtx.c | 18 ++++++++++------
+ 4 files changed, 51 insertions(+), 24 deletions(-)
+
+--- a/drivers/staging/vt6656/dpc.c
++++ b/drivers/staging/vt6656/dpc.c
+@@ -1238,7 +1238,7 @@ static BOOL s_bHandleRxEncryption (
+
+ PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+ *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
+ if (byDecMode == KEY_CTL_TKIP) {
+ *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+ } else {
+@@ -1349,7 +1349,7 @@ static BOOL s_bHostWepRxEncryption (
+
+ PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+ *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16);
+
+ if (byDecMode == KEY_CTL_TKIP) {
+ *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+--- a/drivers/staging/vt6656/key.c
++++ b/drivers/staging/vt6656/key.c
+@@ -235,7 +235,8 @@ BOOL KeybSetKey(
+ PSKeyItem pKey;
+ unsigned int uKeyIdx;
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
++ "Enter KeybSetKey: %X\n", dwKeyIndex);
+
+ j = (MAX_KEY_TABLE-1);
+ for (i=0;i<(MAX_KEY_TABLE-1);i++) {
+@@ -261,7 +262,9 @@ BOOL KeybSetKey(
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
++ "Group transmit key(R)[%X]: %d\n",
++ pTable->KeyTable[i].dwGTKeyIndex, i);
+ }
+ pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
+ pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
+@@ -302,9 +305,12 @@ BOOL KeybSetKey(
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
++ pKey->dwTSC47_16);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ",
++ pKey->wTSC15_0);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
++ pKey->dwKeyIndex);
+
+ return (TRUE);
+ }
+@@ -326,7 +332,9 @@ BOOL KeybSetKey(
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
++ "Group transmit key(N)[%X]: %d\n",
++ pTable->KeyTable[j].dwGTKeyIndex, j);
+ }
+ pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed
+ pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
+@@ -367,9 +375,11 @@ BOOL KeybSetKey(
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ",
++ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ",
++ pKey->dwKeyIndex);
+
+ return (TRUE);
+ }
+@@ -597,7 +607,8 @@ BOOL KeybGetTransmitKey(PSKeyManagement
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n",
++ pTable->KeyTable[i].dwGTKeyIndex);
+
+ return (TRUE);
+ }
+@@ -696,7 +707,10 @@ BOOL KeybSetDefaultKey(
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
++ "Group transmit key(R)[%X]: %d\n",
++ pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex,
++ MAX_KEY_TABLE-1);
+
+ }
+ pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed
+@@ -747,9 +761,11 @@ BOOL KeybSetDefaultKey(
+ }
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n",
++ pKey->dwTSC47_16);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n",
++ pKey->dwKeyIndex);
+
+ return (TRUE);
+ }
+@@ -787,7 +803,8 @@ BOOL KeybSetAllGroupKey(
+ PSKeyItem pKey;
+ unsigned int uKeyIdx;
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n",
++ dwKeyIndex);
+
+
+ if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key
+@@ -804,7 +821,9 @@ BOOL KeybSetAllGroupKey(
+ if ((dwKeyIndex & TRANSMIT_KEY) != 0) {
+ // Group transmit key
+ pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
++ "Group transmit key(R)[%X]: %d\n",
++ pTable->KeyTable[i].dwGTKeyIndex, i);
+
+ }
+ pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed
+--- a/drivers/staging/vt6656/mac.c
++++ b/drivers/staging/vt6656/mac.c
+@@ -260,7 +260,8 @@ BYTE pbyData[24];
+ dwData1 <<= 16;
+ dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %X,"\
++ " KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
+
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+ //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+@@ -277,7 +278,8 @@ BYTE pbyData[24];
+ dwData2 <<= 8;
+ dwData2 |= *(pbyAddr+0);
+
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %X\n",
++ wOffset, dwData2);
+
+ //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+ //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+--- a/drivers/staging/vt6656/rxtx.c
++++ b/drivers/staging/vt6656/rxtx.c
+@@ -375,7 +375,8 @@ s_vFillTxKey (
+ *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+ // Append IV&ExtIV after Mac Header
+ *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n",
++ *pdwExtIV);
+
+ } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+ pTransmitKey->wTSC15_0++;
+@@ -1751,7 +1752,8 @@ s_bPacketToWirelessUsb(
+ MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
+ dwMIC_Priority = 0;
+ MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n",
++ dwMICKey0, dwMICKey1);
+
+ ///////////////////////////////////////////////////////////////////
+
+@@ -2633,7 +2635,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct
+ MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
+ dwMIC_Priority = 0;
+ MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\
++ " %X, %X\n", dwMICKey0, dwMICKey1);
+
+ uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
+
+@@ -2653,7 +2656,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct
+
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n",
++ *pdwMIC_L, *pdwMIC_R);
+
+ }
+
+@@ -3027,7 +3031,8 @@ int nsDMA_tx_packet(PSDevice pDevice, un
+ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
+ }
+ else {
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
++ pTransmitKey->dwKeyIndex);
+ bNeedEncryption = TRUE;
+ }
+ }
+@@ -3041,7 +3046,8 @@ int nsDMA_tx_packet(PSDevice pDevice, un
+ if (pDevice->bEnableHostWEP) {
+ if ((uNodeIndex != 0) &&
+ (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
+- DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
++ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n",
++ pTransmitKey->dwKeyIndex);
+ bNeedEncryption = TRUE;
+ }
+ }
+From c0d05b305b00c698b0a8c1b3d46c9380bce9db45 Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 11 Nov 2012 15:49:59 +0000
+Subject: staging: vt6656: 64bit fixes: key.c/h change unsigned long to u32
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit c0d05b305b00c698b0a8c1b3d46c9380bce9db45 upstream.
+
+Fixes long issues.
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/key.c | 6 +++---
+ drivers/staging/vt6656/key.h | 8 ++++----
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/staging/vt6656/key.c
++++ b/drivers/staging/vt6656/key.c
+@@ -223,7 +223,7 @@ BOOL KeybSetKey(
+ PSKeyManagement pTable,
+ PBYTE pbyBSSID,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+@@ -675,7 +675,7 @@ BOOL KeybSetDefaultKey(
+ void *pDeviceHandler,
+ PSKeyManagement pTable,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+@@ -791,7 +791,7 @@ BOOL KeybSetAllGroupKey(
+ void *pDeviceHandler,
+ PSKeyManagement pTable,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+--- a/drivers/staging/vt6656/key.h
++++ b/drivers/staging/vt6656/key.h
+@@ -58,7 +58,7 @@
+ typedef struct tagSKeyItem
+ {
+ BOOL bKeyValid;
+- unsigned long uKeyLength;
++ u32 uKeyLength;
+ BYTE abyKey[MAX_KEY_LEN];
+ QWORD KeyRSC;
+ DWORD dwTSC47_16;
+@@ -107,7 +107,7 @@ BOOL KeybSetKey(
+ PSKeyManagement pTable,
+ PBYTE pbyBSSID,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+@@ -146,7 +146,7 @@ BOOL KeybSetDefaultKey(
+ void *pDeviceHandler,
+ PSKeyManagement pTable,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+@@ -156,7 +156,7 @@ BOOL KeybSetAllGroupKey(
+ void *pDeviceHandler,
+ PSKeyManagement pTable,
+ DWORD dwKeyIndex,
+- unsigned long uKeyLength,
++ u32 uKeyLength,
+ PQWORD pKeyRSC,
+ PBYTE pbyKey,
+ BYTE byKeyDecMode
+From 70e227790d4ee4590023d8041a3485f8053593fc Mon Sep 17 00:00:00 2001
+From: Malcolm Priestley <tvboxspy at gmail.com>
+Date: Sun, 11 Nov 2012 16:07:57 +0000
+Subject: staging: vt6656: 64bit fixes: vCommandTimerWait change calculation of timer.
+
+From: Malcolm Priestley <tvboxspy at gmail.com>
+
+commit 70e227790d4ee4590023d8041a3485f8053593fc upstream.
+
+The timer appears to run too fast/race on 64 bit systems.
+
+Using msecs_to_jiffies seems to cause a deadlock on 64 bit.
+
+A calculation of (MSecond * HZ) / 1000 appears to run satisfactory.
+
+Change BSSIDInfoCount to u32.
+
+After this patch the driver can be successfully connect on little endian 64/32 bit systems.
+
+Signed-off-by: Malcolm Priestley <tvboxspy at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/vt6656/wcmd.c | 20 +++++++++++---------
+ drivers/staging/vt6656/wpa2.h | 4 ++--
+ 2 files changed, 13 insertions(+), 11 deletions(-)
+
+--- a/drivers/staging/vt6656/wcmd.c
++++ b/drivers/staging/vt6656/wcmd.c
+@@ -316,17 +316,19 @@ s_MgrMakeProbeRequest(
+ return pTxPacket;
+ }
+
+-void vCommandTimerWait(void *hDeviceContext, unsigned int MSecond)
++void vCommandTimerWait(void *hDeviceContext, unsigned long MSecond)
+ {
+- PSDevice pDevice = (PSDevice)hDeviceContext;
++ PSDevice pDevice = (PSDevice)hDeviceContext;
+
+- init_timer(&pDevice->sTimerCommand);
+- pDevice->sTimerCommand.data = (unsigned long)pDevice;
+- pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+- // RUN_AT :1 msec ~= (HZ/1024)
+- pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10);
+- add_timer(&pDevice->sTimerCommand);
+- return;
++ init_timer(&pDevice->sTimerCommand);
++
++ pDevice->sTimerCommand.data = (unsigned long)pDevice;
++ pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
++ pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000);
++
++ add_timer(&pDevice->sTimerCommand);
++
++ return;
+ }
+
+ void vRunCommand(void *hDeviceContext)
+--- a/drivers/staging/vt6656/wpa2.h
++++ b/drivers/staging/vt6656/wpa2.h
+@@ -45,8 +45,8 @@ typedef struct tagsPMKIDInfo {
+ } PMKIDInfo, *PPMKIDInfo;
+
+ typedef struct tagSPMKIDCache {
+- unsigned long BSSIDInfoCount;
+- PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
++ u32 BSSIDInfoCount;
++ PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE];
+ } SPMKIDCache, *PSPMKIDCache;
+
+
+From 0602934f302e016e2ea5dc6951681bfac77455ef Mon Sep 17 00:00:00 2001
+From: Chris Verges <kg4ysn at gmail.com>
+Date: Fri, 21 Dec 2012 01:58:34 -0800
+Subject: hwmon: (lm73} Detect and report i2c bus errors
+
+From: Chris Verges <kg4ysn at gmail.com>
+
+commit 0602934f302e016e2ea5dc6951681bfac77455ef upstream.
+
+If an LM73 device does not exist on an I2C bus, attempts to communicate
+with the device result in an error code returned from the i2c read/write
+functions. The current lm73 driver casts that return value from a s32
+type to a s16 type, then converts it to a temperature in celsius.
+Because negative temperatures are valid, it is difficult to distinguish
+between an error code printed to the response buffer and a negative
+temperature recorded by the sensor.
+
+The solution is to evaluate the return value from the i2c functions
+before performing any temperature calculations. If the i2c function did
+not succeed, the error code should be passed back through the virtual
+file system layer instead of being printed into the response buffer.
+
+Before:
+
+ $ cat /sys/class/hwmon/hwmon0/device/temp1_input
+ -46
+
+After:
+
+ $ cat /sys/class/hwmon/hwmon0/device/temp1_input
+ cat: read error: No such device or address
+
+Signed-off-by: Chris Verges <kg4ysn at gmail.com>
+Signed-off-by: Guenter Roeck <linux at roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/hwmon/lm73.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/hwmon/lm73.c
++++ b/drivers/hwmon/lm73.c
+@@ -49,6 +49,7 @@ static ssize_t set_temp(struct device *d
+ struct i2c_client *client = to_i2c_client(dev);
+ long temp;
+ short value;
++ s32 err;
+
+ int status = kstrtol(buf, 10, &temp);
+ if (status < 0)
+@@ -57,8 +58,8 @@ static ssize_t set_temp(struct device *d
+ /* Write value */
+ value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
+ (LM73_TEMP_MAX*4)) << 5;
+- i2c_smbus_write_word_swapped(client, attr->index, value);
+- return count;
++ err = i2c_smbus_write_word_swapped(client, attr->index, value);
++ return (err < 0) ? err : count;
+ }
+
+ static ssize_t show_temp(struct device *dev, struct device_attribute *da,
+@@ -66,11 +67,16 @@ static ssize_t show_temp(struct device *
+ {
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev);
++ int temp;
++
++ s32 err = i2c_smbus_read_word_swapped(client, attr->index);
++ if (err < 0)
++ return err;
++
+ /* use integer division instead of equivalent right shift to
+ guarantee arithmetic shift and preserve the sign */
+- int temp = ((s16) (i2c_smbus_read_word_swapped(client,
+- attr->index))*250) / 32;
+- return sprintf(buf, "%d\n", temp);
++ temp = (((s16) err) * 250) / 32;
++ return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
+ }
+
+
+From 7b9205bd775afc4439ed86d617f9042ee9e76a71 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook at chromium.org>
+Date: Fri, 11 Jan 2013 14:32:05 -0800
+Subject: audit: create explicit AUDIT_SECCOMP event type
+
+From: Kees Cook <keescook at chromium.org>
+
+commit 7b9205bd775afc4439ed86d617f9042ee9e76a71 upstream.
+
+The seccomp path was using AUDIT_ANOM_ABEND from when seccomp mode 1
+could only kill a process. While we still want to make sure an audit
+record is forced on a kill, this should use a separate record type since
+seccomp mode 2 introduces other behaviors.
+
+In the case of "handled" behaviors (process wasn't killed), only emit a
+record if the process is under inspection. This change also fixes
+userspace examination of seccomp audit events, since it was considered
+malformed due to missing fields of the AUDIT_ANOM_ABEND event type.
+
+Signed-off-by: Kees Cook <keescook at chromium.org>
+Cc: Al Viro <viro at zeniv.linux.org.uk>
+Cc: Eric Paris <eparis at redhat.com>
+Cc: Jeff Layton <jlayton at redhat.com>
+Cc: "Eric W. Biederman" <ebiederm at xmission.com>
+Cc: Julien Tinnes <jln at google.com>
+Acked-by: Will Drewry <wad at chromium.org>
+Acked-by: Steve Grubb <sgrubb at redhat.com>
+Cc: Andrea Arcangeli <aarcange at redhat.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ include/linux/audit.h | 3 ++-
+ include/uapi/linux/audit.h | 1 +
+ kernel/auditsc.c | 14 +++++++++++---
+ 3 files changed, 14 insertions(+), 4 deletions(-)
+
+--- a/include/linux/audit.h
++++ b/include/linux/audit.h
+@@ -157,7 +157,8 @@ void audit_core_dumps(long signr);
+
+ static inline void audit_seccomp(unsigned long syscall, long signr, int code)
+ {
+- if (unlikely(!audit_dummy_context()))
++ /* Force a record to be reported if a signal was delivered. */
++ if (signr || unlikely(!audit_dummy_context()))
+ __audit_seccomp(syscall, signr, code);
+ }
+
+--- a/include/uapi/linux/audit.h
++++ b/include/uapi/linux/audit.h
+@@ -106,6 +106,7 @@
+ #define AUDIT_MMAP 1323 /* Record showing descriptor and flags in mmap */
+ #define AUDIT_NETFILTER_PKT 1324 /* Packets traversing netfilter chains */
+ #define AUDIT_NETFILTER_CFG 1325 /* Netfilter chain modifications */
++#define AUDIT_SECCOMP 1326 /* Secure Computing event */
+
+ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */
+ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */
+--- a/kernel/auditsc.c
++++ b/kernel/auditsc.c
+@@ -2735,7 +2735,7 @@ void __audit_mmap_fd(int fd, int flags)
+ context->type = AUDIT_MMAP;
+ }
+
+-static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
++static void audit_log_task(struct audit_buffer *ab)
+ {
+ kuid_t auid, uid;
+ kgid_t gid;
+@@ -2753,6 +2753,11 @@ static void audit_log_abend(struct audit
+ audit_log_task_context(ab);
+ audit_log_format(ab, " pid=%d comm=", current->pid);
+ audit_log_untrustedstring(ab, current->comm);
++}
++
++static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
++{
++ audit_log_task(ab);
+ audit_log_format(ab, " reason=");
+ audit_log_string(ab, reason);
+ audit_log_format(ab, " sig=%ld", signr);
+@@ -2783,8 +2788,11 @@ void __audit_seccomp(unsigned long sysca
+ {
+ struct audit_buffer *ab;
+
+- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND);
+- audit_log_abend(ab, "seccomp", signr);
++ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP);
++ if (unlikely(!ab))
++ return;
++ audit_log_task(ab);
++ audit_log_format(ab, " sig=%ld", signr);
+ audit_log_format(ab, " syscall=%ld", syscall);
+ audit_log_format(ab, " compat=%d", is_compat_task());
+ audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current));
+From d9a58a782e396a0f04e8445b7ba3763c8a48c7fe Mon Sep 17 00:00:00 2001
+From: Ian Campbell <Ian.Campbell at citrix.com>
+Date: Mon, 7 Jan 2013 05:32:06 +0000
+Subject: xen/netfront: improve truesize tracking
+
+From: Ian Campbell <Ian.Campbell at citrix.com>
+
+commit d9a58a782e396a0f04e8445b7ba3763c8a48c7fe upstream.
+
+Using RX_COPY_THRESHOLD is incorrect if the SKB is actually smaller
+than that. We have already accounted for this in
+NETFRONT_SKB_CB(skb)->pull_to so use that instead.
+
+Fixes WARN_ON from skb_try_coalesce.
+
+Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
+Cc: Sander Eikelenboom <linux at eikelenboom.it>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Cc: annie li <annie.li at oracle.com>
+Cc: xen-devel at lists.xen.org
+Cc: netdev at vger.kernel.org
+Acked-by: Eric Dumazet <edumazet at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/xen-netfront.c | 27 ++++-----------------------
+ 1 file changed, 4 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -1015,29 +1015,10 @@ err:
+ i = xennet_fill_frags(np, skb, &tmpq);
+
+ /*
+- * Truesize approximates the size of true data plus
+- * any supervisor overheads. Adding hypervisor
+- * overheads has been shown to significantly reduce
+- * achievable bandwidth with the default receive
+- * buffer size. It is therefore not wise to account
+- * for it here.
+- *
+- * After alloc_skb(RX_COPY_THRESHOLD), truesize is set
+- * to RX_COPY_THRESHOLD + the supervisor
+- * overheads. Here, we add the size of the data pulled
+- * in xennet_fill_frags().
+- *
+- * We also adjust for any unused space in the main
+- * data area by subtracting (RX_COPY_THRESHOLD -
+- * len). This is especially important with drivers
+- * which split incoming packets into header and data,
+- * using only 66 bytes of the main data area (see the
+- * e1000 driver for example.) On such systems,
+- * without this last adjustement, our achievable
+- * receive throughout using the standard receive
+- * buffer size was cut by 25%(!!!).
+- */
+- skb->truesize += skb->data_len - RX_COPY_THRESHOLD;
++ * Truesize is the actual allocation size, even if the
++ * allocation is only partially used.
++ */
++ skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags;
+ skb->len += skb->data_len;
+
+ if (rx->flags & XEN_NETRXF_csum_blank)
+From 92638e2facc5330475c7d558acec77721c3214e4 Mon Sep 17 00:00:00 2001
+From: Sivaram Nair <sivaramn at nvidia.com>
+Date: Tue, 18 Dec 2012 13:52:54 +0100
+Subject: cpuidle / coupled: fix ready counter decrement
+
+From: Sivaram Nair <sivaramn at nvidia.com>
+
+commit 92638e2facc5330475c7d558acec77721c3214e4 upstream.
+
+The ready_waiting_counts atomic variable is compared against the wrong
+online cpu count. The latter is computed incorrectly using logical-OR
+instead of bit-OR. This patch fixes that.
+
+Signed-off-by: Sivaram Nair <sivaramn at nvidia.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar at ti.com>
+Acked-by: Colin Cross <ccross at android.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/cpuidle/coupled.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/cpuidle/coupled.c
++++ b/drivers/cpuidle/coupled.c
+@@ -209,7 +209,7 @@ inline int cpuidle_coupled_set_not_ready
+ int all;
+ int ret;
+
+- all = coupled->online_count || (coupled->online_count << WAITING_BITS);
++ all = coupled->online_count | (coupled->online_count << WAITING_BITS);
+ ret = atomic_add_unless(&coupled->ready_waiting_counts,
+ -MAX_WAITING_CPUS, all);
+
+From 619c5a9ad54e6bbdafd16d1cdc6c049403710540 Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <meuleman at broadcom.com>
+Date: Wed, 2 Jan 2013 15:12:39 +0100
+Subject: brcmfmac: fix parsing rsn ie for ap mode.
+
+From: Hante Meuleman <meuleman at broadcom.com>
+
+commit 619c5a9ad54e6bbdafd16d1cdc6c049403710540 upstream.
+
+RSN IEs got incorrectly parsed and therefore ap mode using WPA2
+security was not working.
+
+Reviewed-by: Arend Van Spriel <arend at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg at broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman at broadcom.com>
+Signed-off-by: Arend van Spriel <arend at broadcom.com>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+@@ -3730,10 +3730,11 @@ brcmf_configure_wpaie(struct net_device
+
+ len = wpa_ie->len + TLV_HDR_LEN;
+ data = (u8 *)wpa_ie;
+- offset = 0;
++ offset = TLV_HDR_LEN;
+ if (!is_rsn_ie)
+ offset += VS_IE_FIXED_HDR_LEN;
+- offset += WPA_IE_VERSION_LEN;
++ else
++ offset += WPA_IE_VERSION_LEN;
+
+ /* check for multicast cipher suite */
+ if (offset + WPA_IE_MIN_OUI_LEN > len) {
+From 6c1ecba8d84841277d68140ef485335d5be28485 Mon Sep 17 00:00:00 2001
+From: Lothar Waßmann <LW at KARO-electronics.de>
+Date: Thu, 22 Nov 2012 13:49:14 +0100
+Subject: video: mxsfb: fix crash when unblanking the display
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Lothar Waßmann <LW at KARO-electronics.de>
+
+commit 6c1ecba8d84841277d68140ef485335d5be28485 upstream.
+
+The VDCTRL4 register does not provide the MXS SET/CLR/TOGGLE feature.
+The write in mxsfb_disable_controller() sets the data_cnt for the LCD
+DMA to 0 which obviously means the max. count for the LCD DMA and
+leads to overwriting arbitrary memory when the display is unblanked.
+
+Signed-off-by: Lothar Waßmann <LW at KARO-electronics.de>
+Acked-by: Juergen Beisert <jbe at pengutronix.de>
+Tested-by: Lauri Hintsala <lauri.hintsala at bluegiga.net>
+Signed-off-by: Shawn Guo <shawn.guo at linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/video/mxsfb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/mxsfb.c
++++ b/drivers/video/mxsfb.c
+@@ -369,7 +369,8 @@ static void mxsfb_disable_controller(str
+ loop--;
+ }
+
+- writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR);
++ reg = readl(host->base + LCDC_VDCTRL4);
++ writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
+
+ clk_disable_unprepare(host->clk);
+
+From e04c200f1f2de8eaa2f5af6d97e7e213a1abb424 Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee at canonical.com>
+Date: Wed, 5 Dec 2012 16:08:33 -0600
+Subject: samsung-laptop: Add quirk for broken acpi_video backlight on N250P
+
+From: Seth Forshee <seth.forshee at canonical.com>
+
+commit e04c200f1f2de8eaa2f5af6d97e7e213a1abb424 upstream.
+
+BugLink: http://bugs.launchpad.net/bugs/1086921
+Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
+Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/platform/x86/samsung-laptop.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/platform/x86/samsung-laptop.c
++++ b/drivers/platform/x86/samsung-laptop.c
+@@ -1523,6 +1523,16 @@ static struct dmi_system_id __initdata s
+ },
+ .driver_data = &samsung_broken_acpi_video,
+ },
++ {
++ .callback = samsung_dmi_matched,
++ .ident = "N250P",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
++ DMI_MATCH(DMI_PRODUCT_NAME, "N250P"),
++ DMI_MATCH(DMI_BOARD_NAME, "N250P"),
++ },
++ .driver_data = &samsung_broken_acpi_video,
++ },
+ { },
+ };
+ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
+From 9f6d8f6ab26b42620a914d67f29822f9bba90233 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki at intel.com>
+Date: Sat, 22 Dec 2012 23:59:01 +0100
+Subject: PM: Move disabling/enabling runtime PM to late suspend/early resume
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki at intel.com>
+
+commit 9f6d8f6ab26b42620a914d67f29822f9bba90233 upstream.
+
+Currently, the PM core disables runtime PM for all devices right
+after executing subsystem/driver .suspend() callbacks for them
+and re-enables it right before executing subsystem/driver .resume()
+callbacks for them. This may lead to problems when there are
+two devices such that the .suspend() callback executed for one of
+them depends on runtime PM working for the other. In that case,
+if runtime PM has already been disabled for the second device,
+the first one's .suspend() won't work correctly (and analogously
+for resume).
+
+To make those issues go away, make the PM core disable runtime PM
+for devices right before executing subsystem/driver .suspend_late()
+callbacks for them and enable runtime PM for them right after
+executing subsystem/driver .resume_early() callbacks for them. This
+way the potential conflitcs between .suspend_late()/.resume_early()
+and their runtime PM counterparts are still prevented from happening,
+but the subtle ordering issues related to disabling/enabling runtime
+PM for devices during system suspend/resume are much easier to avoid.
+
+Reported-and-tested-by: Jan-Matthias Braun <jan_braun at gmx.net>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
+Reviewed-by: Kevin Hilman <khilman at deeprootsystems.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ Documentation/power/runtime_pm.txt | 9 +++++----
+ drivers/base/power/main.c | 9 ++++-----
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/Documentation/power/runtime_pm.txt
++++ b/Documentation/power/runtime_pm.txt
+@@ -642,12 +642,13 @@ out the following operations:
+ * During system suspend it calls pm_runtime_get_noresume() and
+ pm_runtime_barrier() for every device right before executing the
+ subsystem-level .suspend() callback for it. In addition to that it calls
+- pm_runtime_disable() for every device right after executing the
+- subsystem-level .suspend() callback for it.
++ __pm_runtime_disable() with 'false' as the second argument for every device
++ right before executing the subsystem-level .suspend_late() callback for it.
+
+ * During system resume it calls pm_runtime_enable() and pm_runtime_put_sync()
+- for every device right before and right after executing the subsystem-level
+- .resume() callback for it, respectively.
++ for every device right after executing the subsystem-level .resume_early()
++ callback and right after executing the subsystem-level .resume() callback
++ for it, respectively.
+
+ 7. Generic subsystem callbacks
+
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -513,6 +513,8 @@ static int device_resume_early(struct de
+
+ Out:
+ TRACE_RESUME(error);
++
++ pm_runtime_enable(dev);
+ return error;
+ }
+
+@@ -589,8 +591,6 @@ static int device_resume(struct device *
+ if (!dev->power.is_suspended)
+ goto Unlock;
+
+- pm_runtime_enable(dev);
+-
+ if (dev->pm_domain) {
+ info = "power domain ";
+ callback = pm_op(&dev->pm_domain->ops, state);
+@@ -930,6 +930,8 @@ static int device_suspend_late(struct de
+ pm_callback_t callback = NULL;
+ char *info = NULL;
+
++ __pm_runtime_disable(dev, false);
++
+ if (dev->power.syscore)
+ return 0;
+
+@@ -1133,11 +1135,8 @@ static int __device_suspend(struct devic
+
+ Complete:
+ complete_all(&dev->power.completion);
+-
+ if (error)
+ async_error = error;
+- else if (dev->power.is_suspended)
+- __pm_runtime_disable(dev, false);
+
+ return error;
+ }
+From c36575e663e302dbaa4d16b9c72d2c9a913a9aef Mon Sep 17 00:00:00 2001
+From: Forrest Liu <forrestl at synology.com>
+Date: Mon, 17 Dec 2012 09:55:39 -0500
+Subject: ext4: fix extent tree corruption caused by hole punch
+
+From: Forrest Liu <forrestl at synology.com>
+
+commit c36575e663e302dbaa4d16b9c72d2c9a913a9aef upstream.
+
+When depth of extent tree is greater than 1, logical start value of
+interior node is not correctly updated in ext4_ext_rm_idx.
+
+Signed-off-by: Forrest Liu <forrestl at synology.com>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Reviewed-by: Ashish Sangwan <ashishsangwan2 at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/extents.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -2190,13 +2190,14 @@ errout:
+ * removes index from the index block.
+ */
+ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
+- struct ext4_ext_path *path)
++ struct ext4_ext_path *path, int depth)
+ {
+ int err;
+ ext4_fsblk_t leaf;
+
+ /* free index block */
+- path--;
++ depth--;
++ path = path + depth;
+ leaf = ext4_idx_pblock(path->p_idx);
+ if (unlikely(path->p_hdr->eh_entries == 0)) {
+ EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0");
+@@ -2221,6 +2222,19 @@ static int ext4_ext_rm_idx(handle_t *han
+
+ ext4_free_blocks(handle, inode, NULL, leaf, 1,
+ EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
++
++ while (--depth >= 0) {
++ if (path->p_idx != EXT_FIRST_INDEX(path->p_hdr))
++ break;
++ path--;
++ err = ext4_ext_get_access(handle, inode, path);
++ if (err)
++ break;
++ path->p_idx->ei_block = (path+1)->p_idx->ei_block;
++ err = ext4_ext_dirty(handle, inode, path);
++ if (err)
++ break;
++ }
+ return err;
+ }
+
+@@ -2557,7 +2571,7 @@ ext4_ext_rm_leaf(handle_t *handle, struc
+ /* if this leaf is free, then we should
+ * remove it from index block above */
+ if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
+- err = ext4_ext_rm_idx(handle, inode, path + depth);
++ err = ext4_ext_rm_idx(handle, inode, path, depth);
+
+ out:
+ return err;
+@@ -2760,7 +2774,7 @@ again:
+ /* index is empty, remove it;
+ * handle must be already prepared by the
+ * truncatei_leaf() */
+- err = ext4_ext_rm_idx(handle, inode, path + i);
++ err = ext4_ext_rm_idx(handle, inode, path, i);
+ }
+ /* root level has p_bh == NULL, brelse() eats this */
+ brelse(path[i].p_bh);
+From 261cb20cb2f0737a247aaf08dff7eb065e3e5b66 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack at suse.cz>
+Date: Thu, 20 Dec 2012 00:07:18 -0500
+Subject: ext4: check dioread_nolock on remount
+
+From: Jan Kara <jack at suse.cz>
+
+commit 261cb20cb2f0737a247aaf08dff7eb065e3e5b66 upstream.
+
+Currently we allow enabling dioread_nolock mount option on remount for
+filesystems where blocksize < PAGE_CACHE_SIZE. This isn't really
+supported so fix the bug by moving the check for blocksize !=
+PAGE_CACHE_SIZE into parse_options(). Change the original PAGE_SIZE to
+PAGE_CACHE_SIZE along the way because that's what we are really
+interested in.
+
+Signed-off-by: Jan Kara <jack at suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Reviewed-by: Eric Sandeen <sandeen at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1650,9 +1650,7 @@ static int parse_options(char *options,
+ unsigned int *journal_ioprio,
+ int is_remount)
+ {
+-#ifdef CONFIG_QUOTA
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+-#endif
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+@@ -1701,6 +1699,16 @@ static int parse_options(char *options,
+ }
+ }
+ #endif
++ if (test_opt(sb, DIOREAD_NOLOCK)) {
++ int blocksize =
++ BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
++
++ if (blocksize < PAGE_CACHE_SIZE) {
++ ext4_msg(sb, KERN_ERR, "can't mount with "
++ "dioread_nolock if block size != PAGE_SIZE");
++ return 0;
++ }
++ }
+ return 1;
+ }
+
+@@ -3446,15 +3454,6 @@ static int ext4_fill_super(struct super_
+ clear_opt(sb, DELALLOC);
+ }
+
+- blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
+- if (test_opt(sb, DIOREAD_NOLOCK)) {
+- if (blocksize < PAGE_SIZE) {
+- ext4_msg(sb, KERN_ERR, "can't mount with "
+- "dioread_nolock if block size != PAGE_SIZE");
+- goto failed_mount;
+- }
+- }
+-
+ sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
+ (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0);
+
+@@ -3496,6 +3495,7 @@ static int ext4_fill_super(struct super_
+ if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY)))
+ goto failed_mount;
+
++ blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
+ if (blocksize < EXT4_MIN_BLOCK_SIZE ||
+ blocksize > EXT4_MAX_BLOCK_SIZE) {
+ ext4_msg(sb, KERN_ERR,
+From d7961c7fa4d2e3c3f12be67e21ba8799b5a7238a Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack at suse.cz>
+Date: Fri, 21 Dec 2012 00:15:51 -0500
+Subject: jbd2: fix assertion failure in jbd2_journal_flush()
+
+From: Jan Kara <jack at suse.cz>
+
+commit d7961c7fa4d2e3c3f12be67e21ba8799b5a7238a upstream.
+
+The following race is possible between start_this_handle() and someone
+calling jbd2_journal_flush().
+
+Process A Process B
+start_this_handle().
+ if (journal->j_barrier_count) # false
+ if (!journal->j_running_transaction) { #true
+ read_unlock(&journal->j_state_lock);
+ jbd2_journal_lock_updates()
+ jbd2_journal_flush()
+ write_lock(&journal->j_state_lock);
+ if (journal->j_running_transaction) {
+ # false
+ ... wait for committing trans ...
+ write_unlock(&journal->j_state_lock);
+ ...
+ write_lock(&journal->j_state_lock);
+ if (!journal->j_running_transaction) { # true
+ jbd2_get_transaction(journal, new_transaction);
+ write_unlock(&journal->j_state_lock);
+ goto repeat; # eventually blocks on j_barrier_count > 0
+ ...
+ J_ASSERT(!journal->j_running_transaction);
+ # fails
+
+We fix the race by rechecking j_barrier_count after reacquiring j_state_lock
+in exclusive mode.
+
+Reported-by: yjwsignal at empal.com
+Signed-off-by: Jan Kara <jack at suse.cz>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/jbd2/transaction.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -209,7 +209,8 @@ repeat:
+ if (!new_transaction)
+ goto alloc_transaction;
+ write_lock(&journal->j_state_lock);
+- if (!journal->j_running_transaction) {
++ if (!journal->j_running_transaction &&
++ !journal->j_barrier_count) {
+ jbd2_get_transaction(journal, new_transaction);
+ new_transaction = NULL;
+ }
+From d096ad0f79a782935d2e06ae8fb235e8c5397775 Mon Sep 17 00:00:00 2001
+From: Michael Tokarev <mjt at tls.msk.ru>
+Date: Tue, 25 Dec 2012 14:08:16 -0500
+Subject: ext4: do not try to write superblock on ro remount w/o journal
+
+From: Michael Tokarev <mjt at tls.msk.ru>
+
+commit d096ad0f79a782935d2e06ae8fb235e8c5397775 upstream.
+
+When a journal-less ext4 filesystem is mounted on a read-only block
+device (blockdev --setro will do), each remount (for other, unrelated,
+flags, like suid=>nosuid etc) results in a series of scary messages
+from kernel telling about I/O errors on the device.
+
+This is becauese of the following code ext4_remount():
+
+ if (sbi->s_journal == NULL)
+ ext4_commit_super(sb, 1);
+
+at the end of remount procedure, which forces writing (flushing) of
+a superblock regardless whenever it is dirty or not, if the filesystem
+is readonly or not, and whenever the device itself is readonly or not.
+
+We only need call ext4_commit_super when the file system had been
+previously mounted read/write.
+
+Thanks to Eric Sandeen for help in diagnosing this issue.
+
+Signed-off-By: Michael Tokarev <mjt at tls.msk.ru>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4729,7 +4729,7 @@ static int ext4_remount(struct super_blo
+ }
+
+ ext4_setup_system_zone(sb);
+- if (sbi->s_journal == NULL)
++ if (sbi->s_journal == NULL && !(old_sb_flags & MS_RDONLY))
+ ext4_commit_super(sb, 1);
+
+ #ifdef CONFIG_QUOTA
+From 721e3eba21e43532e438652dd8f1fcdfce3187e7 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso at mit.edu>
+Date: Thu, 27 Dec 2012 01:42:48 -0500
+Subject: ext4: lock i_mutex when truncating orphan inodes
+
+From: Theodore Ts'o <tytso at mit.edu>
+
+commit 721e3eba21e43532e438652dd8f1fcdfce3187e7 upstream.
+
+Commit c278531d39 added a warning when ext4_flush_unwritten_io() is
+called without i_mutex being taken. It had previously not been taken
+during orphan cleanup since races weren't possible at that point in
+the mount process, but as a result of this c278531d39, we will now see
+a kernel WARN_ON in this case. Take the i_mutex in
+ext4_orphan_cleanup() to suppress this warning.
+
+Reported-by: Alexander Beregalov <a.beregalov at gmail.com>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Reviewed-by: Zheng Liu <wenqing.lz at taobao.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2225,7 +2225,9 @@ static void ext4_orphan_cleanup(struct s
+ __func__, inode->i_ino, inode->i_size);
+ jbd_debug(2, "truncating inode %lu to %lld bytes\n",
+ inode->i_ino, inode->i_size);
++ mutex_lock(&inode->i_mutex);
+ ext4_truncate(inode);
++ mutex_unlock(&inode->i_mutex);
+ nr_truncates++;
+ } else {
+ ext4_msg(sb, KERN_DEBUG,
+From 0e9a9a1ad619e7e987815d20262d36a2f95717ca Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso at mit.edu>
+Date: Thu, 27 Dec 2012 01:42:50 -0500
+Subject: ext4: avoid hang when mounting non-journal filesystems with orphan list
+
+From: Theodore Ts'o <tytso at mit.edu>
+
+commit 0e9a9a1ad619e7e987815d20262d36a2f95717ca upstream.
+
+When trying to mount a file system which does not contain a journal,
+but which does have a orphan list containing an inode which needs to
+be truncated, the mount call with hang forever in
+ext4_orphan_cleanup() because ext4_orphan_del() will return
+immediately without removing the inode from the orphan list, leading
+to an uninterruptible loop in kernel code which will busy out one of
+the CPU's on the system.
+
+This can be trivially reproduced by trying to mount the file system
+found in tests/f_orphan_extents_inode/image.gz from the e2fsprogs
+source tree. If a malicious user were to put this on a USB stick, and
+mount it on a Linux desktop which has automatic mounts enabled, this
+could be considered a potential denial of service attack. (Not a big
+deal in practice, but professional paranoids worry about such things,
+and have even been known to allocate CVE numbers for such problems.)
+
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Reviewed-by: Zheng Liu <wenqing.lz at taobao.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/namei.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2498,7 +2498,8 @@ int ext4_orphan_del(handle_t *handle, st
+ struct ext4_iloc iloc;
+ int err = 0;
+
+- if (!EXT4_SB(inode->i_sb)->s_journal)
++ if ((!EXT4_SB(inode->i_sb)->s_journal) &&
++ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS))
+ return 0;
+
+ mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
+From 0ecaef0644973e9006fdbc6974301047aaff9bc6 Mon Sep 17 00:00:00 2001
+From: Guo Chao <yan at linux.vnet.ibm.com>
+Date: Sun, 6 Jan 2013 23:38:47 -0500
+Subject: ext4: release buffer in failed path in dx_probe()
+
+From: Guo Chao <yan at linux.vnet.ibm.com>
+
+commit 0ecaef0644973e9006fdbc6974301047aaff9bc6 upstream.
+
+If checksum fails, we should also release the buffer
+read from previous iteration.
+
+Signed-off-by: Guo Chao <yan at linux.vnet.ibm.com>
+Signed-off-by: "Theodore Ts'o" <tytso at mit.edu>
+Reviewed-by: Darrick J. Wong <darrick.wong at oracle.com>-
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/ext4/namei.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -725,7 +725,7 @@ dx_probe(const struct qstr *d_name, stru
+ ext4_warning(dir->i_sb, "Node failed checksum");
+ brelse(bh);
+ *err = ERR_BAD_DX_DIR;
+- goto fail;
++ goto fail2;
+ }
+ set_buffer_verified(bh);
+
+From 0a41409c518083133e79015092585d68915865be Mon Sep 17 00:00:00 2001
+From: Ed Cashin <ecashin at coraid.com>
+Date: Mon, 17 Dec 2012 16:03:58 -0800
+Subject: aoe: remove vestigial request queue allocation
+
+From: Ed Cashin <ecashin at coraid.com>
+
+commit 0a41409c518083133e79015092585d68915865be upstream.
+
+Before the aoe driver was an I/O request handler, it was a
+make_request-style block driver. Even so, there was a problem where
+sysfs expected a request queue to exist, so one was provided in commit
+7135a71b19be ("aoe: allocate unused request_queue for sysfs").
+
+During the transition to the request-handler style, a patch was merged
+that was based on a driver without the noop queue, and the noop queue
+remained in place after the patch was merged, even though a new
+functional queue was introduced by the patch, allocated through
+blk_init_queue.
+
+The user impact is a memory leak proportional to the number of AoE
+targets discovered. This patch removes the memory leak and cleans up
+vestiges of the old do-nothing queue from the aoeblk_gdalloc function.
+
+Signed-off-by: Ed Cashin <ecashin at coraid.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/block/aoe/aoeblk.c | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+--- a/drivers/block/aoe/aoeblk.c
++++ b/drivers/block/aoe/aoeblk.c
+@@ -231,18 +231,12 @@ aoeblk_gdalloc(void *vp)
+ if (q == NULL) {
+ pr_err("aoe: cannot allocate block queue for %ld.%d\n",
+ d->aoemajor, d->aoeminor);
+- mempool_destroy(mp);
+- goto err_disk;
++ goto err_mempool;
+ }
+
+- d->blkq = blk_alloc_queue(GFP_KERNEL);
+- if (!d->blkq)
+- goto err_mempool;
+- d->blkq->backing_dev_info.name = "aoe";
+- if (bdi_init(&d->blkq->backing_dev_info))
+- goto err_blkq;
+ spin_lock_irqsave(&d->lock, flags);
+- blk_queue_max_hw_sectors(d->blkq, BLK_DEF_MAX_SECTORS);
++ blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS);
++ q->backing_dev_info.name = "aoe";
+ q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE;
+ d->bufpool = mp;
+ d->blkq = gd->queue = q;
+@@ -265,11 +259,8 @@ aoeblk_gdalloc(void *vp)
+ aoedisk_add_sysfs(d);
+ return;
+
+-err_blkq:
+- blk_cleanup_queue(d->blkq);
+- d->blkq = NULL;
+ err_mempool:
+- mempool_destroy(d->bufpool);
++ mempool_destroy(mp);
+ err_disk:
+ put_disk(gd);
+ err:
+From 2fb7d99d0de3fd8ae869f35ab682581d8455887a Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon at samsung.com>
+Date: Wed, 10 Oct 2012 00:08:56 +0900
+Subject: udf: fix memory leak while allocating blocks during write
+
+From: Namjae Jeon <namjae.jeon at samsung.com>
+
+commit 2fb7d99d0de3fd8ae869f35ab682581d8455887a upstream.
+
+Need to brelse the buffer_head stored in cur_epos and next_epos.
+
+Signed-off-by: Namjae Jeon <namjae.jeon at samsung.com>
+Signed-off-by: Ashish Sangwan <a.sangwan at samsung.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+Signed-off-by: Shuah Khan <shuah.khan at hp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/udf/inode.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -765,6 +765,8 @@ static sector_t inode_getblk(struct inod
+ goal, err);
+ if (!newblocknum) {
+ brelse(prev_epos.bh);
++ brelse(cur_epos.bh);
++ brelse(next_epos.bh);
+ *err = -ENOSPC;
+ return 0;
+ }
+@@ -795,6 +797,8 @@ static sector_t inode_getblk(struct inod
+ udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
+
+ brelse(prev_epos.bh);
++ brelse(cur_epos.bh);
++ brelse(next_epos.bh);
+
+ newblock = udf_get_pblock(inode->i_sb, newblocknum,
+ iinfo->i_location.partitionReferenceNum, 0);
+From fb719c59bdb4fca86ee1fd1f42ab3735ca12b6b2 Mon Sep 17 00:00:00 2001
+From: Namjae Jeon <namjae.jeon at samsung.com>
+Date: Wed, 10 Oct 2012 00:09:12 +0900
+Subject: udf: don't increment lenExtents while writing to a hole
+
+From: Namjae Jeon <namjae.jeon at samsung.com>
+
+commit fb719c59bdb4fca86ee1fd1f42ab3735ca12b6b2 upstream.
+
+Incrementing lenExtents even while writing to a hole is bad
+for performance as calls to udf_discard_prealloc and
+udf_truncate_tail_extent would not return from start if
+isize != lenExtents
+
+Signed-off-by: Namjae Jeon <namjae.jeon at samsung.com>
+Signed-off-by: Ashish Sangwan <a.sangwan at samsung.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+Signed-off-by: Shuah Khan <shuah.khan at hp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/udf/inode.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/udf/inode.c
++++ b/fs/udf/inode.c
+@@ -601,6 +601,7 @@ static sector_t inode_getblk(struct inod
+ struct udf_inode_info *iinfo = UDF_I(inode);
+ int goal = 0, pgoal = iinfo->i_location.logicalBlockNum;
+ int lastblock = 0;
++ bool isBeyondEOF;
+
+ *err = 0;
+ *new = 0;
+@@ -680,7 +681,7 @@ static sector_t inode_getblk(struct inod
+ /* Are we beyond EOF? */
+ if (etype == -1) {
+ int ret;
+-
++ isBeyondEOF = 1;
+ if (count) {
+ if (c)
+ laarr[0] = laarr[1];
+@@ -723,6 +724,7 @@ static sector_t inode_getblk(struct inod
+ endnum = c + 1;
+ lastblock = 1;
+ } else {
++ isBeyondEOF = 0;
+ endnum = startnum = ((count > 2) ? 2 : count);
+
+ /* if the current extent is in position 0,
+@@ -770,7 +772,8 @@ static sector_t inode_getblk(struct inod
+ *err = -ENOSPC;
+ return 0;
+ }
+- iinfo->i_lenExtents += inode->i_sb->s_blocksize;
++ if (isBeyondEOF)
++ iinfo->i_lenExtents += inode->i_sb->s_blocksize;
+ }
+
+ /* if the extent the requsted block is located in contains multiple
+From b7e383046c2c7c13ad928cd7407eafff758ddd4b Mon Sep 17 00:00:00 2001
+From: Zhang Rui <rui.zhang at intel.com>
+Date: Tue, 4 Dec 2012 23:23:16 +0100
+Subject: ACPI : do not use Lid and Sleep button for S5 wakeup
+
+From: Zhang Rui <rui.zhang at intel.com>
+
+commit b7e383046c2c7c13ad928cd7407eafff758ddd4b upstream.
+
+When system enters power off, the _PSW of Lid device is enabled.
+But this may cause the system to reboot instead of power off.
+
+A proper way to fix this is to always disable lid wakeup capability for S5.
+
+References: https://bugzilla.kernel.org/show_bug.cgi?id=35262
+Signed-off-by: Zhang Rui <rui.zhang at intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
+Cc: Joseph Salisbury <joseph.salisbury at canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/acpi/scan.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -859,8 +859,8 @@ acpi_bus_extract_wakeup_device_power_pac
+ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
+ {
+ struct acpi_device_id button_device_ids[] = {
+- {"PNP0C0D", 0},
+ {"PNP0C0C", 0},
++ {"PNP0C0D", 0},
+ {"PNP0C0E", 0},
+ {"", 0},
+ };
+@@ -872,6 +872,11 @@ static void acpi_bus_set_run_wake_flags(
+ /* Power button, Lid switch always enable wakeup */
+ if (!acpi_match_device_ids(device, button_device_ids)) {
+ device->wakeup.flags.run_wake = 1;
++ if (!acpi_match_device_ids(device, &button_device_ids[1])) {
++ /* Do not use Lid/sleep button for S5 wakeup */
++ if (device->wakeup.sleep_state == ACPI_STATE_S5)
++ device->wakeup.sleep_state = ACPI_STATE_S4;
++ }
+ device_set_wakeup_capable(&device->dev, true);
+ return;
+ }
+From db04328c167ff8e7c57f4a3532214aeada3a82fd Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Tue, 11 Dec 2012 01:14:11 +0900
+Subject: regmap: debugfs: Avoid overflows for very small reads
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit db04328c167ff8e7c57f4a3532214aeada3a82fd upstream.
+
+If count is less than the size of a register then we may hit integer
+wraparound when trying to move backwards to check if we're still in
+the buffer. Instead move the position forwards to check if it's still
+in the buffer, we are unlikely to be able to allocate a buffer
+sufficiently big to overflow here.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Cc: stable at vger.kernel.org
+
+---
+ drivers/base/regmap/regmap-debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/base/regmap/regmap-debugfs.c
++++ b/drivers/base/regmap/regmap-debugfs.c
+@@ -90,7 +90,7 @@ static ssize_t regmap_map_read_file(stru
+ /* If we're in the region the user is trying to read */
+ if (p >= *ppos) {
+ /* ...but not beyond it */
+- if (buf_pos >= count - 1 - tot_len)
++ if (buf_pos + 1 + tot_len >= count)
+ break;
+
+ /* Format the register */
+From 128dd1759d96ad36c379240f8b9463e8acfd37a1 Mon Sep 17 00:00:00 2001
+From: Eric Wong <normalperson at yhbt.net>
+Date: Tue, 1 Jan 2013 21:20:27 +0000
+Subject: epoll: prevent missed events on EPOLL_CTL_MOD
+
+From: Eric Wong <normalperson at yhbt.net>
+
+commit 128dd1759d96ad36c379240f8b9463e8acfd37a1 upstream.
+
+EPOLL_CTL_MOD sets the interest mask before calling f_op->poll() to
+ensure events are not missed. Since the modifications to the interest
+mask are not protected by the same lock as ep_poll_callback, we need to
+ensure the change is visible to other CPUs calling ep_poll_callback.
+
+We also need to ensure f_op->poll() has an up-to-date view of past
+events which occured before we modified the interest mask. So this
+barrier also pairs with the barrier in wq_has_sleeper().
+
+This should guarantee either ep_poll_callback or f_op->poll() (or both)
+will notice the readiness of a recently-ready/modified item.
+
+This issue was encountered by Andreas Voellmy and Junchang(Jason) Wang in:
+http://thread.gmane.org/gmane.linux.kernel/1408782/
+
+Signed-off-by: Eric Wong <normalperson at yhbt.net>
+Cc: Hans Verkuil <hans.verkuil at cisco.com>
+Cc: Jiri Olsa <jolsa at redhat.com>
+Cc: Jonathan Corbet <corbet at lwn.net>
+Cc: Al Viro <viro at zeniv.linux.org.uk>
+Cc: Davide Libenzi <davidel at xmailserver.org>
+Cc: Hans de Goede <hdegoede at redhat.com>
+Cc: Mauro Carvalho Chehab <mchehab at infradead.org>
+Cc: David Miller <davem at davemloft.net>
+Cc: Eric Dumazet <eric.dumazet at gmail.com>
+Cc: Andrew Morton <akpm at linux-foundation.org>
+Cc: Andreas Voellmy <andreas.voellmy at yale.edu>
+Tested-by: "Junchang(Jason) Wang" <junchang.wang at yale.edu>
+Cc: netdev at vger.kernel.org
+Cc: linux-fsdevel at vger.kernel.org
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/eventpoll.c | 22 +++++++++++++++++++++-
+ 1 file changed, 21 insertions(+), 1 deletion(-)
+
+--- a/fs/eventpoll.c
++++ b/fs/eventpoll.c
+@@ -1285,7 +1285,7 @@ static int ep_modify(struct eventpoll *e
+ * otherwise we might miss an event that happens between the
+ * f_op->poll() call and the new event set registering.
+ */
+- epi->event.events = event->events;
++ epi->event.events = event->events; /* need barrier below */
+ pt._key = event->events;
+ epi->event.data = event->data; /* protected by mtx */
+ if (epi->event.events & EPOLLWAKEUP) {
+@@ -1296,6 +1296,26 @@ static int ep_modify(struct eventpoll *e
+ }
+
+ /*
++ * The following barrier has two effects:
++ *
++ * 1) Flush epi changes above to other CPUs. This ensures
++ * we do not miss events from ep_poll_callback if an
++ * event occurs immediately after we call f_op->poll().
++ * We need this because we did not take ep->lock while
++ * changing epi above (but ep_poll_callback does take
++ * ep->lock).
++ *
++ * 2) We also need to ensure we do not miss _past_ events
++ * when calling f_op->poll(). This barrier also
++ * pairs with the barrier in wq_has_sleeper (see
++ * comments for wq_has_sleeper).
++ *
++ * This barrier will now guarantee ep_poll_callback or f_op->poll
++ * (or both) will notice the readiness of an item.
++ */
++ smp_mb();
++
++ /*
+ * Get current event bits. We can safely use the file* here because
+ * its usage count has been increased by the caller of this function.
+ */
+From 436136cec650d661eb662fcb508a99878606d050 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex at denx.de>
+Date: Sat, 24 Nov 2012 06:15:57 +0100
+Subject: HID: add quirk for Freescale i.MX23 ROM recovery
+
+From: Marek Vasut <marex at denx.de>
+
+commit 436136cec650d661eb662fcb508a99878606d050 upstream.
+
+The USB recovery mode present in i.MX23 ROM emulates USB HID. It needs this
+quirk to behave properly.
+
+Even if the official branding of the chip is Freescale i.MX23, I named it
+Sigmatel STMP3780 since that's what the chip really is and it even reports
+itself as STMP3780.
+
+Signed-off-by: Marek Vasut <marex at denx.de>
+Signed-off-by: Jiri Kosina <jkosina at suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/hid/hid-ids.h | 3 +++
+ drivers/hid/usbhid/hid-quirks.c | 1 +
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -696,6 +696,9 @@
+ #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
+ #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
+
++#define USB_VENDOR_ID_SIGMATEL 0x066F
++#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
++
+ #define USB_VENDOR_ID_SKYCABLE 0x1223
+ #define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
+
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -79,6 +79,7 @@ static const struct hid_blacklist {
+ { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
++ { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
+From a8c02db029385fb4426e0396e108ab23cd08f384 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Tue, 18 Dec 2012 14:05:01 +0000
+Subject: ASoC: arizona: Correct FLL source definitions
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit a8c02db029385fb4426e0396e108ab23cd08f384 upstream.
+
+The FLL source constants were numbered as a simple enumeration but were
+being used in the code as direct values to be written to the registers.
+Renumber the constants to reflect the usage.
+
+Reported-by: Ryo Tsutsui <Ryo.Tsutsui at wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/arizona.h | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/sound/soc/codecs/arizona.h
++++ b/sound/soc/codecs/arizona.h
+@@ -32,15 +32,15 @@
+
+ #define ARIZONA_FLL_SRC_MCLK1 0
+ #define ARIZONA_FLL_SRC_MCLK2 1
+-#define ARIZONA_FLL_SRC_SLIMCLK 2
+-#define ARIZONA_FLL_SRC_FLL1 3
+-#define ARIZONA_FLL_SRC_FLL2 4
+-#define ARIZONA_FLL_SRC_AIF1BCLK 5
+-#define ARIZONA_FLL_SRC_AIF2BCLK 6
+-#define ARIZONA_FLL_SRC_AIF3BCLK 7
+-#define ARIZONA_FLL_SRC_AIF1LRCLK 8
+-#define ARIZONA_FLL_SRC_AIF2LRCLK 9
+-#define ARIZONA_FLL_SRC_AIF3LRCLK 10
++#define ARIZONA_FLL_SRC_SLIMCLK 3
++#define ARIZONA_FLL_SRC_FLL1 4
++#define ARIZONA_FLL_SRC_FLL2 5
++#define ARIZONA_FLL_SRC_AIF1BCLK 8
++#define ARIZONA_FLL_SRC_AIF2BCLK 9
++#define ARIZONA_FLL_SRC_AIF3BCLK 10
++#define ARIZONA_FLL_SRC_AIF1LRCLK 12
++#define ARIZONA_FLL_SRC_AIF2LRCLK 13
++#define ARIZONA_FLL_SRC_AIF3LRCLK 14
+
+ #define ARIZONA_MIXER_VOL_MASK 0x00FE
+ #define ARIZONA_MIXER_VOL_SHIFT 1
+From 7110a287ff2b1f3780905d1686a1a4edccb95133 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Thu, 20 Dec 2012 23:29:42 +0800
+Subject: ASoC: arizona: Do proper shift for setting AIF rate
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit 7110a287ff2b1f3780905d1686a1a4edccb95133 upstream.
+
+ARIZONA_AIF1_RATE_MASK is 0x7800 /* AIF1_RATE - [14:11] */
+Thus we need left shift ARIZONA_AIF1_RATE_SHIFT when setting aif1 rate.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/arizona.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/arizona.c
++++ b/sound/soc/codecs/arizona.c
+@@ -677,7 +677,8 @@ static int arizona_hw_params(struct snd_
+ snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
+ ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
+ snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
+- ARIZONA_AIF1_RATE_MASK, 8);
++ ARIZONA_AIF1_RATE_MASK,
++ 8 << ARIZONA_AIF1_RATE_SHIFT);
+ break;
+ default:
+ arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
+From d71753e22b24548911b377db28f80870cf50d07b Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Fri, 4 Jan 2013 10:48:02 +0000
+Subject: ASoC: arizona: Remove DSP B and left justified AIF modes
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit d71753e22b24548911b377db28f80870cf50d07b upstream.
+
+These are not supported.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/arizona.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/sound/soc/codecs/arizona.c
++++ b/sound/soc/codecs/arizona.c
+@@ -409,15 +409,9 @@ static int arizona_set_fmt(struct snd_so
+ case SND_SOC_DAIFMT_DSP_A:
+ mode = 0;
+ break;
+- case SND_SOC_DAIFMT_DSP_B:
+- mode = 1;
+- break;
+ case SND_SOC_DAIFMT_I2S:
+ mode = 2;
+ break;
+- case SND_SOC_DAIFMT_LEFT_J:
+- mode = 3;
+- break;
+ default:
+ arizona_aif_err(dai, "Unsupported DAI format %d\n",
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+From 267f8fa2e1eef0612b2007e1f1846bcbc35cc1fa Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Fri, 4 Jan 2013 21:18:12 +0000
+Subject: ASoC: wm2000: Fix sense of speech clarity enable
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit 267f8fa2e1eef0612b2007e1f1846bcbc35cc1fa upstream.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm2000.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/sound/soc/codecs/wm2000.c
++++ b/sound/soc/codecs/wm2000.c
+@@ -209,9 +209,9 @@ static int wm2000_power_up(struct i2c_cl
+
+ ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
+ if (wm2000->speech_clarity)
+- ret &= ~WM2000_SPEECH_CLARITY;
+- else
+ ret |= WM2000_SPEECH_CLARITY;
++ else
++ ret &= ~WM2000_SPEECH_CLARITY;
+ wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
+
+ wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
+From 2a5f431592343b78896013b055582f94c12a5049 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Fri, 21 Dec 2012 16:28:37 +0800
+Subject: ASoC: wm2200: Fix setting dai format in wm2200_set_fmt
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit 2a5f431592343b78896013b055582f94c12a5049 upstream.
+
+According to the defines in wm2200.h:
+/*
+ * R1284 (0x504) - Audio IF 1_5
+ */
+
+We should not left shift 1 bit for fmt_val when setting dai format.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm2200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/wm2200.c
++++ b/sound/soc/codecs/wm2200.c
+@@ -1440,7 +1440,7 @@ static int wm2200_set_fmt(struct snd_soc
+ WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
+ lrclk);
+ snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
+- WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
++ WM2200_AIF1_FMT_MASK, fmt_val);
+
+ return 0;
+ }
+From 0cc411b934c4317b363d1af993549f391852b980 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Fri, 4 Jan 2013 10:48:10 +0000
+Subject: ASoC: wm2200: Remove DSP B and left justified AIF modes
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit 0cc411b934c4317b363d1af993549f391852b980 upstream.
+
+These are not supported.
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm2200.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/sound/soc/codecs/wm2200.c
++++ b/sound/soc/codecs/wm2200.c
+@@ -1380,15 +1380,9 @@ static int wm2200_set_fmt(struct snd_soc
+ case SND_SOC_DAIFMT_DSP_A:
+ fmt_val = 0;
+ break;
+- case SND_SOC_DAIFMT_DSP_B:
+- fmt_val = 1;
+- break;
+ case SND_SOC_DAIFMT_I2S:
+ fmt_val = 2;
+ break;
+- case SND_SOC_DAIFMT_LEFT_J:
+- fmt_val = 3;
+- break;
+ default:
+ dev_err(codec->dev, "Unsupported DAI format %d\n",
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+From ad1937cdd59c412097ec2bb8f38c12a5640f1f9a Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Thu, 20 Dec 2012 16:17:25 +0800
+Subject: ASoC: sta529: Fix update register bits in sta529_set_dai_fmt
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit ad1937cdd59c412097ec2bb8f38c12a5640f1f9a upstream.
+
+Both the mask and mode settings are wrong in current code.
+
+According to the datasheet:
+
+S2PCFG0 (0x0A)
+BIT[3:1] DATA_FORMAT
+ serial interface protocol format:
+ 000: left Justified
+ 001: I2S (default)
+ 010: right justified
+ 100: PCM no delay
+ 101: PCM delay
+ 111: DSP
+
+Thus fixes the defines for LEFT_J_DATA_FORMAT, I2S_DATA_FORMAT, and
+RIGHT_J_DATA_FORMAT.
+Also adds define for DATA_FORMAT_MSK.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Acked-by: Rajeev Kumar <rajeev-dlh.kumar at st.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/sta529.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/sound/soc/codecs/sta529.c
++++ b/sound/soc/codecs/sta529.c
+@@ -74,9 +74,10 @@
+ SNDRV_PCM_FMTBIT_S32_LE)
+ #define S2PC_VALUE 0x98
+ #define CLOCK_OUT 0x60
+-#define LEFT_J_DATA_FORMAT 0x10
+-#define I2S_DATA_FORMAT 0x12
+-#define RIGHT_J_DATA_FORMAT 0x14
++#define DATA_FORMAT_MSK 0x0E
++#define LEFT_J_DATA_FORMAT 0x00
++#define I2S_DATA_FORMAT 0x02
++#define RIGHT_J_DATA_FORMAT 0x04
+ #define CODEC_MUTE_VAL 0x80
+
+ #define POWER_CNTLMSAK 0x40
+@@ -289,7 +290,7 @@ static int sta529_set_dai_fmt(struct snd
+ return -EINVAL;
+ }
+
+- snd_soc_update_bits(codec, STA529_S2PCFG0, 0x0D, mode);
++ snd_soc_update_bits(codec, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
+
+ return 0;
+ }
+From 08b27848da620f206a8b6d80f26184485dd7aa40 Mon Sep 17 00:00:00 2001
+From: Patrick Lai <plai at codeaurora.org>
+Date: Wed, 19 Dec 2012 19:36:02 -0800
+Subject: ASoC: pcm: allow backend hardware to be freed in pause state
+
+From: Patrick Lai <plai at codeaurora.org>
+
+commit 08b27848da620f206a8b6d80f26184485dd7aa40 upstream.
+
+When front-end PCM session is in paused state, back-end
+PCM session will be put in paused state as well if given
+front-end PCM session is the only client of given back-end.
+Then, application closes front-end PCM session, DPCM
+framework will not allow back-end enters HW_FREE state
+so back-end will never get shutdown completely.
+
+Signed-off-by: Patrick Lai <plai at codeaurora.org>
+Acked-by: Liam Girdwood <lrg at ti.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/soc-pcm.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1240,6 +1240,7 @@ static int dpcm_be_dai_hw_free(struct sn
+ if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
++ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) &&
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
+ continue;
+
+From 5f960294e2031d12f10c8488c3446fecbf59628d Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Date: Fri, 4 Jan 2013 21:06:08 +0000
+Subject: ASoC: wm5100: Remove DSP B and left justified formats
+
+From: Mark Brown <broonie at opensource.wolfsonmicro.com>
+
+commit 5f960294e2031d12f10c8488c3446fecbf59628d upstream.
+
+These are not supported
+
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/soc/codecs/wm5100.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/sound/soc/codecs/wm5100.c
++++ b/sound/soc/codecs/wm5100.c
+@@ -1279,15 +1279,9 @@ static int wm5100_set_fmt(struct snd_soc
+ case SND_SOC_DAIFMT_DSP_A:
+ mask = 0;
+ break;
+- case SND_SOC_DAIFMT_DSP_B:
+- mask = 1;
+- break;
+ case SND_SOC_DAIFMT_I2S:
+ mask = 2;
+ break;
+- case SND_SOC_DAIFMT_LEFT_J:
+- mask = 3;
+- break;
+ default:
+ dev_err(codec->dev, "Unsupported DAI format %d\n",
+ fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+From c930812fe5ebe725760422c9c351d1f6fde1502d Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Fri, 11 Jan 2013 12:08:56 +0100
+Subject: udldrmfb: Fix EDID not working with monitors with EDID
+ extension blocks
+
+From: Hans de Goede <hdegoede at redhat.com>
+
+commit c930812fe5ebe725760422c9c351d1f6fde1502d upstream.
+
+udldrmfb only reads the main EDID block, and if that advertises extensions
+the drm_edid code expects them to be present, and starts reading beyond the
+buffer udldrmfb passes it.
+
+Although it may be possible to read more EDID info with the udl we simpy don't
+know how, and even if trial and error gets it working on one device, that is
+no guarantee it will work on other revisions. So this patch does a simple fix
+in the form of patching the EDID info to report 0 extension blocks, this
+fixes udldrmfb only doing 1024x768 on monitors with EDID extension blocks.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_connector.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/gpu/drm/udl/udl_connector.c
++++ b/drivers/gpu/drm/udl/udl_connector.c
+@@ -57,6 +57,14 @@ static int udl_get_modes(struct drm_conn
+
+ edid = (struct edid *)udl_get_edid(udl);
+
++ /*
++ * We only read the main block, but if the monitor reports extension
++ * blocks then the drm edid code expects them to be present, so patch
++ * the extension count to 0.
++ */
++ edid->checksum += edid->extensions;
++ edid->extensions = 0;
++
+ drm_mode_connector_update_edid_property(connector, edid);
+ ret = drm_add_edid_modes(connector, edid);
+ kfree(edid);
+From 242187b362555849e8c971dfbbfd55f8bd9fa717 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Fri, 11 Jan 2013 12:08:57 +0100
+Subject: udldrmfb: udl_get_edid: usb_control_msg buffer must not be on the stack
+
+From: Hans de Goede <hdegoede at redhat.com>
+
+commit 242187b362555849e8c971dfbbfd55f8bd9fa717 upstream.
+
+The buffer passed to usb_control_msg may end up in scatter-gather list, and
+may thus not be on the stack. Having it on the stack usually works on x86, but
+not on other archs.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_connector.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/udl/udl_connector.c
++++ b/drivers/gpu/drm/udl/udl_connector.c
+@@ -22,13 +22,17 @@
+ static u8 *udl_get_edid(struct udl_device *udl)
+ {
+ u8 *block;
+- char rbuf[3];
++ char *rbuf;
+ int ret, i;
+
+ block = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ if (block == NULL)
+ return NULL;
+
++ rbuf = kmalloc(2, GFP_KERNEL);
++ if (rbuf == NULL)
++ goto error;
++
+ for (i = 0; i < EDID_LENGTH; i++) {
+ ret = usb_control_msg(udl->ddev->usbdev,
+ usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02),
+@@ -42,10 +46,12 @@ static u8 *udl_get_edid(struct udl_devic
+ block[i] = rbuf[1];
+ }
+
++ kfree(rbuf);
+ return block;
+
+ error:
+ kfree(block);
++ kfree(rbuf);
+ return NULL;
+ }
+
+From 7b4cf994e4c6ba48872bb25253cc393b7fb74c82 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Fri, 11 Jan 2013 12:08:58 +0100
+Subject: udldrmfb: udl_get_edid: drop unneeded i--
+
+From: Hans de Goede <hdegoede at redhat.com>
+
+commit 7b4cf994e4c6ba48872bb25253cc393b7fb74c82 upstream.
+
+This is a left-over from when udl_get_edid returned the amount of bytes
+successfully read, which it no longer does.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Dave Airlie <airlied at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_connector.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/udl/udl_connector.c
++++ b/drivers/gpu/drm/udl/udl_connector.c
+@@ -40,7 +40,6 @@ static u8 *udl_get_edid(struct udl_devic
+ HZ);
+ if (ret < 1) {
+ DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret);
+- i--;
+ goto error;
+ }
+ block[i] = rbuf[1];
+From 6d283dba3721cc43be014b50a1acc2f35860a65a Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds at linux-foundation.org>
+Date: Mon, 14 Jan 2013 13:17:50 -0800
+Subject: vfs: add missing virtual cache flush after editing partial pages
+
+From: Linus Torvalds <torvalds at linux-foundation.org>
+
+commit 6d283dba3721cc43be014b50a1acc2f35860a65a upstream.
+
+Andrew Morton pointed this out a month ago, and then I completely forgot
+about it.
+
+If we read a partial last page of a block device, we will zero out the
+end of the page, but since that page can then be mapped into user space,
+we should also make sure to flush the cache on architectures that have
+virtual caches. We have the flush_dcache_page() function for this, so
+use it.
+
+Now, in practice this really never matters, because nobody sane uses
+virtual caches to begin with, and they largely exist on old broken RISC
+arhitectures.
+
+And even if you did run on one of those obsolete CPU's, the whole "mmap
+and access the last partial page of a block device" behavior probably
+doesn't actually exist. The normal IO functions (read/write) will never
+see the zeroed-out part of the page that migth not be coherent in the
+cache, because they honor the size of the device.
+
+So I'm marking this for stable (3.7 only), but I'm not sure anybody will
+ever care.
+
+Pointed-out-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ fs/buffer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -2939,6 +2939,7 @@ static void guard_bh_eod(int rw, struct
+ void *kaddr = kmap_atomic(bh->b_page);
+ memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes);
+ kunmap_atomic(kaddr);
++ flush_dcache_page(bh->b_page);
+ }
+ }
+
+From 7ed4165e2d01bdbbb4c1086eb73eadf0f64cbbf0 Mon Sep 17 00:00:00 2001
+From: David Henningsson <david.henningsson at canonical.com>
+Date: Wed, 19 Dec 2012 09:44:47 +0100
+Subject: Revert "ALSA: hda - Shut up pins at power-saving mode with Conexnat codecs"
+
+From: David Henningsson <david.henningsson at canonical.com>
+
+commit 7ed4165e2d01bdbbb4c1086eb73eadf0f64cbbf0 upstream.
+
+This reverts commit 697c373e34613609cb5450f98b91fefb6e910588.
+
+The original patch was meant to remove clicking, but in fact caused even
+more clicking instead.
+
+Thanks to c4pp4 for doing most of the work with this bug.
+
+BugLink: https://bugs.launchpad.net/bugs/886975
+Signed-off-by: David Henningsson <david.henningsson at canonical.com>
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_conexant.c | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -553,24 +553,12 @@ static int conexant_build_controls(struc
+ return 0;
+ }
+
+-#ifdef CONFIG_PM
+-static int conexant_suspend(struct hda_codec *codec)
+-{
+- snd_hda_shutup_pins(codec);
+- return 0;
+-}
+-#endif
+-
+ static const struct hda_codec_ops conexant_patch_ops = {
+ .build_controls = conexant_build_controls,
+ .build_pcms = conexant_build_pcms,
+ .init = conexant_init,
+ .free = conexant_free,
+ .set_power_state = conexant_set_power,
+-#ifdef CONFIG_PM
+- .suspend = conexant_suspend,
+-#endif
+- .reboot_notify = snd_hda_shutup_pins,
+ };
+
+ #ifdef CONFIG_SND_HDA_INPUT_BEEP
+@@ -4393,10 +4381,6 @@ static const struct hda_codec_ops cx_aut
+ .init = cx_auto_init,
+ .free = conexant_free,
+ .unsol_event = snd_hda_jack_unsol_event,
+-#ifdef CONFIG_PM
+- .suspend = conexant_suspend,
+-#endif
+- .reboot_notify = snd_hda_shutup_pins,
+ };
+
+ /*
+From d7dab4dbbb2d1b0c903378d6bade2e4ae161804e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai at suse.de>
+Date: Tue, 8 Jan 2013 13:51:30 +0100
+Subject: ALSA: hda - Disable runtime D3 for Intel CPT & co
+
+From: Takashi Iwai <tiwai at suse.de>
+
+commit d7dab4dbbb2d1b0c903378d6bade2e4ae161804e upstream.
+
+We've got a few bug reports that the runtime D3 results in the dead
+HD-audio controller. It seems that the problem is in a deeper level
+than the sound driver itself, so as a temporal solution, disable the
+feature for these controllers again.
+
+Reported-and-tested-by: Vincent Blut <vincent.debian at free.fr>
+Reported-and-tested-by: Maurizio Avogadro <mavoga at gmail.com>
+Signed-off-by: Takashi Iwai <tiwai at suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -559,9 +559,12 @@ enum {
+ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
+
+ /* quirks for Intel PCH */
+-#define AZX_DCAPS_INTEL_PCH \
++#define AZX_DCAPS_INTEL_PCH_NOPM \
+ (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \
+- AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME)
++ AZX_DCAPS_COUNT_LPIB_DELAY)
++
++#define AZX_DCAPS_INTEL_PCH \
++ (AZX_DCAPS_INTEL_PCH_NOPM | AZX_DCAPS_PM_RUNTIME)
+
+ /* quirks for ATI SB / AMD Hudson */
+ #define AZX_DCAPS_PRESET_ATI_SB \
+@@ -3448,13 +3451,13 @@ static void __devexit azx_remove(struct
+ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
+ /* CPT */
+ { PCI_DEVICE(0x8086, 0x1c20),
+- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
+ /* PBG */
+ { PCI_DEVICE(0x8086, 0x1d20),
+- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
+ /* Panther Point */
+ { PCI_DEVICE(0x8086, 0x1e20),
+- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM },
+ /* Lynx Point */
+ { PCI_DEVICE(0x8086, 0x8c20),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+From 41b645c8624df6ace020a8863ad1449d69140f7d Mon Sep 17 00:00:00 2001
+From: Mike Dunn <mikedunn at newsguy.com>
+Date: Mon, 7 Jan 2013 13:55:12 -0800
+Subject: ALSA: pxa27x: fix ac97 cold reset
+
+From: Mike Dunn <mikedunn at newsguy.com>
+
+commit 41b645c8624df6ace020a8863ad1449d69140f7d upstream.
+
+Cold reset on the pxa27x currently fails and
+
+ pxa2xx_ac97_try_cold_reset: cold reset timeout (GSR=0x44)
+
+appears in the kernel log. Through trial-and-error (the pxa270 developer's
+manual is mostly incoherent on the topic of ac97 reset), I got cold reset to
+complete by setting the WARM_RST bit in the GCR register (and later noticed that
+pxa3xx does this for cold reset as well). Also, a timeout loop is needed to
+wait for the reset to complete.
+
+Tested on a palm treo 680 machine.
+
+Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
+Acked-by: Igor Grinberg <grinberg at compulab.co.il>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ sound/arm/pxa2xx-ac97-lib.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/sound/arm/pxa2xx-ac97-lib.c
++++ b/sound/arm/pxa2xx-ac97-lib.c
+@@ -148,6 +148,8 @@ static inline void pxa_ac97_warm_pxa27x(
+
+ static inline void pxa_ac97_cold_pxa27x(void)
+ {
++ unsigned int timeout;
++
+ GCR &= GCR_COLD_RST; /* clear everything but nCRST */
+ GCR &= ~GCR_COLD_RST; /* then assert nCRST */
+
+@@ -157,8 +159,10 @@ static inline void pxa_ac97_cold_pxa27x(
+ clk_enable(ac97conf_clk);
+ udelay(5);
+ clk_disable(ac97conf_clk);
+- GCR = GCR_COLD_RST;
+- udelay(50);
++ GCR = GCR_COLD_RST | GCR_WARM_RST;
++ timeout = 100; /* wait for the codec-ready bit to be set */
++ while (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)) && timeout--)
++ mdelay(1);
+ }
+ #endif
+
+From 3b4bc7bccc7857274705b05cf81a0c72cfd0b0dd Mon Sep 17 00:00:00 2001
+From: Mike Dunn <mikedunn at newsguy.com>
+Date: Mon, 7 Jan 2013 13:55:13 -0800
+Subject: ALSA: pxa27x: fix ac97 warm reset
+
+From: Mike Dunn <mikedunn at newsguy.com>
+
+commit 3b4bc7bccc7857274705b05cf81a0c72cfd0b0dd upstream.
+
+This patch fixes some code that implements a work-around to a hardware bug in
+the ac97 controller on the pxa27x. A bug in the controller's warm reset
+functionality requires that the mfp used by the controller as the AC97_nRESET
+line be temporarily reconfigured as a generic output gpio (AF0) and manually
+held high for the duration of the warm reset cycle. This is what was done in
+the original code, but it was broken long ago by commit fb1bf8cd
+ ([ARM] pxa: introduce processor specific pxa27x_assert_ac97reset())
+which changed the mfp to a GPIO input instead of a high output.
+
+The fix requires the ac97 controller to obtain the gpio via gpio_request_one(),
+with arguments that configure the gpio as an output initially driven high.
+
+Tested on a palm treo 680 machine. Reportedly, this broken code only prevents a
+warm reset on hardware that lacks a pull-up on the line, which appears to be the
+case for me.
+
+Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
+Signed-off-by: Igor Grinberg <grinberg at compulab.co.il>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/arm/mach-pxa/include/mach/mfp-pxa27x.h | 3 +++
+ arch/arm/mach-pxa/pxa27x.c | 4 ++--
+ sound/arm/pxa2xx-ac97-lib.c | 18 +++++++++++++++++-
+ 3 files changed, 22 insertions(+), 3 deletions(-)
+
+--- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
++++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
+@@ -463,6 +463,9 @@
+ GPIO76_LCD_PCLK, \
+ GPIO77_LCD_BIAS
+
++/* these enable a work-around for a hw bug in pxa27x during ac97 warm reset */
++#define GPIO113_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO113, AF0, DEFAULT)
++#define GPIO95_AC97_nRESET_GPIO_HIGH MFP_CFG_OUT(GPIO95, AF0, DEFAULT)
+
+ extern int keypad_set_wake(unsigned int on);
+ #endif /* __ASM_ARCH_MFP_PXA27X_H */
+--- a/arch/arm/mach-pxa/pxa27x.c
++++ b/arch/arm/mach-pxa/pxa27x.c
+@@ -47,9 +47,9 @@ void pxa27x_clear_otgph(void)
+ EXPORT_SYMBOL(pxa27x_clear_otgph);
+
+ static unsigned long ac97_reset_config[] = {
+- GPIO113_GPIO,
++ GPIO113_AC97_nRESET_GPIO_HIGH,
+ GPIO113_AC97_nRESET,
+- GPIO95_GPIO,
++ GPIO95_AC97_nRESET_GPIO_HIGH,
+ GPIO95_AC97_nRESET,
+ };
+
+--- a/sound/arm/pxa2xx-ac97-lib.c
++++ b/sound/arm/pxa2xx-ac97-lib.c
+@@ -18,6 +18,7 @@
+ #include <linux/delay.h>
+ #include <linux/module.h>
+ #include <linux/io.h>
++#include <linux/gpio.h>
+
+ #include <sound/ac97_codec.h>
+ #include <sound/pxa2xx-lib.h>
+@@ -344,8 +345,21 @@ int __devinit pxa2xx_ac97_hw_probe(struc
+ }
+
+ if (cpu_is_pxa27x()) {
+- /* Use GPIO 113 as AC97 Reset on Bulverde */
++ /*
++ * This gpio is needed for a work-around to a bug in the ac97
++ * controller during warm reset. The direction and level is set
++ * here so that it is an output driven high when switching from
++ * AC97_nRESET alt function to generic gpio.
++ */
++ ret = gpio_request_one(reset_gpio, GPIOF_OUT_INIT_HIGH,
++ "pxa27x ac97 reset");
++ if (ret < 0) {
++ pr_err("%s: gpio_request_one() failed: %d\n",
++ __func__, ret);
++ goto err_conf;
++ }
+ pxa27x_assert_ac97reset(reset_gpio, 0);
++
+ ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK");
+ if (IS_ERR(ac97conf_clk)) {
+ ret = PTR_ERR(ac97conf_clk);
+@@ -388,6 +402,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
+
+ void pxa2xx_ac97_hw_remove(struct platform_device *dev)
+ {
++ if (cpu_is_pxa27x())
++ gpio_free(reset_gpio);
+ GCR |= GCR_ACLINK_OFF;
+ free_irq(IRQ_AC97, NULL);
+ if (ac97conf_clk) {
+From 7d3135af399e92cf4c9bbc5f86b6c140aab3b88c Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti at mev.co.uk>
+Date: Tue, 4 Dec 2012 15:59:55 +0000
+Subject: staging: comedi: prevent auto-unconfig of manually configured devices
+
+From: Ian Abbott <abbotti at mev.co.uk>
+
+commit 7d3135af399e92cf4c9bbc5f86b6c140aab3b88c upstream.
+
+When a low-level comedi driver auto-configures a device, a `struct
+comedi_dev_file_info` is allocated (as well as a `struct
+comedi_device`) by `comedi_alloc_board_minor()`. A pointer to the
+hardware `struct device` is stored as a cookie in the `struct
+comedi_dev_file_info`. When the low-level comedi driver
+auto-unconfigures the device, `comedi_auto_unconfig()` uses the cookie
+to find the `struct comedi_dev_file_info` so it can detach the comedi
+device from the driver, clean it up and free it.
+
+A problem arises if the user manually unconfigures and reconfigures the
+comedi device using the `COMEDI_DEVCONFIG` ioctl so that is no longer
+associated with the original hardware device. The problem is that the
+cookie is not cleared, so that a call to `comedi_auto_unconfig()` from
+the low-level driver will still find it, detach it, clean it up and free
+it.
+
+Stop this problem occurring by always clearing the `hardware_device`
+cookie in the `struct comedi_dev_file_info` whenever the
+`COMEDI_DEVCONFIG` ioctl call is successful.
+
+Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/comedi/comedi_fops.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -1546,6 +1546,9 @@ static long comedi_unlocked_ioctl(struct
+ if (cmd == COMEDI_DEVCONFIG) {
+ rc = do_devconfig_ioctl(dev,
+ (struct comedi_devconfig __user *)arg);
++ if (rc == 0)
++ /* Evade comedi_auto_unconfig(). */
++ dev_file_info->hardware_device = NULL;
+ goto done;
+ }
+
+From 34b55d8c48f4f76044d8f4d6ec3dc786cf210312 Mon Sep 17 00:00:00 2001
+From: Éric Piel <piel at delmic.com>
+Date: Wed, 19 Dec 2012 13:03:13 +0100
+Subject: staging: comedi: fix minimum AO period for NI 625x and NI 628x
+
+From: Éric Piel <piel at delmic.com>
+
+commit 34b55d8c48f4f76044d8f4d6ec3dc786cf210312 upstream.
+
+The minimum period was set to 357 ns, while the divider for these boards is 50
+ns. This prevented to output at maximum speed as ni_ao_cmdtest() would return
+357 but would not accept it.
+
+Not sure why it was set to 357 ns (this was done before the git history,
+which starts 5 years ago). My guess is that it comes from reading the
+specification stating a 2.8 MHz rate (~ 357 ns). The latest
+specification states a 2.86 MHz rate (~ 350 ns), which makes a lot
+more sense.
+
+Tested on a pci-6251.
+
+Signed-off-by: Éric Piel <piel at delmic.com>
+Acked-By: Ian Abbott <abbotti at mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/ni_pcimio.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/staging/comedi/drivers/ni_pcimio.c
++++ b/drivers/staging/comedi/drivers/ni_pcimio.c
+@@ -963,7 +963,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -982,7 +982,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1001,7 +1001,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1037,7 +1037,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1056,7 +1056,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1092,7 +1092,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1111,7 +1111,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+@@ -1147,7 +1147,7 @@ static const struct ni_board_struct ni_b
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+- .ao_speed = 357,
++ .ao_speed = 350,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+From 34ffb33e09132401872fe79e95c30824ce194d23 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti at mev.co.uk>
+Date: Thu, 3 Jan 2013 12:15:26 +0000
+Subject: staging: comedi: Kconfig: COMEDI_NI_AT_A2150 should select COMEDI_FC
+
+From: Ian Abbott <abbotti at mev.co.uk>
+
+commit 34ffb33e09132401872fe79e95c30824ce194d23 upstream.
+
+The 'ni_at_a2150' module links to `cfc_write_to_buffer` in the
+'comedi_fc' module, so selecting 'COMEDI_NI_AT_A2150' in the kernel config
+needs to also select 'COMEDI_FC'.
+
+Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/comedi/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/comedi/Kconfig
++++ b/drivers/staging/comedi/Kconfig
+@@ -444,6 +444,7 @@ config COMEDI_ADQ12B
+
+ config COMEDI_NI_AT_A2150
+ tristate "NI AT-A2150 ISA card support"
++ select COMEDI_FC
+ depends on VIRT_TO_BUS
+ ---help---
+ Enable support for National Instruments AT-A2150 cards
+From c0729eeefdcd76db338f635162bf0739fd2c5f6f Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti at mev.co.uk>
+Date: Fri, 4 Jan 2013 11:33:21 +0000
+Subject: staging: comedi: comedi_test: fix race when cancelling command
+
+From: Ian Abbott <abbotti at mev.co.uk>
+
+commit c0729eeefdcd76db338f635162bf0739fd2c5f6f upstream.
+
+Éric Piel reported a kernel oops in the "comedi_test" module. It was a
+NULL pointer dereference within `waveform_ai_interrupt()` (actually a
+timer function) that sometimes occurred when a running asynchronous
+command is cancelled (either by the `COMEDI_CANCEL` ioctl or by closing
+the device file).
+
+This seems to be a race between the caller of `waveform_ai_cancel()`
+which on return from that function goes and tears down the running
+command, and the timer function which uses the command. In particular,
+`async->cmd.chanlist` gets freed (and the pointer set to NULL) by
+`do_become_nonbusy()` in "comedi_fops.c" but a previously scheduled
+`waveform_ai_interrupt()` timer function will dereference that pointer
+regardless, leading to the oops.
+
+Fix it by replacing the `del_timer()` call in `waveform_ai_cancel()`
+with `del_timer_sync()`.
+
+Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
+Reported-by: Éric Piel <piel at delmic.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/comedi_test.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/comedi/drivers/comedi_test.c
++++ b/drivers/staging/comedi/drivers/comedi_test.c
+@@ -372,7 +372,7 @@ static int waveform_ai_cancel(struct com
+ struct waveform_private *devpriv = dev->private;
+
+ devpriv->timer_running = 0;
+- del_timer(&devpriv->timer);
++ del_timer_sync(&devpriv->timer);
+ return 0;
+ }
+
+From da849a92d3bafaf24d770e971c2c9e5c3f60b5d1 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger at lwfinger.net>
+Date: Sat, 29 Dec 2012 11:36:53 -0600
+Subject: staging: r8712u: Add new device ID
+
+From: Larry Finger <Larry.Finger at lwfinger.net>
+
+commit da849a92d3bafaf24d770e971c2c9e5c3f60b5d1 upstream.
+
+The ISY IWL 1000 USB WLAN stick with USB ID 050d:11f1 is a clone of
+the Belkin F7D1101 V1 device.
+
+Reported-by: Thomas Hartmann <hartmann at ict.tuwien.ac.at>
+Signed-off-by: Larry Finger <Larry.Finger at lwfinger.net>
+Cc: Thomas Hartmann <hartmann at ict.tuwien.ac.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/rtl8712/usb_intf.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/staging/rtl8712/usb_intf.c
++++ b/drivers/staging/rtl8712/usb_intf.c
+@@ -63,6 +63,8 @@ static struct usb_device_id rtl871x_usb_
+ {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */
+ /* Belkin */
+ {USB_DEVICE(0x050D, 0x945A)},
++ /* ISY IWL - Belkin clone */
++ {USB_DEVICE(0x050D, 0x11F1)},
+ /* Corega */
+ {USB_DEVICE(0x07AA, 0x0047)},
+ /* D-Link */
+From ae428655b826f2755a8101b27beda42a275ef8ad Mon Sep 17 00:00:00 2001
+From: Nickolai Zeldovich <nickolai at csail.mit.edu>
+Date: Sat, 5 Jan 2013 14:17:45 -0500
+Subject: staging: speakup: avoid out-of-range access in synth_init()
+
+From: Nickolai Zeldovich <nickolai at csail.mit.edu>
+
+commit ae428655b826f2755a8101b27beda42a275ef8ad upstream.
+
+Check that array index is in-bounds before accessing the synths[] array.
+
+Signed-off-by: Nickolai Zeldovich <nickolai at csail.mit.edu>
+Cc: Samuel Thibault <samuel.thibault at ens-lyon.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/speakup/synth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/speakup/synth.c
++++ b/drivers/staging/speakup/synth.c
+@@ -342,7 +342,7 @@ int synth_init(char *synth_name)
+
+ mutex_lock(&spk_mutex);
+ /* First, check if we already have it loaded. */
+- for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++)
++ for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
+ if (strcmp(synths[i]->name, synth_name) == 0)
+ synth = synths[i];
+
+From 6102c48bd421074a33e102f2ebda3724e8d275f9 Mon Sep 17 00:00:00 2001
+From: Samuel Thibault <samuel.thibault at ens-lyon.org>
+Date: Mon, 7 Jan 2013 22:03:51 +0100
+Subject: staging: speakup: avoid out-of-range access in synth_add()
+
+From: Samuel Thibault <samuel.thibault at ens-lyon.org>
+
+commit 6102c48bd421074a33e102f2ebda3724e8d275f9 upstream.
+
+Check that array index is in-bounds before accessing the synths[] array.
+
+Signed-off-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
+Cc: Nickolai Zeldovich <nickolai at csail.mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/speakup/synth.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/speakup/synth.c
++++ b/drivers/staging/speakup/synth.c
+@@ -423,7 +423,7 @@ int synth_add(struct spk_synth *in_synth
+ int i;
+ int status = 0;
+ mutex_lock(&spk_mutex);
+- for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++)
++ for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++)
+ /* synth_remove() is responsible for rotating the array down */
+ if (in_synth == synths[i]) {
+ mutex_unlock(&spk_mutex);
+From 37b51fdddf64e7ba0971d070428655f8d6f36578 Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky at gmail.com>
+Date: Tue, 30 Oct 2012 22:40:23 +0300
+Subject: staging: zram: factor-out zram_decompress_page() function
+
+From: Sergey Senozhatsky <sergey.senozhatsky at gmail.com>
+
+commit 37b51fdddf64e7ba0971d070428655f8d6f36578 upstream.
+
+zram_bvec_read() shared decompress functionality with zram_read_before_write() function.
+Factor-out and make commonly used zram_decompress_page() function, which also simplified
+error handling in zram_bvec_read().
+
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky at gmail.com>
+Reviewed-by: Nitin Gupta <ngupta at vflare.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/zram/zram_drv.c | 113 ++++++++++++++++------------------------
+ 1 file changed, 48 insertions(+), 65 deletions(-)
+
+--- a/drivers/staging/zram/zram_drv.c
++++ b/drivers/staging/zram/zram_drv.c
+@@ -183,62 +183,25 @@ static inline int is_partial_io(struct b
+ return bvec->bv_len != PAGE_SIZE;
+ }
+
+-static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
+- u32 index, int offset, struct bio *bio)
++static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
+ {
+- int ret;
+- size_t clen;
+- struct page *page;
+- unsigned char *user_mem, *cmem, *uncmem = NULL;
+-
+- page = bvec->bv_page;
+-
+- if (zram_test_flag(zram, index, ZRAM_ZERO)) {
+- handle_zero_page(bvec);
+- return 0;
+- }
++ int ret = LZO_E_OK;
++ size_t clen = PAGE_SIZE;
++ unsigned char *cmem;
++ unsigned long handle = zram->table[index].handle;
+
+- /* Requested page is not present in compressed area */
+- if (unlikely(!zram->table[index].handle)) {
+- pr_debug("Read before write: sector=%lu, size=%u",
+- (ulong)(bio->bi_sector), bio->bi_size);
+- handle_zero_page(bvec);
++ if (!handle || zram_test_flag(zram, index, ZRAM_ZERO)) {
++ memset(mem, 0, PAGE_SIZE);
+ return 0;
+ }
+
+- if (is_partial_io(bvec)) {
+- /* Use a temporary buffer to decompress the page */
+- uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
+- if (!uncmem) {
+- pr_info("Error allocating temp memory!\n");
+- return -ENOMEM;
+- }
+- }
+-
+- user_mem = kmap_atomic(page);
+- if (!is_partial_io(bvec))
+- uncmem = user_mem;
+- clen = PAGE_SIZE;
+-
+- cmem = zs_map_object(zram->mem_pool, zram->table[index].handle,
+- ZS_MM_RO);
+-
+- if (zram->table[index].size == PAGE_SIZE) {
+- memcpy(uncmem, cmem, PAGE_SIZE);
+- ret = LZO_E_OK;
+- } else {
++ cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
++ if (zram->table[index].size == PAGE_SIZE)
++ memcpy(mem, cmem, PAGE_SIZE);
++ else
+ ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
+- uncmem, &clen);
+- }
+-
+- if (is_partial_io(bvec)) {
+- memcpy(user_mem + bvec->bv_offset, uncmem + offset,
+- bvec->bv_len);
+- kfree(uncmem);
+- }
+-
+- zs_unmap_object(zram->mem_pool, zram->table[index].handle);
+- kunmap_atomic(user_mem);
++ mem, &clen);
++ zs_unmap_object(zram->mem_pool, handle);
+
+ /* Should NEVER happen. Return bio error if it does. */
+ if (unlikely(ret != LZO_E_OK)) {
+@@ -247,36 +210,56 @@ static int zram_bvec_read(struct zram *z
+ return ret;
+ }
+
+- flush_dcache_page(page);
+-
+ return 0;
+ }
+
+-static int zram_read_before_write(struct zram *zram, char *mem, u32 index)
++static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
++ u32 index, int offset, struct bio *bio)
+ {
+ int ret;
+- size_t clen = PAGE_SIZE;
+- unsigned char *cmem;
+- unsigned long handle = zram->table[index].handle;
++ struct page *page;
++ unsigned char *user_mem, *uncmem = NULL;
+
+- if (zram_test_flag(zram, index, ZRAM_ZERO) || !handle) {
+- memset(mem, 0, PAGE_SIZE);
++ page = bvec->bv_page;
++
++ if (unlikely(!zram->table[index].handle) ||
++ zram_test_flag(zram, index, ZRAM_ZERO)) {
++ handle_zero_page(bvec);
+ return 0;
+ }
+
+- cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
+- ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
+- mem, &clen);
+- zs_unmap_object(zram->mem_pool, handle);
++ user_mem = kmap_atomic(page);
++ if (is_partial_io(bvec))
++ /* Use a temporary buffer to decompress the page */
++ uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
++ else
++ uncmem = user_mem;
++
++ if (!uncmem) {
++ pr_info("Unable to allocate temp memory\n");
++ ret = -ENOMEM;
++ goto out_cleanup;
++ }
+
++ ret = zram_decompress_page(zram, uncmem, index);
+ /* Should NEVER happen. Return bio error if it does. */
+ if (unlikely(ret != LZO_E_OK)) {
+ pr_err("Decompression failed! err=%d, page=%u\n", ret, index);
+ zram_stat64_inc(zram, &zram->stats.failed_reads);
+- return ret;
++ goto out_cleanup;
+ }
+
+- return 0;
++ if (is_partial_io(bvec))
++ memcpy(user_mem + bvec->bv_offset, uncmem + offset,
++ bvec->bv_len);
++
++ flush_dcache_page(page);
++ ret = 0;
++out_cleanup:
++ kunmap_atomic(user_mem);
++ if (is_partial_io(bvec))
++ kfree(uncmem);
++ return ret;
+ }
+
+ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
+@@ -302,7 +285,7 @@ static int zram_bvec_write(struct zram *
+ ret = -ENOMEM;
+ goto out;
+ }
+- ret = zram_read_before_write(zram, uncmem, index);
++ ret = zram_decompress_page(zram, uncmem, index);
+ if (ret) {
+ kfree(uncmem);
+ goto out;
+From 397c60668aa5ae7130b5ad4e73870d7b8a787085 Mon Sep 17 00:00:00 2001
+From: Nitin Gupta <ngupta at vflare.org>
+Date: Wed, 2 Jan 2013 08:53:41 -0800
+Subject: staging: zram: fix invalid memory references during disk write
+
+From: Nitin Gupta <ngupta at vflare.org>
+
+commit 397c60668aa5ae7130b5ad4e73870d7b8a787085 upstream.
+
+Fixes a bug introduced by commit c8f2f0db1 ("zram: Fix handling
+of incompressible pages") which caused invalid memory references
+during disk write. Invalid references could occur in two cases:
+ - Incoming data expands on compression: In this case, reference was
+made to kunmap()'ed bio page.
+ - Partial (non PAGE_SIZE) write with incompressible data: In this
+case, reference was made to a kfree()'ed buffer.
+
+Fixes bug 50081:
+https://bugzilla.kernel.org/show_bug.cgi?id=50081
+
+Signed-off-by: Nitin Gupta <ngupta at vflare.org>
+Reported-by: Mihail Kasadjikov <hamer.mk at gmail.com>
+Reported-by: Tomas M <tomas at slax.org>
+Reviewed-by: Minchan Kim <minchan at kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/staging/zram/zram_drv.c | 39 ++++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+--- a/drivers/staging/zram/zram_drv.c
++++ b/drivers/staging/zram/zram_drv.c
+@@ -265,7 +265,7 @@ out_cleanup:
+ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
+ int offset)
+ {
+- int ret;
++ int ret = 0;
+ size_t clen;
+ unsigned long handle;
+ struct page *page;
+@@ -286,10 +286,8 @@ static int zram_bvec_write(struct zram *
+ goto out;
+ }
+ ret = zram_decompress_page(zram, uncmem, index);
+- if (ret) {
+- kfree(uncmem);
++ if (ret)
+ goto out;
+- }
+ }
+
+ /*
+@@ -302,16 +300,18 @@ static int zram_bvec_write(struct zram *
+
+ user_mem = kmap_atomic(page);
+
+- if (is_partial_io(bvec))
++ if (is_partial_io(bvec)) {
+ memcpy(uncmem + offset, user_mem + bvec->bv_offset,
+ bvec->bv_len);
+- else
++ kunmap_atomic(user_mem);
++ user_mem = NULL;
++ } else {
+ uncmem = user_mem;
++ }
+
+ if (page_zero_filled(uncmem)) {
+- kunmap_atomic(user_mem);
+- if (is_partial_io(bvec))
+- kfree(uncmem);
++ if (!is_partial_io(bvec))
++ kunmap_atomic(user_mem);
+ zram_stat_inc(&zram->stats.pages_zero);
+ zram_set_flag(zram, index, ZRAM_ZERO);
+ ret = 0;
+@@ -321,9 +321,11 @@ static int zram_bvec_write(struct zram *
+ ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen,
+ zram->compress_workmem);
+
+- kunmap_atomic(user_mem);
+- if (is_partial_io(bvec))
+- kfree(uncmem);
++ if (!is_partial_io(bvec)) {
++ kunmap_atomic(user_mem);
++ user_mem = NULL;
++ uncmem = NULL;
++ }
+
+ if (unlikely(ret != LZO_E_OK)) {
+ pr_err("Compression failed! err=%d\n", ret);
+@@ -332,8 +334,10 @@ static int zram_bvec_write(struct zram *
+
+ if (unlikely(clen > max_zpage_size)) {
+ zram_stat_inc(&zram->stats.bad_compress);
+- src = uncmem;
+ clen = PAGE_SIZE;
++ src = NULL;
++ if (is_partial_io(bvec))
++ src = uncmem;
+ }
+
+ handle = zs_malloc(zram->mem_pool, clen);
+@@ -345,7 +349,11 @@ static int zram_bvec_write(struct zram *
+ }
+ cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_WO);
+
++ if ((clen == PAGE_SIZE) && !is_partial_io(bvec))
++ src = kmap_atomic(page);
+ memcpy(cmem, src, clen);
++ if ((clen == PAGE_SIZE) && !is_partial_io(bvec))
++ kunmap_atomic(src);
+
+ zs_unmap_object(zram->mem_pool, handle);
+
+@@ -358,9 +366,10 @@ static int zram_bvec_write(struct zram *
+ if (clen <= PAGE_SIZE / 2)
+ zram_stat_inc(&zram->stats.good_compress);
+
+- return 0;
+-
+ out:
++ if (is_partial_io(bvec))
++ kfree(uncmem);
++
+ if (ret)
+ zram_stat64_inc(zram, &zram->stats.failed_writes);
+ return ret;
+From 51861d4eebc2ddc25c77084343d060fa79f6e291 Mon Sep 17 00:00:00 2001
+From: Jerome Glisse <jglisse at redhat.com>
+Date: Tue, 8 Jan 2013 18:41:01 -0500
+Subject: radeon/kms: force rn50 chip to always report connected on analog output
+
+From: Jerome Glisse <jglisse at redhat.com>
+
+commit 51861d4eebc2ddc25c77084343d060fa79f6e291 upstream.
+
+Those rn50 chip are often connected to console remoting hw and load
+detection often fails with those. Just don't try to load detect and
+report connect.
+
+Signed-off-by: Jerome Glisse <jglisse at redhat.com>
+Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
++++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+@@ -640,6 +640,14 @@ static enum drm_connector_status radeon_
+ enum drm_connector_status found = connector_status_disconnected;
+ bool color = true;
+
++ /* just don't bother on RN50 those chip are often connected to remoting
++ * console hw and often we get failure to load detect those. So to make
++ * everyone happy report the encoder as always connected.
++ */
++ if (ASIC_IS_RN50(rdev)) {
++ return connector_status_connected;
++ }
++
+ /* save the regs we need */
+ vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
+ crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
+From 392d4cad7907f6cb4ffc85e135a01abfddc89027 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Thu, 27 Dec 2012 21:37:04 +0100
+Subject: iwlwifi: fix PCIe interrupt handle return value
+
+From: Johannes Berg <johannes.berg at intel.com>
+
+commit 392d4cad7907f6cb4ffc85e135a01abfddc89027 upstream.
+
+By accident, commit eb6476441bc2fecf6232a87d0313a85f8e3da7f4
+("iwlwifi: protect use_ict with irq_lock") changed the return
+value of the iwl_pcie_isr() function in case it handles an
+interrupt -- it now returns IRQ_NONE instead of IRQ_HANDLED.
+
+Put back the correct return value.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/pcie/rx.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
++++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
+@@ -971,6 +971,7 @@ static irqreturn_t iwl_isr(int irq, void
+ else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
+ !trans_pcie->inta)
+ iwl_enable_interrupts(trans);
++ return IRQ_HANDLED;
+
+ none:
+ /* re-enable interrupts here since we don't have anything to service. */
+From f590dcec944552f9a4a61155810f3abd17d6465d Mon Sep 17 00:00:00 2001
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Mon, 31 Dec 2012 09:26:10 +0200
+Subject: iwlwifi: fix the reclaimed packet tracking upon flush queue
+
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+
+commit f590dcec944552f9a4a61155810f3abd17d6465d upstream.
+
+There's a bug in the currently released firmware version,
+the sequence control in the Tx response isn't updated in
+all cases. Take it from the packet as a workaround.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/iwlwifi/dvm/tx.c | 24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
++++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
+@@ -1154,13 +1154,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *
+ next_reclaimed = ssn;
+ }
+
+- if (tid != IWL_TID_NON_QOS) {
+- priv->tid_data[sta_id][tid].next_reclaimed =
+- next_reclaimed;
+- IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
+- next_reclaimed);
+- }
+-
+ iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
+
+ iwlagn_check_ratid_empty(priv, sta_id, tid);
+@@ -1211,11 +1204,28 @@ int iwlagn_rx_reply_tx(struct iwl_priv *
+ if (!is_agg)
+ iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
+
++ /*
++ * W/A for FW bug - the seq_ctl isn't updated when the
++ * queues are flushed. Fetch it from the packet itself
++ */
++ if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
++ next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
++ next_reclaimed =
++ SEQ_TO_SN(next_reclaimed + 0x10);
++ }
++
+ is_offchannel_skb =
+ (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
+ freed++;
+ }
+
++ if (tid != IWL_TID_NON_QOS) {
++ priv->tid_data[sta_id][tid].next_reclaimed =
++ next_reclaimed;
++ IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
++ next_reclaimed);
++ }
++
+ WARN_ON(!is_agg && freed != 1);
+
+ /*
+From 34bcf71502413f8903ade93746f2d0f04b937a78 Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+Date: Tue, 11 Dec 2012 10:48:23 +0100
+Subject: mac80211: fix ibss scanning
+
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+
+commit 34bcf71502413f8903ade93746f2d0f04b937a78 upstream.
+
+Do not scan on no-IBSS and disabled channels in IBSS mode. Doing this
+can trigger Microcode errors on iwlwifi and iwlegacy drivers.
+
+Also rename ieee80211_request_internal_scan() function since it is only
+used in IBSS mode and simplify calling it from ieee80211_sta_find_ibss().
+
+This patch should address:
+https://bugzilla.redhat.com/show_bug.cgi?id=883414
+https://bugzilla.kernel.org/show_bug.cgi?id=49411
+
+Reported-by: Jesse Kahtava <jesse_kahtava at f-m.fm>
+Reported-by: Mikko Rapeli <mikko.rapeli at iki.fi>
+Signed-off-by: Stanislaw Gruszka <sgruszka at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/mac80211/ibss.c | 9 ++++-----
+ net/mac80211/ieee80211_i.h | 6 +++---
+ net/mac80211/scan.c | 34 ++++++++++++++++++++++++----------
+ 3 files changed, 31 insertions(+), 18 deletions(-)
+
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -678,8 +678,8 @@ static void ieee80211_sta_merge_ibss(str
+ sdata_info(sdata,
+ "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
+
+- ieee80211_request_internal_scan(sdata,
+- ifibss->ssid, ifibss->ssid_len, NULL);
++ ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
++ NULL);
+ }
+
+ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
+@@ -777,9 +777,8 @@ static void ieee80211_sta_find_ibss(stru
+ IEEE80211_SCAN_INTERVAL)) {
+ sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
+
+- ieee80211_request_internal_scan(sdata,
+- ifibss->ssid, ifibss->ssid_len,
+- ifibss->fixed_channel ? ifibss->channel : NULL);
++ ieee80211_request_ibss_scan(sdata, ifibss->ssid,
++ ifibss->ssid_len, chan);
+ } else {
+ int interval = IEEE80211_SCAN_INTERVAL;
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1247,9 +1247,9 @@ void ieee80211_mesh_rx_queued_mgmt(struc
+
+ /* scan/BSS handling */
+ void ieee80211_scan_work(struct work_struct *work);
+-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+- const u8 *ssid, u8 ssid_len,
+- struct ieee80211_channel *chan);
++int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
++ const u8 *ssid, u8 ssid_len,
++ struct ieee80211_channel *chan);
+ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_scan_request *req);
+ void ieee80211_scan_cancel(struct ieee80211_local *local);
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -819,9 +819,9 @@ int ieee80211_request_scan(struct ieee80
+ return res;
+ }
+
+-int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+- const u8 *ssid, u8 ssid_len,
+- struct ieee80211_channel *chan)
++int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
++ const u8 *ssid, u8 ssid_len,
++ struct ieee80211_channel *chan)
+ {
+ struct ieee80211_local *local = sdata->local;
+ int ret = -EBUSY;
+@@ -835,22 +835,36 @@ int ieee80211_request_internal_scan(stru
+
+ /* fill internal scan request */
+ if (!chan) {
+- int i, nchan = 0;
++ int i, max_n;
++ int n_ch = 0;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ if (!local->hw.wiphy->bands[band])
+ continue;
+- for (i = 0;
+- i < local->hw.wiphy->bands[band]->n_channels;
+- i++) {
+- local->int_scan_req->channels[nchan] =
++
++ max_n = local->hw.wiphy->bands[band]->n_channels;
++ for (i = 0; i < max_n; i++) {
++ struct ieee80211_channel *tmp_ch =
+ &local->hw.wiphy->bands[band]->channels[i];
+- nchan++;
++
++ if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS |
++ IEEE80211_CHAN_DISABLED))
++ continue;
++
++ local->int_scan_req->channels[n_ch] = tmp_ch;
++ n_ch++;
+ }
+ }
+
+- local->int_scan_req->n_channels = nchan;
++ if (WARN_ON_ONCE(n_ch == 0))
++ goto unlock;
++
++ local->int_scan_req->n_channels = n_ch;
+ } else {
++ if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS |
++ IEEE80211_CHAN_DISABLED)))
++ goto unlock;
++
+ local->int_scan_req->channels[0] = chan;
+ local->int_scan_req->n_channels = 1;
+ }
+From 97f97b1f5fe0878b35c8e314f98591771696321b Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Thu, 13 Dec 2012 22:54:58 +0100
+Subject: mac80211: fix station destruction in AP/mesh modes
+
+From: Johannes Berg <johannes.berg at intel.com>
+
+commit 97f97b1f5fe0878b35c8e314f98591771696321b upstream.
+
+Unfortunately, commit b22cfcfcae5b, intended to speed up roaming
+by avoiding the synchronize_rcu() broke AP/mesh modes as it moved
+some code into that work item that will still call into the driver
+at a time where it's no longer expected to handle this: after the
+AP or mesh has been stopped.
+
+To fix this problem remove the per-station work struct, maintain a
+station cleanup list instead and flush this list when stations are
+flushed. To keep this patch smaller for stable, do this when the
+stations are flushed (sta_info_flush()). This unfortunately brings
+back the original roaming delay; I'll fix that again in a separate
+patch.
+
+Also, Ben reported that the original commit could sometimes (with
+many interfaces) cause long delays when an interface is set down,
+due to blocking on flush_workqueue(). Since we now maintain the
+cleanup list, this particular change of the original patch can be
+reverted.
+
+Reported-by: Ben Greear <greearb at candelatech.com>
+Tested-by: Ben Greear <greearb at candelatech.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/mac80211/ieee80211_i.h | 4 ++++
+ net/mac80211/iface.c | 28 ++++++++++++++++------------
+ net/mac80211/sta_info.c | 44 ++++++++++++++++++++++++++++++++++++++++----
+ net/mac80211/sta_info.h | 3 ++-
+ 4 files changed, 62 insertions(+), 17 deletions(-)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -730,6 +730,10 @@ struct ieee80211_sub_if_data {
+ u32 mntr_flags;
+ } u;
+
++ spinlock_t cleanup_stations_lock;
++ struct list_head cleanup_stations;
++ struct work_struct cleanup_stations_wk;
++
+ #ifdef CONFIG_MAC80211_DEBUGFS
+ struct {
+ struct dentry *dir;
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -793,20 +793,11 @@ static void ieee80211_do_stop(struct iee
+ flush_work(&sdata->work);
+ /*
+ * When we get here, the interface is marked down.
+- * Call rcu_barrier() to wait both for the RX path
++ * Call synchronize_rcu() to wait for the RX path
+ * should it be using the interface and enqueuing
+- * frames at this very time on another CPU, and
+- * for the sta free call_rcu callbacks.
++ * frames at this very time on another CPU.
+ */
+- rcu_barrier();
+-
+- /*
+- * free_sta_rcu() enqueues a work for the actual
+- * sta cleanup, so we need to flush it while
+- * sdata is still valid.
+- */
+- flush_workqueue(local->workqueue);
+-
++ synchronize_rcu();
+ skb_queue_purge(&sdata->skb_queue);
+
+ /*
+@@ -1432,6 +1423,15 @@ static void ieee80211_assign_perm_addr(s
+ mutex_unlock(&local->iflist_mtx);
+ }
+
++static void ieee80211_cleanup_sdata_stas_wk(struct work_struct *wk)
++{
++ struct ieee80211_sub_if_data *sdata;
++
++ sdata = container_of(wk, struct ieee80211_sub_if_data, cleanup_stations_wk);
++
++ ieee80211_cleanup_sdata_stas(sdata);
++}
++
+ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
+ struct wireless_dev **new_wdev, enum nl80211_iftype type,
+ struct vif_params *params)
+@@ -1507,6 +1507,10 @@ int ieee80211_if_add(struct ieee80211_lo
+
+ INIT_LIST_HEAD(&sdata->key_list);
+
++ spin_lock_init(&sdata->cleanup_stations_lock);
++ INIT_LIST_HEAD(&sdata->cleanup_stations);
++ INIT_WORK(&sdata->cleanup_stations_wk, ieee80211_cleanup_sdata_stas_wk);
++
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+ struct ieee80211_supported_band *sband;
+ sband = local->hw.wiphy->bands[i];
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -91,9 +91,8 @@ static int sta_info_hash_del(struct ieee
+ return -ENOENT;
+ }
+
+-static void free_sta_work(struct work_struct *wk)
++static void cleanup_single_sta(struct sta_info *sta)
+ {
+- struct sta_info *sta = container_of(wk, struct sta_info, free_sta_wk);
+ int ac, i;
+ struct tid_ampdu_tx *tid_tx;
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+@@ -148,11 +147,35 @@ static void free_sta_work(struct work_st
+ sta_info_free(local, sta);
+ }
+
++void ieee80211_cleanup_sdata_stas(struct ieee80211_sub_if_data *sdata)
++{
++ struct sta_info *sta;
++
++ spin_lock_bh(&sdata->cleanup_stations_lock);
++ while (!list_empty(&sdata->cleanup_stations)) {
++ sta = list_first_entry(&sdata->cleanup_stations,
++ struct sta_info, list);
++ list_del(&sta->list);
++ spin_unlock_bh(&sdata->cleanup_stations_lock);
++
++ cleanup_single_sta(sta);
++
++ spin_lock_bh(&sdata->cleanup_stations_lock);
++ }
++
++ spin_unlock_bh(&sdata->cleanup_stations_lock);
++}
++
+ static void free_sta_rcu(struct rcu_head *h)
+ {
+ struct sta_info *sta = container_of(h, struct sta_info, rcu_head);
++ struct ieee80211_sub_if_data *sdata = sta->sdata;
+
+- ieee80211_queue_work(&sta->local->hw, &sta->free_sta_wk);
++ spin_lock(&sdata->cleanup_stations_lock);
++ list_add_tail(&sta->list, &sdata->cleanup_stations);
++ spin_unlock(&sdata->cleanup_stations_lock);
++
++ ieee80211_queue_work(&sdata->local->hw, &sdata->cleanup_stations_wk);
+ }
+
+ /* protected by RCU */
+@@ -305,7 +328,6 @@ struct sta_info *sta_info_alloc(struct i
+
+ spin_lock_init(&sta->lock);
+ INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
+- INIT_WORK(&sta->free_sta_wk, free_sta_work);
+ INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
+ mutex_init(&sta->ampdu_mlme.mtx);
+
+@@ -877,6 +899,20 @@ int sta_info_flush(struct ieee80211_loca
+ }
+ mutex_unlock(&local->sta_mtx);
+
++ rcu_barrier();
++
++ if (sdata) {
++ ieee80211_cleanup_sdata_stas(sdata);
++ cancel_work_sync(&sdata->cleanup_stations_wk);
++ } else {
++ mutex_lock(&local->iflist_mtx);
++ list_for_each_entry(sdata, &local->interfaces, list) {
++ ieee80211_cleanup_sdata_stas(sdata);
++ cancel_work_sync(&sdata->cleanup_stations_wk);
++ }
++ mutex_unlock(&local->iflist_mtx);
++ }
++
+ return ret;
+ }
+
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -298,7 +298,6 @@ struct sta_info {
+ spinlock_t lock;
+
+ struct work_struct drv_unblock_wk;
+- struct work_struct free_sta_wk;
+
+ u16 listen_interval;
+
+@@ -558,4 +557,6 @@ void ieee80211_sta_ps_deliver_wakeup(str
+ void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta);
+ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
+
++void ieee80211_cleanup_sdata_stas(struct ieee80211_sub_if_data *sdata);
++
+ #endif /* STA_INFO_H */
+From a56f992cdabc63f56b4b142885deebebf936ff76 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg at intel.com>
+Date: Thu, 13 Dec 2012 23:08:52 +0100
+Subject: mac80211: use del_timer_sync for final sta cleanup timer deletion
+
+From: Johannes Berg <johannes.berg at intel.com>
+
+commit a56f992cdabc63f56b4b142885deebebf936ff76 upstream.
+
+This is a very old bug, but there's nothing that prevents the
+timer from running while the module is being removed when we
+only do del_timer() instead of del_timer_sync().
+
+The timer should normally not be running at this point, but
+it's not clearly impossible (or we could just remove this.)
+
+Tested-by: Ben Greear <greearb at candelatech.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ net/mac80211/sta_info.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -870,7 +870,7 @@ void sta_info_init(struct ieee80211_loca
+
+ void sta_info_stop(struct ieee80211_local *local)
+ {
+- del_timer(&local->sta_cleanup);
++ del_timer_sync(&local->sta_cleanup);
+ sta_info_flush(local, NULL);
+ }
+
+From 9c969d8ccb1e17bd20742f4ac9f00c1a64487234 Mon Sep 17 00:00:00 2001
+From: Bing Zhao <bzhao at marvell.com>
+Date: Wed, 2 Jan 2013 16:07:35 -0800
+Subject: mwifiex: check wait_event_interruptible return value
+
+From: Bing Zhao <bzhao at marvell.com>
+
+commit 9c969d8ccb1e17bd20742f4ac9f00c1a64487234 upstream.
+
+wait_event_interruptible function returns -ERESTARTSYS if it's
+interrupted by a signal. Driver should check the return value
+and handle this case properly.
+
+In mwifiex_wait_queue_complete() routine, as we are now checking
+wait_event_interruptible return value, the condition check is not
+required. Also, we have removed mwifiex_cancel_pending_ioctl()
+call to avoid a chance of sending second command to FW by other path
+as soon as we clear current command node. FW can not handle two
+commands simultaneously.
+
+Signed-off-by: Bing Zhao <bzhao at marvell.com>
+Signed-off-by: Amitkumar Karwar <akarwar at marvell.com>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/mwifiex/sta_ioctl.c | 21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
++++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
+@@ -56,7 +56,6 @@ int mwifiex_copy_mcast_addr(struct mwifi
+ */
+ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
+ {
+- bool cancel_flag = false;
+ int status;
+ struct cmd_ctrl_node *cmd_queued;
+
+@@ -70,14 +69,11 @@ int mwifiex_wait_queue_complete(struct m
+ atomic_inc(&adapter->cmd_pending);
+
+ /* Wait for completion */
+- wait_event_interruptible(adapter->cmd_wait_q.wait,
+- *(cmd_queued->condition));
+- if (!*(cmd_queued->condition))
+- cancel_flag = true;
+-
+- if (cancel_flag) {
+- mwifiex_cancel_pending_ioctl(adapter);
+- dev_dbg(adapter->dev, "cmd cancel\n");
++ status = wait_event_interruptible(adapter->cmd_wait_q.wait,
++ *(cmd_queued->condition));
++ if (status) {
++ dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
++ return status;
+ }
+
+ status = adapter->cmd_wait_q.status;
+@@ -480,8 +476,11 @@ int mwifiex_enable_hs(struct mwifiex_ada
+ return false;
+ }
+
+- wait_event_interruptible(adapter->hs_activate_wait_q,
+- adapter->hs_activate_wait_q_woken);
++ if (wait_event_interruptible(adapter->hs_activate_wait_q,
++ adapter->hs_activate_wait_q_woken)) {
++ dev_err(adapter->dev, "hs_activate_wait_q terminated\n");
++ return false;
++ }
+
+ return true;
+ }
+From 5e20a4b53094651d80f856ff55a916b999dbb57a Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger at lwfinger.net>
+Date: Thu, 20 Dec 2012 15:55:01 -0600
+Subject: b43: Fix firmware loading when driver is built into the kernel
+
+From: Larry Finger <Larry.Finger at lwfinger.net>
+
+commit 5e20a4b53094651d80f856ff55a916b999dbb57a upstream.
+
+Recent versions of udev cause synchronous firmware loading from the
+probe routine to fail because the request to user space would time
+out. The original fix for b43 (commit 6b6fa58) moved the firmware
+load from the probe routine to a work queue, but it still used synchronous
+firmware loading. This method is OK when b43 is built as a module;
+however, it fails when the driver is compiled into the kernel.
+
+This version changes the code to load the initial firmware file
+using request_firmware_nowait(). A completion event is used to
+hold the work queue until that file is available. This driver
+reads several firmware files - the remainder can be read synchronously.
+On some test systems, the async read fails; however, a following synch
+read works, thus the async failure falls through to the sync try.
+
+Reported-and-Tested by: Felix Janda <felix.janda at posteo.de>
+Signed-off-by: Larry Finger <Larry.Finger at lwfinger.net>
+Signed-off-by: John W. Linville <linville at tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/b43/b43.h | 5 +++
+ drivers/net/wireless/b43/main.c | 54 ++++++++++++++++++++++++++++++----------
+ drivers/net/wireless/b43/main.h | 5 +--
+ 3 files changed, 48 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/wireless/b43/b43.h
++++ b/drivers/net/wireless/b43/b43.h
+@@ -7,6 +7,7 @@
+ #include <linux/hw_random.h>
+ #include <linux/bcma/bcma.h>
+ #include <linux/ssb/ssb.h>
++#include <linux/completion.h>
+ #include <net/mac80211.h>
+
+ #include "debugfs.h"
+@@ -722,6 +723,10 @@ enum b43_firmware_file_type {
+ struct b43_request_fw_context {
+ /* The device we are requesting the fw for. */
+ struct b43_wldev *dev;
++ /* a completion event structure needed if this call is asynchronous */
++ struct completion fw_load_complete;
++ /* a pointer to the firmware object */
++ const struct firmware *blob;
+ /* The type of firmware to request. */
+ enum b43_firmware_file_type req_type;
+ /* Error messages for each firmware type. */
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -2088,11 +2088,18 @@ static void b43_print_fw_helptext(struct
+ b43warn(wl, text);
+ }
+
++static void b43_fw_cb(const struct firmware *firmware, void *context)
++{
++ struct b43_request_fw_context *ctx = context;
++
++ ctx->blob = firmware;
++ complete(&ctx->fw_load_complete);
++}
++
+ int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+- struct b43_firmware_file *fw)
++ struct b43_firmware_file *fw, bool async)
+ {
+- const struct firmware *blob;
+ struct b43_fw_header *hdr;
+ u32 size;
+ int err;
+@@ -2131,11 +2138,31 @@ int b43_do_request_fw(struct b43_request
+ B43_WARN_ON(1);
+ return -ENOSYS;
+ }
+- err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
++ if (async) {
++ /* do this part asynchronously */
++ init_completion(&ctx->fw_load_complete);
++ err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,
++ ctx->dev->dev->dev, GFP_KERNEL,
++ ctx, b43_fw_cb);
++ if (err < 0) {
++ pr_err("Unable to load firmware\n");
++ return err;
++ }
++ /* stall here until fw ready */
++ wait_for_completion(&ctx->fw_load_complete);
++ if (ctx->blob)
++ goto fw_ready;
++ /* On some ARM systems, the async request will fail, but the next sync
++ * request works. For this reason, we dall through here
++ */
++ }
++ err = request_firmware(&ctx->blob, ctx->fwname,
++ ctx->dev->dev->dev);
+ if (err == -ENOENT) {
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+- "Firmware file \"%s\" not found\n", ctx->fwname);
++ "Firmware file \"%s\" not found\n",
++ ctx->fwname);
+ return err;
+ } else if (err) {
+ snprintf(ctx->errors[ctx->req_type],
+@@ -2144,14 +2171,15 @@ int b43_do_request_fw(struct b43_request
+ ctx->fwname, err);
+ return err;
+ }
+- if (blob->size < sizeof(struct b43_fw_header))
++fw_ready:
++ if (ctx->blob->size < sizeof(struct b43_fw_header))
+ goto err_format;
+- hdr = (struct b43_fw_header *)(blob->data);
++ hdr = (struct b43_fw_header *)(ctx->blob->data);
+ switch (hdr->type) {
+ case B43_FW_TYPE_UCODE:
+ case B43_FW_TYPE_PCM:
+ size = be32_to_cpu(hdr->size);
+- if (size != blob->size - sizeof(struct b43_fw_header))
++ if (size != ctx->blob->size - sizeof(struct b43_fw_header))
+ goto err_format;
+ /* fallthrough */
+ case B43_FW_TYPE_IV:
+@@ -2162,7 +2190,7 @@ int b43_do_request_fw(struct b43_request
+ goto err_format;
+ }
+
+- fw->data = blob;
++ fw->data = ctx->blob;
+ fw->filename = name;
+ fw->type = ctx->req_type;
+
+@@ -2172,7 +2200,7 @@ err_format:
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" format error.\n", ctx->fwname);
+- release_firmware(blob);
++ release_firmware(ctx->blob);
+
+ return -EPROTO;
+ }
+@@ -2223,7 +2251,7 @@ static int b43_try_request_fw(struct b43
+ goto err_no_ucode;
+ }
+ }
+- err = b43_do_request_fw(ctx, filename, &fw->ucode);
++ err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
+ if (err)
+ goto err_load;
+
+@@ -2235,7 +2263,7 @@ static int b43_try_request_fw(struct b43
+ else
+ goto err_no_pcm;
+ fw->pcm_request_failed = false;
+- err = b43_do_request_fw(ctx, filename, &fw->pcm);
++ err = b43_do_request_fw(ctx, filename, &fw->pcm, false);
+ if (err == -ENOENT) {
+ /* We did not find a PCM file? Not fatal, but
+ * core rev <= 10 must do without hwcrypto then. */
+@@ -2296,7 +2324,7 @@ static int b43_try_request_fw(struct b43
+ default:
+ goto err_no_initvals;
+ }
+- err = b43_do_request_fw(ctx, filename, &fw->initvals);
++ err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
+ if (err)
+ goto err_load;
+
+@@ -2355,7 +2383,7 @@ static int b43_try_request_fw(struct b43
+ default:
+ goto err_no_initvals;
+ }
+- err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
++ err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
+ if (err)
+ goto err_load;
+
+--- a/drivers/net/wireless/b43/main.h
++++ b/drivers/net/wireless/b43/main.h
+@@ -137,9 +137,8 @@ void b43_mac_phy_clock_set(struct b43_wl
+
+
+ struct b43_request_fw_context;
+-int b43_do_request_fw(struct b43_request_fw_context *ctx,
+- const char *name,
+- struct b43_firmware_file *fw);
++int b43_do_request_fw(struct b43_request_fw_context *ctx, const char *name,
++ struct b43_firmware_file *fw, bool async);
+ void b43_do_release_fw(struct b43_firmware_file *fw);
+
+ #endif /* B43_MAIN_H_ */
+From ad86e58661b38b279b7519d4e49c7a19dc1654bb Mon Sep 17 00:00:00 2001
+From: Dzianis Kahanovich <mahatma at bspu.unibel.by>
+Date: Mon, 3 Dec 2012 16:06:26 +0300
+Subject: USB: option: add Nexpring NP10T terminal id
+
+From: Dzianis Kahanovich <mahatma at bspu.unibel.by>
+
+commit ad86e58661b38b279b7519d4e49c7a19dc1654bb upstream.
+
+Hyundai Petatel Inc. Nexpring NP10T terminal (EV-DO rev.A USB modem) ID
+
+Signed-off-by: Denis Kaganovich <mahatma at eu.by>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -442,6 +442,10 @@ static void option_instat_callback(struc
+ #define CELLIENT_VENDOR_ID 0x2692
+ #define CELLIENT_PRODUCT_MEN200 0x9005
+
++/* Hyundai Petatel Inc. products */
++#define PETATEL_VENDOR_ID 0x1ff4
++#define PETATEL_PRODUCT_NP10T 0x600e
++
+ /* some devices interfaces need special handling due to a number of reasons */
+ enum option_blacklist_reason {
+ OPTION_BLACKLIST_NONE = 0,
+@@ -1296,6 +1300,7 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) },
+ { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
++ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+From fab38246f318edcd0dcb8fd3852a47cf8938878a Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn at mork.no>
+Date: Wed, 19 Dec 2012 15:15:17 +0100
+Subject: USB: option: blacklist network interface on ZTE MF880
+
+From: Bjørn Mork <bjorn at mork.no>
+
+commit fab38246f318edcd0dcb8fd3852a47cf8938878a upstream.
+
+The driver description files gives these names to the vendor specific
+functions on this modem:
+
+ diag: VID_19D2&PID_0284&MI_00
+ nmea: VID_19D2&PID_0284&MI_01
+ at: VID_19D2&PID_0284&MI_02
+ mdm: VID_19D2&PID_0284&MI_03
+ net: VID_19D2&PID_0284&MI_04
+
+Signed-off-by: Bjørn Mork <bjorn at mork.no>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -928,7 +928,8 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */
+ .driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff) },
+- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */
++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+From 94a85b633829b946eef53fc1825d526312fb856f Mon Sep 17 00:00:00 2001
+From: "Quentin.Li" <snowmanli88 at 163.com>
+Date: Wed, 26 Dec 2012 16:58:22 +0800
+Subject: USB: option: Add new MEDIATEK PID support
+
+From: "Quentin.Li" <snowmanli88 at 163.com>
+
+commit 94a85b633829b946eef53fc1825d526312fb856f upstream.
+
+In option.c, add some new MEDIATEK PIDs support for MEDIATEK new products. This
+is a MEDIATEK inc. release patch.
+
+Signed-off-by: Quentin.Li <snowmanli88 at 163.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -430,9 +430,12 @@ static void option_instat_callback(struc
+ #define MEDIATEK_VENDOR_ID 0x0e8d
+ #define MEDIATEK_PRODUCT_DC_1COM 0x00a0
+ #define MEDIATEK_PRODUCT_DC_4COM 0x00a5
++#define MEDIATEK_PRODUCT_DC_4COM2 0x00a7
+ #define MEDIATEK_PRODUCT_DC_5COM 0x00a4
+ #define MEDIATEK_PRODUCT_7208_1COM 0x7101
+ #define MEDIATEK_PRODUCT_7208_2COM 0x7102
++#define MEDIATEK_PRODUCT_7103_2COM 0x7103
++#define MEDIATEK_PRODUCT_7106_2COM 0x7106
+ #define MEDIATEK_PRODUCT_FP_1COM 0x0003
+ #define MEDIATEK_PRODUCT_FP_2COM 0x0023
+ #define MEDIATEK_PRODUCT_FPDC_1COM 0x0043
+@@ -1300,6 +1303,10 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7103_2COM, 0xff, 0x00, 0x00) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7106_2COM, 0x02, 0x02, 0x01) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) },
++ { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) },
+ { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) },
+ { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },
+ { } /* Terminating entry */
+From 5ec0085440ef8c2cf50002b34d5a504ee12aa2bf Mon Sep 17 00:00:00 2001
+From: Bjørn Mork <bjorn at mork.no>
+Date: Fri, 28 Dec 2012 17:29:52 +0100
+Subject: USB: option: add Telekom Speedstick LTE II
+
+From: Bjørn Mork <bjorn at mork.no>
+
+commit 5ec0085440ef8c2cf50002b34d5a504ee12aa2bf upstream.
+
+also known as Alcatel One Touch L100V LTE
+
+The driver description files gives these names to the vendor specific
+functions on this modem:
+
+ Application1: VID_1BBB&PID_011E&MI_00
+ Application2: VID_1BBB&PID_011E&MI_01
+ Modem: VID_1BBB&PID_011E&MI_03
+ Ethernet: VID_1BBB&PID_011E&MI_04
+
+Reported-by: Thomas Schäfer <tschaefer at t-online.de>
+Signed-off-by: Bjørn Mork <bjorn at mork.no>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -289,6 +289,7 @@ static void option_instat_callback(struc
+ #define ALCATEL_VENDOR_ID 0x1bbb
+ #define ALCATEL_PRODUCT_X060S_X200 0x0000
+ #define ALCATEL_PRODUCT_X220_X500D 0x0017
++#define ALCATEL_PRODUCT_L100V 0x011e
+
+ #define PIRELLI_VENDOR_ID 0x1266
+ #define PIRELLI_PRODUCT_C100_1 0x1002
+@@ -1199,6 +1200,8 @@ static const struct usb_device_id option
+ .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
+ },
+ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
++ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V),
++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
+ { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+ { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
+From 8cf65dc386f3634a43312f436cc7a935476a40c4 Mon Sep 17 00:00:00 2001
+From: Tomasz Mloduchowski <q at qdot.me>
+Date: Sun, 13 Jan 2013 23:32:53 +0100
+Subject: usb: ftdi_sio: Crucible Technologies COMET Caller ID - pid added
+
+From: Tomasz Mloduchowski <q at qdot.me>
+
+commit 8cf65dc386f3634a43312f436cc7a935476a40c4 upstream.
+
+Simple fix to add support for Crucible Technologies COMET Caller ID
+USB decoder - a device containing FTDI USB/Serial converter chip,
+handling 1200bps CallerID messages decoded from the phone line -
+adding correct USB PID is sufficient.
+
+Tested to apply cleanly and work flawlessly against 3.6.9, 3.7.0-rc8
+and 3.8.0-rc3 on both amd64 and x86 arches.
+
+Signed-off-by: Tomasz Mloduchowski <q at qdot.me>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 2 ++
+ drivers/usb/serial/ftdi_sio_ids.h | 6 ++++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -876,6 +876,8 @@ static struct usb_device_id id_table_com
+ { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
++ /* Crucible Devices */
++ { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
+ { }, /* Optional parameter entry */
+ { } /* Terminating entry */
+ };
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -1259,3 +1259,9 @@
+ * ATI command output: Cinterion MC55i
+ */
+ #define FTDI_CINTERION_MC55I_PID 0xA951
++
++/*
++ * Product: Comet Caller ID decoder
++ * Manufacturer: Crucible Technologies
++ */
++#define FTDI_CT_COMET_PID 0x8e08
+From 036915a7a402753c05b8d0529f5fd08805ab46d0 Mon Sep 17 00:00:00 2001
+From: Denis N Ladin <denladin at gmail.com>
+Date: Wed, 26 Dec 2012 18:29:44 +0500
+Subject: USB: cdc-acm: Add support for "PSC Scanning, Magellan 800i"
+
+From: Denis N Ladin <denladin at gmail.com>
+
+commit 036915a7a402753c05b8d0529f5fd08805ab46d0 upstream.
+
+Adding support "PSC Scanning, Magellan 800i" in cdc-acm
+
+Very simple, but very necessary.
+Suitable for all versions of the kernel > 2.6
+
+Signed-off-by: Denis N Ladin <denladin at gmail.com>
+Acked-by: Oliver Neukum <oneukum at suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1602,6 +1602,9 @@ static const struct usb_device_id acm_id
+ { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */
+ .driver_info = NO_UNION_NORMAL,
+ },
++ { USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */
++ .driver_info = NO_UNION_NORMAL,
++ },
+ { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
+From 1d16638e3b9cc195bac18a8fcbca748f33c1bc24 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+Date: Tue, 20 Nov 2012 13:23:15 +0100
+Subject: usb: gadget: dummy: fix enumeration with g_multi
+
+From: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+
+commit 1d16638e3b9cc195bac18a8fcbca748f33c1bc24 upstream.
+
+If we do have endpoints named like "ep-a" then bEndpointAddress is
+counted internally by the gadget framework.
+
+If we do have endpoints named like "ep-1" then bEndpointAddress is
+assigned from the digit after "ep-".
+
+If we do have both, then it is likely that after we used up the
+"generic" endpoints we will use the digits and thus assign one
+bEndpointAddress to multiple endpoints.
+
+This theory can be proofed by using the completely enabled g_multi.
+Without this patch, the mass storage won't enumerate and times out
+because it shares endpoints with RNDIS.
+
+This patch also adds fills up the endpoints list so we have in total
+endpoints 1 to 15 in + out available while some of them are restricted
+to certain types like BULK or ISO. Without this change the nokia gadget
+won't load because the system does not provide enough (BULK) endpoints
+but it did before ep-a - ep-f were removed.
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Felipe Balbi <balbi at ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/gadget/dummy_hcd.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/gadget/dummy_hcd.c
++++ b/drivers/usb/gadget/dummy_hcd.c
+@@ -126,10 +126,7 @@ static const char ep0name[] = "ep0";
+ static const char *const ep_name[] = {
+ ep0name, /* everyone has ep0 */
+
+- /* act like a net2280: high speed, six configurable endpoints */
+- "ep-a", "ep-b", "ep-c", "ep-d", "ep-e", "ep-f",
+-
+- /* or like pxa250: fifteen fixed function endpoints */
++ /* act like a pxa250: fifteen fixed function endpoints */
+ "ep1in-bulk", "ep2out-bulk", "ep3in-iso", "ep4out-iso", "ep5in-int",
+ "ep6in-bulk", "ep7out-bulk", "ep8in-iso", "ep9out-iso", "ep10in-int",
+ "ep11in-bulk", "ep12out-bulk", "ep13in-iso", "ep14out-iso",
+@@ -137,6 +134,10 @@ static const char *const ep_name[] = {
+
+ /* or like sa1100: two fixed function endpoints */
+ "ep1out-bulk", "ep2in-bulk",
++
++ /* and now some generic EPs so we have enough in multi config */
++ "ep3out", "ep4in", "ep5out", "ep6out", "ep7in", "ep8out", "ep9in",
++ "ep10out", "ep11out", "ep12in", "ep13out", "ep14in", "ep15out",
+ };
+ #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name)
+
+From 2ac788f705e5118dd45204e7a5bc8d5bb6873835 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov at ru.mvista.com>
+Date: Wed, 14 Nov 2012 18:49:50 +0300
+Subject: usb: musb: core: print new line in the driver banner again
+
+From: Sergei Shtylyov <sshtylyov at ru.mvista.com>
+
+commit 2ac788f705e5118dd45204e7a5bc8d5bb6873835 upstream.
+
+Commit 5c8a86e10a7c164f44537fabdc169fd8b4e7a440 (usb: musb: drop unneeded
+musb_debug trickery) erroneously removed '\n' from the driver's banner.
+Concatenate all the banner substrings while adding it back...
+
+Signed-off-by: Sergei Shtylyov <sshtylyov at ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi at ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/musb/musb_core.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2351,10 +2351,7 @@ static int __init musb_init(void)
+ if (usb_disabled())
+ return 0;
+
+- pr_info("%s: version " MUSB_VERSION ", "
+- "?dma?"
+- ", "
+- "otg (peripheral+host)",
++ pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n",
+ musb_driver_name);
+ return platform_driver_register(&musb_driver);
+ }
+From f20ebd034eab43fd38c58b11c5bb5fb125e5f7d7 Mon Sep 17 00:00:00 2001
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+Date: Tue, 25 Dec 2012 18:13:22 +0100
+Subject: drm/nv17-50: restore fence buffer on resume
+
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+
+commit f20ebd034eab43fd38c58b11c5bb5fb125e5f7d7 upstream.
+
+Since commit 5e120f6e4b3f35b741c5445dfc755f50128c3c44 "drm/nouveau/fence:
+convert to exec engine, and improve channel sync" nouveau fence sync
+implementation for nv17-50 and nvc0+ started to rely on state of fence buffer
+left by previous sync operation. But as pinned bo's (where fence state is
+stored) are not saved+restored across suspend/resume, we need to do it
+manually.
+
+nvc0+ was fixed by commit d6ba6d215a538a58f0f0026f0961b0b9125e8042
+"drm/nvc0/fence: restore pre-suspend fence buffer context on resume".
+
+Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=50121
+
+Signed-off-by: Marcin Slusarz <marcin.slusarz at gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nouveau_fence.h | 1 +
+ drivers/gpu/drm/nouveau/nv10_fence.c | 8 ++++++++
+ drivers/gpu/drm/nouveau/nv50_fence.c | 1 +
+ 3 files changed, 10 insertions(+)
+
+--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
++++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
+@@ -60,6 +60,7 @@ u32 nv10_fence_read(struct nouveau_chan
+ void nv10_fence_context_del(struct nouveau_channel *);
+ void nv10_fence_destroy(struct nouveau_drm *);
+ int nv10_fence_create(struct nouveau_drm *);
++void nv17_fence_resume(struct nouveau_drm *drm);
+
+ int nv50_fence_create(struct nouveau_drm *);
+ int nv84_fence_create(struct nouveau_drm *);
+--- a/drivers/gpu/drm/nouveau/nv10_fence.c
++++ b/drivers/gpu/drm/nouveau/nv10_fence.c
+@@ -160,6 +160,13 @@ nv10_fence_destroy(struct nouveau_drm *d
+ kfree(priv);
+ }
+
++void nv17_fence_resume(struct nouveau_drm *drm)
++{
++ struct nv10_fence_priv *priv = drm->fence;
++
++ nouveau_bo_wr32(priv->bo, 0, priv->sequence);
++}
++
+ int
+ nv10_fence_create(struct nouveau_drm *drm)
+ {
+@@ -192,6 +199,7 @@ nv10_fence_create(struct nouveau_drm *dr
+ if (ret == 0) {
+ nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
+ priv->base.sync = nv17_fence_sync;
++ priv->base.resume = nv17_fence_resume;
+ }
+ }
+
+--- a/drivers/gpu/drm/nouveau/nv50_fence.c
++++ b/drivers/gpu/drm/nouveau/nv50_fence.c
+@@ -119,6 +119,7 @@ nv50_fence_create(struct nouveau_drm *dr
+ if (ret == 0) {
+ nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
+ priv->base.sync = nv17_fence_sync;
++ priv->base.resume = nv17_fence_resume;
+ }
+
+ if (ret)
+From 92441b2263866c27ef48137be5aa6c8c692652fc Mon Sep 17 00:00:00 2001
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+Date: Tue, 18 Dec 2012 20:30:47 +0100
+Subject: drm/nouveau: fix blank LVDS screen regression on pre-nv50 cards
+
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+
+commit 92441b2263866c27ef48137be5aa6c8c692652fc upstream.
+
+Commit 2a44e499 ("drm/nouveau/disp: introduce proper init/fini, separate
+from create/destroy") started to call display init routines on pre-nv50
+hardware on module load. But LVDS init code sets driver state in a way
+which prevents modesetting code from operating properly.
+
+nv04_display_init calls nv04_dfp_restore, which sets encoder->last_dpms to
+NV_DPMS_CLEARED.
+
+drm_crtc_helper_set_mode
+ nv04_dfp_prepare
+ nv04_lvds_dpms(DRM_MODE_DPMS_OFF)
+
+nv04_lvds_dpms checks last_dpms mode (which is NV_DPMS_CLEARED) and wrongly
+assumes it's a "powersaving mode", the new one (DRM_MODE_DPMS_OFF) is too,
+so it skips calling some crucial lvds scripts.
+
+Reported-by: Chris Paulson-Ellis <chris at edesix.com>
+Signed-off-by: Marcin Slusarz <marcin.slusarz at gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/nv04_dfp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
++++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
+@@ -505,7 +505,7 @@ static void nv04_dfp_update_backlight(st
+
+ static inline bool is_powersaving_dpms(int mode)
+ {
+- return (mode != DRM_MODE_DPMS_ON);
++ return mode != DRM_MODE_DPMS_ON && mode != NV_DPMS_CLEARED;
+ }
+
+ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
+From 4c4101d29fb6c63f78791d02c437702b11e1d4f0 Mon Sep 17 00:00:00 2001
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+Date: Sun, 2 Dec 2012 12:56:22 +0100
+Subject: drm/nouveau: add locking around instobj list operations
+
+From: Marcin Slusarz <marcin.slusarz at gmail.com>
+
+commit 4c4101d29fb6c63f78791d02c437702b11e1d4f0 upstream.
+
+Fixes memory corruptions, oopses, etc. when multiple gpuobjs are
+simultaneously created or destroyed.
+
+Signed-off-by: Marcin Slusarz <marcin.slusarz at gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/subdev/instmem/base.c | 35 ++++++++++++++++-----
+ 1 file changed, 27 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
++++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/base.c
+@@ -40,15 +40,21 @@ nouveau_instobj_create_(struct nouveau_o
+ if (ret)
+ return ret;
+
++ mutex_lock(&imem->base.mutex);
+ list_add(&iobj->head, &imem->list);
++ mutex_unlock(&imem->base.mutex);
+ return 0;
+ }
+
+ void
+ nouveau_instobj_destroy(struct nouveau_instobj *iobj)
+ {
+- if (iobj->head.prev)
+- list_del(&iobj->head);
++ struct nouveau_subdev *subdev = nv_subdev(iobj->base.engine);
++
++ mutex_lock(&subdev->mutex);
++ list_del(&iobj->head);
++ mutex_unlock(&subdev->mutex);
++
+ return nouveau_object_destroy(&iobj->base);
+ }
+
+@@ -88,6 +94,8 @@ nouveau_instmem_init(struct nouveau_inst
+ if (ret)
+ return ret;
+
++ mutex_lock(&imem->base.mutex);
++
+ list_for_each_entry(iobj, &imem->list, head) {
+ if (iobj->suspend) {
+ for (i = 0; i < iobj->size; i += 4)
+@@ -97,6 +105,8 @@ nouveau_instmem_init(struct nouveau_inst
+ }
+ }
+
++ mutex_unlock(&imem->base.mutex);
++
+ return 0;
+ }
+
+@@ -104,17 +114,26 @@ int
+ nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend)
+ {
+ struct nouveau_instobj *iobj;
+- int i;
++ int i, ret = 0;
+
+ if (suspend) {
++ mutex_lock(&imem->base.mutex);
++
+ list_for_each_entry(iobj, &imem->list, head) {
+ iobj->suspend = vmalloc(iobj->size);
+- if (iobj->suspend) {
+- for (i = 0; i < iobj->size; i += 4)
+- iobj->suspend[i / 4] = nv_ro32(iobj, i);
+- } else
+- return -ENOMEM;
++ if (!iobj->suspend) {
++ ret = -ENOMEM;
++ break;
++ }
++
++ for (i = 0; i < iobj->size; i += 4)
++ iobj->suspend[i / 4] = nv_ro32(iobj, i);
+ }
++
++ mutex_unlock(&imem->base.mutex);
++
++ if (ret)
++ return ret;
+ }
+
+ return nouveau_subdev_fini(&imem->base, suspend);
+From d19528a9e4f220519c2cb3f56ef0c84ead3ee440 Mon Sep 17 00:00:00 2001
+From: Aleksi Torhamo <aleksi at torhamo.net>
+Date: Fri, 4 Jan 2013 18:39:13 +0200
+Subject: drm/nouveau/clock: fix support for more than 2 monitors on nve0
+
+From: Aleksi Torhamo <aleksi at torhamo.net>
+
+commit d19528a9e4f220519c2cb3f56ef0c84ead3ee440 upstream.
+
+Fixes regression introduced in commit 70790f4f
+"drm/nouveau/clock: pull in the implementation from all over the place"
+
+When code was moved from nv50_crtc_set_clock to nvc0_clock_pll_set,
+the PLLs it is used for got limited to only the first two VPLLs.
+
+nv50_crtc_set_clock was only called to change VPLLs, so it didn't
+limit what it was used for in any way. Since nvc0_clock_pll_set is
+used for all PLLs, it has to specify which PLLs the code is used for,
+and only listed the first two VPLLs.
+
+Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=58735
+
+This patch is a -stable candidate for 3.7.
+
+Signed-off-by: Aleksi Torhamo <aleksi at torhamo.net>
+Tested-by: Aleksi Torhamo <aleksi at torhamo.net>
+Tested-by: Sean Santos <quantheory at gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h | 2 ++
+ drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
++++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
+@@ -38,6 +38,8 @@ enum nvbios_pll_type {
+ PLL_UNK42 = 0x42,
+ PLL_VPLL0 = 0x80,
+ PLL_VPLL1 = 0x81,
++ PLL_VPLL2 = 0x82,
++ PLL_VPLL3 = 0x83,
+ PLL_MAX = 0xff
+ };
+
+--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
++++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+@@ -52,6 +52,8 @@ nvc0_clock_pll_set(struct nouveau_clock
+ switch (info.type) {
+ case PLL_VPLL0:
+ case PLL_VPLL1:
++ case PLL_VPLL2:
++ case PLL_VPLL3:
+ nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
+ nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
+ nv_wr32(priv, info.reg + 0x10, fN << 16);
+From 43f789792e2c7ea2bff37195e4c4b4239e9e02b7 Mon Sep 17 00:00:00 2001
+From: Aleksi Torhamo <aleksi at torhamo.net>
+Date: Wed, 9 Jan 2013 20:08:48 +0200
+Subject: drm/nvc0/fb: fix crash when different mutex is used to protect same list
+
+From: Aleksi Torhamo <aleksi at torhamo.net>
+
+commit 43f789792e2c7ea2bff37195e4c4b4239e9e02b7 upstream.
+
+Fixes regression introduced in commit 861d2107
+"drm/nouveau/fb: merge fb/vram and port to subdev interfaces"
+
+nv50_fb_vram_{new,del} functions were changed to use
+nouveau_subdev->mutex instead of the old nouveau_mm->mutex.
+nvc0_fb_vram_new still uses the nouveau_mm->mutex, but nvc0 doesn't
+have its own fb_vram_del function, using nv50_fb_vram_del instead.
+Because of this, on nvc0 a different mutex ends up being used to protect
+additions and deletions to the same list.
+
+This patch is a -stable candidate for 3.7.
+
+Signed-off-by: Aleksi Torhamo <aleksi at torhamo.net>
+Reported-by: Roy Spliet <r.spliet at student.tudelft.nl>
+Tested-by: Roy Spliet <r.spliet at student.tudelft.nl>
+Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
++++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+@@ -86,14 +86,14 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb,
+ mem->memtype = type;
+ mem->size = size;
+
+- mutex_lock(&mm->mutex);
++ mutex_lock(&pfb->base.mutex);
+ do {
+ if (back)
+ ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
+ else
+ ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
+ if (ret) {
+- mutex_unlock(&mm->mutex);
++ mutex_unlock(&pfb->base.mutex);
+ pfb->ram.put(pfb, &mem);
+ return ret;
+ }
+@@ -101,7 +101,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb,
+ list_add_tail(&r->rl_entry, &mem->regions);
+ size -= r->length;
+ } while (size);
+- mutex_unlock(&mm->mutex);
++ mutex_unlock(&pfb->base.mutex);
+
+ r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
+ mem->offset = (u64)r->offset << 12;
+From 1c7439c61fa6516419c32a9824976334ea969d47 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Wed, 14 Nov 2012 15:58:52 -0800
+Subject: USB: Handle auto-transition from hot to warm reset.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 1c7439c61fa6516419c32a9824976334ea969d47 upstream.
+
+USB 3.0 hubs and roothubs will automatically transition a failed hot
+reset to a warm (BH) reset. In that case, the warm reset change bit
+will be set, and the link state change bit may also be set. Change
+hub_port_finish_reset to unconditionally clear those change bits for USB
+3.0 hubs. If these bits are not cleared, we may lose port change events
+from the roothub.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2541,16 +2541,16 @@ static void hub_port_finish_reset(struct
+ clear_port_feature(hub->hdev,
+ port1, USB_PORT_FEAT_C_RESET);
+ /* FIXME need disconnect() for NOTATTACHED device */
+- if (warm) {
++ if (hub_is_superspeed(hub->hdev)) {
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_BH_PORT_RESET);
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_PORT_LINK_STATE);
+- } else {
++ }
++ if (!warm)
+ usb_set_device_state(udev, *status
+ ? USB_STATE_NOTATTACHED
+ : USB_STATE_DEFAULT);
+- }
+ break;
+ }
+ }
+From bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 Mon Sep 17 00:00:00 2001
+From: Andreas Fleig <andreasfleig at gmail.com>
+Date: Wed, 5 Dec 2012 16:17:49 +0100
+Subject: USB: Add device quirk for Microsoft VX700 webcam
+
+From: Andreas Fleig <andreasfleig at gmail.com>
+
+commit bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 upstream.
+
+Add device quirk for Microsoft Lifecam VX700 v2.0 webcams.
+Fixes squeaking noise of the microphone.
+
+Signed-off-by: Andreas Fleig <andreasfleig at gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/quirks.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -43,6 +43,9 @@ static const struct usb_device_id usb_qu
+ /* Creative SB Audigy 2 NX */
+ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
+
++ /* Microsoft LifeCam-VX700 v2.0 */
++ { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ /* Logitech Quickcam Fusion */
+ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
+
+From 8b8132bc3d1cc3d4c0687e4d638a482fa920d98a Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Wed, 14 Nov 2012 16:10:49 -0800
+Subject: USB: Ignore xHCI Reset Device status.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 8b8132bc3d1cc3d4c0687e4d638a482fa920d98a upstream.
+
+When the USB core finishes reseting a USB device, the xHCI driver sends
+a Reset Device command to the host. The xHC then updates its internal
+representation of the USB device to the 'Default' device state. If the
+device was already in the Default state, the xHC will complete the
+command with an error status.
+
+If a device needs to be reset several times during enumeration, the
+second reset will always fail because of the xHCI Reset Device command.
+This can cause issues during enumeration.
+
+For example, usb_reset_and_verify_device calls into hub_port_init in a
+loop. Say that on the first call into hub_port_init, the device is
+successfully reset, but doesn't respond to several set address control
+transfers. Then the port will be disabled, but the udev will remain in
+tact. usb_reset_and_verify_device will call into hub_port_init again.
+
+On the second call into hub_port_init, the device will be reset, and the
+xHCI driver will issue a Reset Device command. This command will fail
+(because the device is already in the Default state), and
+usb_reset_and_verify_device will fail. The port will be disabled, and
+the device won't be able to enumerate.
+
+Fix this by ignoring the return value of the HCD reset_device callback.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2526,14 +2526,11 @@ static void hub_port_finish_reset(struct
+ msleep(10 + 40);
+ update_devnum(udev, 0);
+ hcd = bus_to_hcd(udev->bus);
+- if (hcd->driver->reset_device) {
+- *status = hcd->driver->reset_device(hcd, udev);
+- if (*status < 0) {
+- dev_err(&udev->dev, "Cannot reset "
+- "HCD device state\n");
+- break;
+- }
+- }
++ /* The xHC may think the device is already reset,
++ * so ignore the status.
++ */
++ if (hcd->driver->reset_device)
++ hcd->driver->reset_device(hcd, udev);
+ }
+ /* FALL THROUGH */
+ case -ENOTCONN:
+From 41e7e056cdc662f704fa9262e5c6e213b4ab45dd Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Wed, 14 Nov 2012 16:42:32 -0800
+Subject: USB: Allow USB 3.0 ports to be disabled.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 41e7e056cdc662f704fa9262e5c6e213b4ab45dd upstream.
+
+If hot and warm reset fails, or a port remains in the Compliance Mode,
+the USB core needs to be able to disable a USB 3.0 port. Unlike USB 2.0
+ports, once the port is placed into the Disabled link state, it will not
+report any new device connects. To get device connect notifications, we
+need to put the link into the Disabled state, and then the RxDetect
+state.
+
+The xHCI driver needs to atomically clear all change bits on USB 3.0
+port disable, so that we get Port Status Change Events for future port
+changes. We could technically do this in the USB core instead of in the
+xHCI roothub code, since the port state machine can't advance out of the
+disabled state until we set the link state to RxDetect. However,
+external USB 3.0 hubs don't need this code. They are level-triggered,
+not edge-triggered like xHCI, so they will continue to send interrupt
+events when any change bit is set. Therefore it doesn't make sense to
+put this code in the USB core.
+
+This patch is part of a series to fix several reports of infinite loops
+on device enumeration failure. This includes John, when he boots with
+a USB 3.0 device (Roseweil eusb3 enclosure) attached to his NEC 0.96
+host controller. The fix requires warm reset support, so it does not
+make sense to backport this patch to stable kernels without warm reset
+support.
+
+This patch should be backported to kernels as old as 3.2, contain the
+commit ID 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm
+reset logic"
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Reported-by: John Covici <covici at ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 63 ++++++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/host/xhci-hub.c | 31 ++++++++++++++++++++-
+ 2 files changed, 90 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -876,6 +876,60 @@ static int hub_hub_status(struct usb_hub
+ return ret;
+ }
+
++static int hub_set_port_link_state(struct usb_hub *hub, int port1,
++ unsigned int link_status)
++{
++ return set_port_feature(hub->hdev,
++ port1 | (link_status << 3),
++ USB_PORT_FEAT_LINK_STATE);
++}
++
++/*
++ * If USB 3.0 ports are placed into the Disabled state, they will no longer
++ * detect any device connects or disconnects. This is generally not what the
++ * USB core wants, since it expects a disabled port to produce a port status
++ * change event when a new device connects.
++ *
++ * Instead, set the link state to Disabled, wait for the link to settle into
++ * that state, clear any change bits, and then put the port into the RxDetect
++ * state.
++ */
++static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
++{
++ int ret;
++ int total_time;
++ u16 portchange, portstatus;
++
++ if (!hub_is_superspeed(hub->hdev))
++ return -EINVAL;
++
++ ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED);
++ if (ret) {
++ dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
++ port1, ret);
++ return ret;
++ }
++
++ /* Wait for the link to enter the disabled state. */
++ for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
++ ret = hub_port_status(hub, port1, &portstatus, &portchange);
++ if (ret < 0)
++ return ret;
++
++ if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
++ USB_SS_PORT_LS_SS_DISABLED)
++ break;
++ if (total_time >= HUB_DEBOUNCE_TIMEOUT)
++ break;
++ msleep(HUB_DEBOUNCE_STEP);
++ }
++ if (total_time >= HUB_DEBOUNCE_TIMEOUT)
++ dev_warn(hub->intfdev, "Could not disable port %d after %d ms\n",
++ port1, total_time);
++
++ return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
++}
++
+ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+ {
+ struct usb_device *hdev = hub->hdev;
+@@ -884,8 +938,13 @@ static int hub_port_disable(struct usb_h
+ if (hub->ports[port1 - 1]->child && set_state)
+ usb_set_device_state(hub->ports[port1 - 1]->child,
+ USB_STATE_NOTATTACHED);
+- if (!hub->error && !hub_is_superspeed(hub->hdev))
+- ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
++ if (!hub->error) {
++ if (hub_is_superspeed(hub->hdev))
++ ret = hub_usb3_port_disable(hub, port1);
++ else
++ ret = clear_port_feature(hdev, port1,
++ USB_PORT_FEAT_ENABLE);
++ }
+ if (ret)
+ dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
+ port1, ret);
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -761,12 +761,39 @@ int xhci_hub_control(struct usb_hcd *hcd
+ break;
+ case USB_PORT_FEAT_LINK_STATE:
+ temp = xhci_readl(xhci, port_array[wIndex]);
++
++ /* Disable port */
++ if (link_state == USB_SS_PORT_LS_SS_DISABLED) {
++ xhci_dbg(xhci, "Disable port %d\n", wIndex);
++ temp = xhci_port_state_to_neutral(temp);
++ /*
++ * Clear all change bits, so that we get a new
++ * connection event.
++ */
++ temp |= PORT_CSC | PORT_PEC | PORT_WRC |
++ PORT_OCC | PORT_RC | PORT_PLC |
++ PORT_CEC;
++ xhci_writel(xhci, temp | PORT_PE,
++ port_array[wIndex]);
++ temp = xhci_readl(xhci, port_array[wIndex]);
++ break;
++ }
++
++ /* Put link in RxDetect (enable port) */
++ if (link_state == USB_SS_PORT_LS_RX_DETECT) {
++ xhci_dbg(xhci, "Enable port %d\n", wIndex);
++ xhci_set_link_state(xhci, port_array, wIndex,
++ link_state);
++ temp = xhci_readl(xhci, port_array[wIndex]);
++ break;
++ }
++
+ /* Software should not attempt to set
+- * port link state above '5' (Rx.Detect) and the port
++ * port link state above '3' (U3) and the port
+ * must be enabled.
+ */
+ if ((temp & PORT_PE) == 0 ||
+- (link_state > USB_SS_PORT_LS_RX_DETECT)) {
++ (link_state > USB_SS_PORT_LS_U3)) {
+ xhci_warn(xhci, "Cannot set link state.\n");
+ goto error;
+ }
+From 77c7f072c87fa951e9a74805febf26466f31170c Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Wed, 14 Nov 2012 17:16:52 -0800
+Subject: USB: Increase reset timeout.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 77c7f072c87fa951e9a74805febf26466f31170c upstream.
+
+John's NEC 0.96 xHCI host controller needs a longer timeout for a warm
+reset to complete. The logs show it takes 650ms to complete the warm
+reset, so extend the hub reset timeout to 800ms to be on the safe side.
+
+This commit should be backported to kernels as old as 3.2, that contain
+the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine
+warm reset logic".
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Reported-by: John Covici <covici at ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2460,7 +2460,7 @@ static unsigned hub_is_wusb(struct usb_h
+ #define HUB_SHORT_RESET_TIME 10
+ #define HUB_BH_RESET_TIME 50
+ #define HUB_LONG_RESET_TIME 200
+-#define HUB_RESET_TIMEOUT 500
++#define HUB_RESET_TIMEOUT 800
+
+ static int hub_port_reset(struct usb_hub *hub, int port1,
+ struct usb_device *udev, unsigned int delay, bool warm);
+From 4f43447e62b37ee19c82a13f72f35b1ca60a74d3 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Thu, 15 Nov 2012 14:58:04 -0800
+Subject: USB: Ignore port state until reset completes.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 4f43447e62b37ee19c82a13f72f35b1ca60a74d3 upstream.
+
+The port reset code bails out early if the current connect status is
+cleared (device disconnected). If we're issuing a hot reset, it may
+also look at the link state before the reset is finished.
+
+Section 10.14.2.6 of the USB 3.0 spec says that when a port enters the
+Error state or Resetting state, the port connection bit retains the
+value from the previous state. Therefore we can't trust it until the
+reset finishes. Also, the xHCI spec section 4.19.1.2.5 says software
+shall ignore the link state while the port is resetting, as it can be in
+an unknown state.
+
+The port state during reset is also unknown for USB 2.0 hubs. The hub
+sends a reset signal by driving the bus into an SE0 state. This
+overwhelms the "connect" signal from the device, so the port can't tell
+whether anything is connected or not.
+
+Fix the port reset code to ignore the port link state and current
+connect bit until the reset finishes, and USB_PORT_STAT_RESET is
+cleared.
+
+Remove the check for USB_PORT_STAT_C_BH_RESET in the warm reset case,
+because it's redundant. When the warm reset finishes, the port reset
+bit will be cleared at the same time USB_PORT_STAT_C_BH_RESET is set.
+Remove the now-redundant check for a cleared USB_PORT_STAT_RESET bit
+in the code to deal with the finished reset.
+
+This patch should be backported to all stable kernels.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2495,6 +2495,10 @@ static int hub_port_wait_reset(struct us
+ if (ret < 0)
+ return ret;
+
++ /* The port state is unknown until the reset completes. */
++ if ((portstatus & USB_PORT_STAT_RESET))
++ goto delay;
++
+ /*
+ * Some buggy devices require a warm reset to be issued even
+ * when the port appears not to be connected.
+@@ -2540,11 +2544,7 @@ static int hub_port_wait_reset(struct us
+ if ((portchange & USB_PORT_STAT_C_CONNECTION))
+ return -ENOTCONN;
+
+- /* if we`ve finished resetting, then break out of
+- * the loop
+- */
+- if (!(portstatus & USB_PORT_STAT_RESET) &&
+- (portstatus & USB_PORT_STAT_ENABLE)) {
++ if ((portstatus & USB_PORT_STAT_ENABLE)) {
+ if (hub_is_wusb(hub))
+ udev->speed = USB_SPEED_WIRELESS;
+ else if (hub_is_superspeed(hub->hdev))
+@@ -2558,10 +2558,10 @@ static int hub_port_wait_reset(struct us
+ return 0;
+ }
+ } else {
+- if (portchange & USB_PORT_STAT_C_BH_RESET)
+- return 0;
++ return 0;
+ }
+
++delay:
+ /* switch to the long delay after two short delay failures */
+ if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
+ delay = HUB_LONG_RESET_TIME;
+From 65bdac5effd15d6af619b3b7218627ef4d84ed6a Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Wed, 14 Nov 2012 17:58:04 -0800
+Subject: USB: Handle warm reset failure on empty port.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 65bdac5effd15d6af619b3b7218627ef4d84ed6a upstream.
+
+An empty port can transition to either Inactive or Compliance Mode if a
+newly connected USB 3.0 device fails to link train. In that case, we
+issue a warm reset. Some devices, such as John's Roseweil eusb3
+enclosure, slip back into Compliance Mode after the warm reset.
+
+The current warm reset code does not check for device connect status on
+warm reset completion, and it incorrectly reports the warm reset
+succeeded. This causes the USB core to attempt to send a Set Address
+control transfer to a port in Compliance Mode, which will always fail.
+
+Make hub_port_wait_reset check the current connect status and link state
+after the warm reset completes. Return a failure status if the device
+is disconnected or the link state is Compliance Mode or SS.Inactive.
+
+Make hub_events disable the port if warm reset fails. This will disable
+the port, and then bring it back into the RxDetect state. Make the USB
+core ignore the connect change until the device reconnects.
+
+Note that this patch does NOT handle connected devices slipping into the
+Inactive state very well. This is a concern, because devices can go
+into the Inactive state on U1/U2 exit failure. However, the fix for
+that case is too large for stable, so it will be submitted in a separate
+patch.
+
+This patch should be backported to kernels as old as 3.2, contain the
+commit ID 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore: refine warm
+reset logic"
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Reported-by: John Covici <covici at ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2558,6 +2558,11 @@ static int hub_port_wait_reset(struct us
+ return 0;
+ }
+ } else {
++ if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
++ hub_port_warm_reset_required(hub,
++ portstatus))
++ return -ENOTCONN;
++
+ return 0;
+ }
+
+@@ -4628,9 +4633,14 @@ static void hub_events(void)
+ * SS.Inactive state.
+ */
+ if (hub_port_warm_reset_required(hub, portstatus)) {
++ int status;
++
+ dev_dbg(hub_dev, "warm reset port %d\n", i);
+- hub_port_reset(hub, i, NULL,
++ status = hub_port_reset(hub, i, NULL,
+ HUB_BH_RESET_TIME, true);
++ if (status < 0)
++ hub_port_disable(hub, i, 1);
++ connect_change = 0;
+ }
+
+ if (connect_change)
+From c52804a472649b2e5005342308739434cbd51119 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Tue, 27 Nov 2012 12:30:23 -0800
+Subject: xhci: Avoid "dead ports", add roothub port polling.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit c52804a472649b2e5005342308739434cbd51119 upstream.
+
+The USB core hub thread (khubd) is designed with external USB hubs in
+mind. It expects that if a port status change bit is set, the hub will
+continue to send a notification through the hub status data transfer.
+Basically, it expects hub notifications to be level-triggered.
+
+The xHCI host controller is designed to be edge-triggered on the logical
+'OR' of all the port status change bits. When all port status change
+bits are clear, and a new change bit is set, the xHC will generate a
+Port Status Change Event. If another change bit is set in the same port
+status register before the first bit is cleared, it will not send
+another event.
+
+This means that the hub code may lose port status changes because of
+race conditions between clearing change bits. The user sees this as a
+"dead port" that doesn't react to device connects.
+
+The fix is to turn on port polling whenever a new change bit is set.
+Once the USB core issues a hub status request that shows that no change
+bits are set in any USB ports, turn off port polling.
+
+We can't allow the USB core to poll the roothub for port events during
+host suspend because if the PCI host is in D3cold, the port registers
+will be all f's. Instead, stop the port polling timer, and
+unconditionally restart it when the host resumes. If there are no port
+change bits set after the resume, the first call to hub_status_data will
+disable polling.
+
+This patch should be backported to stable kernels with the first xHCI
+support, 2.6.31 and newer, that include the commit
+0f2a79300a1471cf92ab43af165ea13555c8b0a5 "USB: xhci: Root hub support."
+There will be merge conflicts because the check for HC_STATE_SUSPENDED
+was moved into xhci_suspend in 3.8.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-hub.c | 7 +++++++
+ drivers/usb/host/xhci-ring.c | 9 +++++++++
+ drivers/usb/host/xhci.c | 10 ++++++++++
+ 3 files changed, 26 insertions(+)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -984,6 +984,7 @@ int xhci_hub_status_data(struct usb_hcd
+ int max_ports;
+ __le32 __iomem **port_array;
+ struct xhci_bus_state *bus_state;
++ bool reset_change = false;
+
+ max_ports = xhci_get_ports(hcd, &port_array);
+ bus_state = &xhci->bus_state[hcd_index(hcd)];
+@@ -1015,6 +1016,12 @@ int xhci_hub_status_data(struct usb_hcd
+ buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
+ status = 1;
+ }
++ if ((temp & PORT_RC))
++ reset_change = true;
++ }
++ if (!status && !reset_change) {
++ xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
++ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+ }
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return status ? retval : 0;
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1725,6 +1725,15 @@ cleanup:
+ if (bogus_port_status)
+ return;
+
++ /*
++ * xHCI port-status-change events occur when the "or" of all the
++ * status-change bits in the portsc register changes from 0 to 1.
++ * New status changes won't cause an event if any other change
++ * bits are still set. When an event occurs, switch over to
++ * polling to avoid losing status changes.
++ */
++ xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
++ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+ spin_unlock(&xhci->lock);
+ /* Pass this up to the core */
+ usb_hcd_poll_rh_status(hcd);
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -880,6 +880,11 @@ int xhci_suspend(struct xhci_hcd *xhci)
+ struct usb_hcd *hcd = xhci_to_hcd(xhci);
+ u32 command;
+
++ /* Don't poll the roothubs on bus suspend. */
++ xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
++ clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
++ del_timer_sync(&hcd->rh_timer);
++
+ spin_lock_irq(&xhci->lock);
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
+@@ -1064,6 +1069,11 @@ int xhci_resume(struct xhci_hcd *xhci, b
+ if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+ compliance_mode_recovery_timer_init(xhci);
+
++ /* Re-enable port polling. */
++ xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
++ set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
++ usb_hcd_poll_rh_status(hcd);
++
+ return retval;
+ }
+ #endif /* CONFIG_PM */
+From 07e72b95f5038cc82304b9a4a2eb7f9fc391ea68 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oliver at neukum.org>
+Date: Thu, 29 Nov 2012 15:05:57 +0100
+Subject: USB: hub: handle claim of enabled remote wakeup after reset
+
+From: Oliver Neukum <oliver at neukum.org>
+
+commit 07e72b95f5038cc82304b9a4a2eb7f9fc391ea68 upstream.
+
+Some touchscreens have buggy firmware which claims
+remote wakeup to be enabled after a reset. They nevertheless
+crash if the feature is cleared by the host.
+Add a check for reset resume before checking for
+an enabled remote wakeup feature. On compliant
+devices the feature must be cleared after a reset anyway.
+
+Signed-off-by: Oliver Neukum <oneukum at suse.de>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/core/hub.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2960,7 +2960,7 @@ int usb_port_suspend(struct usb_device *
+ static int finish_port_resume(struct usb_device *udev)
+ {
+ int status = 0;
+- u16 devstatus;
++ u16 devstatus = 0;
+
+ /* caller owns the udev device lock */
+ dev_dbg(&udev->dev, "%s\n",
+@@ -3005,7 +3005,13 @@ static int finish_port_resume(struct usb
+ if (status) {
+ dev_dbg(&udev->dev, "gone after usb resume? status %d\n",
+ status);
+- } else if (udev->actconfig) {
++ /*
++ * There are a few quirky devices which violate the standard
++ * by claiming to have remote wakeup enabled after a reset,
++ * which crash if the feature is cleared, hence check for
++ * udev->reset_resume
++ */
++ } else if (udev->actconfig && !udev->reset_resume) {
+ le16_to_cpus(&devstatus);
+ if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) {
+ status = usb_control_msg(udev,
+From 55c1945edaac94c5338a3647bc2e85ff75d9cf36 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Date: Mon, 17 Dec 2012 14:12:35 -0800
+Subject: xhci: Handle HS bulk/ctrl endpoints that don't NAK.
+
+From: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+
+commit 55c1945edaac94c5338a3647bc2e85ff75d9cf36 upstream.
+
+A high speed control or bulk endpoint may have bInterval set to zero,
+which means it does not NAK. If bInterval is non-zero, it means the
+endpoint NAKs at a rate of 2^(bInterval - 1).
+
+The xHCI code to compute the NAK interval does not handle the special
+case of zero properly. The current code unconditionally subtracts one
+from bInterval and uses it as an exponent. This causes a very large
+bInterval to be used, and warning messages like these will be printed:
+
+usb 1-1: ep 0x1 - rounding interval to 32768 microframes, ep desc says 0 microframes
+
+This may cause the xHCI host hardware to reject the Configure Endpoint
+command, which means the HS device will be unusable under xHCI ports.
+
+This patch should be backported to kernels as old as 2.6.31, that contain
+commit dfa49c4ad120a784ef1ff0717168aa79f55a483a "USB: xhci - fix math in
+xhci_get_endpoint_interval()".
+
+Reported-by: Vincent Pelletier <plr.vincent at gmail.com>
+Suggested-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Sarah Sharp <sarah.a.sharp at linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/host/xhci-mem.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -1250,6 +1250,8 @@ static unsigned int xhci_microframes_to_
+ static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+ {
++ if (ep->desc.bInterval == 0)
++ return 0;
+ return xhci_microframes_to_exponent(udev, ep,
+ ep->desc.bInterval, 0, 15);
+ }
+From 75e1a2ae1f61ce1ae640410ba757bba84bd9fefe Mon Sep 17 00:00:00 2001
+From: Jan Beulich <JBeulich at suse.com>
+Date: Wed, 19 Dec 2012 16:15:56 +0000
+Subject: USB: ehci: make debug port in-use detection functional again
+
+From: Jan Beulich <JBeulich at suse.com>
+
+commit 75e1a2ae1f61ce1ae640410ba757bba84bd9fefe upstream.
+
+Debug port in-use determination must be done before the controller gets
+reset the first time, i.e. before the call to ehci_setup() as of commit
+1a49e2ac9651df7349867a5cf44e2c83de1046af. That commit effectively
+rendered commit 9fa5780beea1274d498a224822397100022da7d4 useless.
+
+While moving that code around, also fix the BAR determination - the
+respective capability field is a 3- rather than a 2-bit one -, and use
+PCI_CAP_ID_DBG instead of the literal 0x0a.
+
+It's unclear to me whether the debug port functionality is important
+enough to warrant fixing this in stable kernels too.
+
+Signed-off-by: Jan Beulich <jbeulich at suse.com>
+Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Acked-by: Alan Stern <stern at rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/usb/host/ehci-pci.c | 39 ++++++++++++++++++++-------------------
+ 1 file changed, 20 insertions(+), 19 deletions(-)
+
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -192,6 +192,26 @@ static int ehci_pci_setup(struct usb_hcd
+ break;
+ }
+
++ /* optional debug port, normally in the first BAR */
++ temp = pci_find_capability(pdev, PCI_CAP_ID_DBG);
++ if (temp) {
++ pci_read_config_dword(pdev, temp, &temp);
++ temp >>= 16;
++ if (((temp >> 13) & 7) == 1) {
++ u32 hcs_params = ehci_readl(ehci,
++ &ehci->caps->hcs_params);
++
++ temp &= 0x1fff;
++ ehci->debug = hcd->regs + temp;
++ temp = ehci_readl(ehci, &ehci->debug->control);
++ ehci_info(ehci, "debug port %d%s\n",
++ HCS_DEBUG_PORT(hcs_params),
++ (temp & DBGP_ENABLED) ? " IN USE" : "");
++ if (!(temp & DBGP_ENABLED))
++ ehci->debug = NULL;
++ }
++ }
++
+ retval = ehci_setup(hcd);
+ if (retval)
+ return retval;
+@@ -226,25 +246,6 @@ static int ehci_pci_setup(struct usb_hcd
+ break;
+ }
+
+- /* optional debug port, normally in the first BAR */
+- temp = pci_find_capability(pdev, 0x0a);
+- if (temp) {
+- pci_read_config_dword(pdev, temp, &temp);
+- temp >>= 16;
+- if ((temp & (3 << 13)) == (1 << 13)) {
+- temp &= 0x1fff;
+- ehci->debug = hcd->regs + temp;
+- temp = ehci_readl(ehci, &ehci->debug->control);
+- ehci_info(ehci, "debug port %d%s\n",
+- HCS_DEBUG_PORT(ehci->hcs_params),
+- (temp & DBGP_ENABLED)
+- ? " IN USE"
+- : "");
+- if (!(temp & DBGP_ENABLED))
+- ehci->debug = NULL;
+- }
+- }
+-
+ /* at least the Genesys GL880S needs fixup here */
+ temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
+ temp &= 0x0f;
+From bc3b7756b5ff66828acf7bc24f148d28b8d61108 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Fri, 28 Dec 2012 17:09:03 +0800
+Subject: regulator: max8997: Use uV in voltage_map_desc
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit bc3b7756b5ff66828acf7bc24f148d28b8d61108 upstream.
+
+Current code does integer division (min_vol = min_uV / 1000) before pass
+min_vol to max8997_get_voltage_proper_val().
+So it is possible min_vol is truncated to a smaller value.
+
+For example, if the request min_uV is 800900 for ldo.
+min_vol = 800900 / 1000 = 800 (mV)
+Then max8997_get_voltage_proper_val returns 800 mV for this case which is lower
+than the requested voltage.
+
+Use uV rather than mV in voltage_map_desc to prevent truncation by integer
+division.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/regulator/max8997.c | 36 +++++++++++++++++-------------------
+ 1 file changed, 17 insertions(+), 19 deletions(-)
+
+--- a/drivers/regulator/max8997.c
++++ b/drivers/regulator/max8997.c
+@@ -69,26 +69,26 @@ struct voltage_map_desc {
+ int step;
+ };
+
+-/* Voltage maps in mV */
++/* Voltage maps in uV */
+ static const struct voltage_map_desc ldo_voltage_map_desc = {
+- .min = 800, .max = 3950, .step = 50,
++ .min = 800000, .max = 3950000, .step = 50000,
+ }; /* LDO1 ~ 18, 21 all */
+
+ static const struct voltage_map_desc buck1245_voltage_map_desc = {
+- .min = 650, .max = 2225, .step = 25,
++ .min = 650000, .max = 2225000, .step = 25000,
+ }; /* Buck1, 2, 4, 5 */
+
+ static const struct voltage_map_desc buck37_voltage_map_desc = {
+- .min = 750, .max = 3900, .step = 50,
++ .min = 750000, .max = 3900000, .step = 50000,
+ }; /* Buck3, 7 */
+
+-/* current map in mA */
++/* current map in uA */
+ static const struct voltage_map_desc charger_current_map_desc = {
+- .min = 200, .max = 950, .step = 50,
++ .min = 200000, .max = 950000, .step = 50000,
+ };
+
+ static const struct voltage_map_desc topoff_current_map_desc = {
+- .min = 50, .max = 200, .step = 10,
++ .min = 50000, .max = 200000, .step = 10000,
+ };
+
+ static const struct voltage_map_desc *reg_voltage_map[] = {
+@@ -192,7 +192,7 @@ static int max8997_list_voltage(struct r
+ if (val > desc->max)
+ return -EINVAL;
+
+- return val * 1000;
++ return val;
+ }
+
+ static int max8997_get_enable_register(struct regulator_dev *rdev,
+@@ -483,7 +483,6 @@ static int max8997_set_voltage_ldobuck(s
+ {
+ struct max8997_data *max8997 = rdev_get_drvdata(rdev);
+ struct i2c_client *i2c = max8997->iodev->i2c;
+- int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+ const struct voltage_map_desc *desc;
+ int rid = rdev_get_id(rdev);
+ int i, reg, shift, mask, ret;
+@@ -507,7 +506,7 @@ static int max8997_set_voltage_ldobuck(s
+
+ desc = reg_voltage_map[rid];
+
+- i = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
++ i = max8997_get_voltage_proper_val(desc, min_uV, max_uV);
+ if (i < 0)
+ return i;
+
+@@ -555,7 +554,7 @@ static int max8997_set_voltage_ldobuck_t
+ case MAX8997_BUCK4:
+ case MAX8997_BUCK5:
+ return DIV_ROUND_UP(desc->step * (new_selector - old_selector),
+- max8997->ramp_delay);
++ max8997->ramp_delay * 1000);
+ }
+
+ return 0;
+@@ -654,7 +653,6 @@ static int max8997_set_voltage_buck(stru
+ const struct voltage_map_desc *desc;
+ int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
+ bool gpio_dvs_mode = false;
+- int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+
+ if (rid < MAX8997_BUCK1 || rid > MAX8997_BUCK7)
+ return -EINVAL;
+@@ -679,7 +677,7 @@ static int max8997_set_voltage_buck(stru
+ selector);
+
+ desc = reg_voltage_map[rid];
+- new_val = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
++ new_val = max8997_get_voltage_proper_val(desc, min_uV, max_uV);
+ if (new_val < 0)
+ return new_val;
+
+@@ -977,8 +975,8 @@ static __devinit int max8997_pmic_probe(
+ max8997->buck1_vol[i] = ret =
+ max8997_get_voltage_proper_val(
+ &buck1245_voltage_map_desc,
+- pdata->buck1_voltage[i] / 1000,
+- pdata->buck1_voltage[i] / 1000 +
++ pdata->buck1_voltage[i],
++ pdata->buck1_voltage[i] +
+ buck1245_voltage_map_desc.step);
+ if (ret < 0)
+ goto err_out;
+@@ -986,8 +984,8 @@ static __devinit int max8997_pmic_probe(
+ max8997->buck2_vol[i] = ret =
+ max8997_get_voltage_proper_val(
+ &buck1245_voltage_map_desc,
+- pdata->buck2_voltage[i] / 1000,
+- pdata->buck2_voltage[i] / 1000 +
++ pdata->buck2_voltage[i],
++ pdata->buck2_voltage[i] +
+ buck1245_voltage_map_desc.step);
+ if (ret < 0)
+ goto err_out;
+@@ -995,8 +993,8 @@ static __devinit int max8997_pmic_probe(
+ max8997->buck5_vol[i] = ret =
+ max8997_get_voltage_proper_val(
+ &buck1245_voltage_map_desc,
+- pdata->buck5_voltage[i] / 1000,
+- pdata->buck5_voltage[i] / 1000 +
++ pdata->buck5_voltage[i],
++ pdata->buck5_voltage[i] +
+ buck1245_voltage_map_desc.step);
+ if (ret < 0)
+ goto err_out;
+From adf6178ad5552a7f2f742a8c85343c50f080c412 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Fri, 28 Dec 2012 17:10:20 +0800
+Subject: regulator: max8998: Use uV in voltage_map_desc
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit adf6178ad5552a7f2f742a8c85343c50f080c412 upstream.
+
+Integer division may truncate.
+This happens when pdata->buckx_voltagex setting is not align with 1000 uV.
+Thus use uV in voltage_map_desc, this ensures the selected voltage won't less
+than pdata buckx_voltagex settings.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/regulator/max8998.c | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -51,39 +51,39 @@ struct voltage_map_desc {
+ int step;
+ };
+
+-/* Voltage maps */
++/* Voltage maps in uV*/
+ static const struct voltage_map_desc ldo23_voltage_map_desc = {
+- .min = 800, .step = 50, .max = 1300,
++ .min = 800000, .step = 50000, .max = 1300000,
+ };
+ static const struct voltage_map_desc ldo456711_voltage_map_desc = {
+- .min = 1600, .step = 100, .max = 3600,
++ .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc ldo8_voltage_map_desc = {
+- .min = 3000, .step = 100, .max = 3600,
++ .min = 3000000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc ldo9_voltage_map_desc = {
+- .min = 2800, .step = 100, .max = 3100,
++ .min = 2800000, .step = 100000, .max = 3100000,
+ };
+ static const struct voltage_map_desc ldo10_voltage_map_desc = {
+- .min = 950, .step = 50, .max = 1300,
++ .min = 95000, .step = 50000, .max = 1300000,
+ };
+ static const struct voltage_map_desc ldo1213_voltage_map_desc = {
+- .min = 800, .step = 100, .max = 3300,
++ .min = 800000, .step = 100000, .max = 3300000,
+ };
+ static const struct voltage_map_desc ldo1415_voltage_map_desc = {
+- .min = 1200, .step = 100, .max = 3300,
++ .min = 1200000, .step = 100000, .max = 3300000,
+ };
+ static const struct voltage_map_desc ldo1617_voltage_map_desc = {
+- .min = 1600, .step = 100, .max = 3600,
++ .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc buck12_voltage_map_desc = {
+- .min = 750, .step = 25, .max = 1525,
++ .min = 750000, .step = 25000, .max = 1525000,
+ };
+ static const struct voltage_map_desc buck3_voltage_map_desc = {
+- .min = 1600, .step = 100, .max = 3600,
++ .min = 1600000, .step = 100000, .max = 3600000,
+ };
+ static const struct voltage_map_desc buck4_voltage_map_desc = {
+- .min = 800, .step = 100, .max = 2300,
++ .min = 800000, .step = 100000, .max = 2300000,
+ };
+
+ static const struct voltage_map_desc *ldo_voltage_map[] = {
+@@ -445,7 +445,7 @@ static int max8998_set_voltage_buck_time
+ if (max8998->iodev->type == TYPE_MAX8998 && !(val & MAX8998_ENRAMP))
+ return 0;
+
+- difference = (new_selector - old_selector) * desc->step;
++ difference = (new_selector - old_selector) * desc->step / 1000;
+ if (difference > 0)
+ return difference / ((val & 0x0f) + 1);
+
+@@ -702,7 +702,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck1_voltage1 / 1000))
++ < pdata->buck1_voltage1)
+ i++;
+ max8998->buck1_vol[0] = i;
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
+@@ -713,7 +713,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck1_voltage2 / 1000))
++ < pdata->buck1_voltage2)
+ i++;
+
+ max8998->buck1_vol[1] = i;
+@@ -725,7 +725,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck1_voltage3 / 1000))
++ < pdata->buck1_voltage3)
+ i++;
+
+ max8998->buck1_vol[2] = i;
+@@ -737,7 +737,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck1_voltage4 / 1000))
++ < pdata->buck1_voltage4)
+ i++;
+
+ max8998->buck1_vol[3] = i;
+@@ -763,7 +763,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck2_voltage1 / 1000))
++ < pdata->buck2_voltage1)
+ i++;
+ max8998->buck2_vol[0] = i;
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
+@@ -774,7 +774,7 @@ static __devinit int max8998_pmic_probe(
+ i = 0;
+ while (buck12_voltage_map_desc.min +
+ buck12_voltage_map_desc.step*i
+- < (pdata->buck2_voltage2 / 1000))
++ < pdata->buck2_voltage2)
+ i++;
+ max8998->buck2_vol[1] = i;
+ ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
+@@ -792,8 +792,8 @@ static __devinit int max8998_pmic_probe(
+ int count = (desc->max - desc->min) / desc->step + 1;
+
+ regulators[index].n_voltages = count;
+- regulators[index].min_uV = desc->min * 1000;
+- regulators[index].uV_step = desc->step * 1000;
++ regulators[index].min_uV = desc->min;
++ regulators[index].uV_step = desc->step;
+ }
+
+ config.dev = max8998->dev;
+From 81d0a6ae7befb24c06f4aa4856af7f8d1f612171 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin at ingics.com>
+Date: Wed, 9 Jan 2013 19:34:57 +0800
+Subject: regulator: max8998: Ensure enough delay time for max8998_set_voltage_buck_time_sel
+
+From: Axel Lin <axel.lin at ingics.com>
+
+commit 81d0a6ae7befb24c06f4aa4856af7f8d1f612171 upstream.
+
+Use DIV_ROUND_UP to prevent truncation by integer division issue.
+This ensures we return enough delay time.
+
+Signed-off-by: Axel Lin <axel.lin at ingics.com>
+Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/regulator/max8998.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/regulator/max8998.c
++++ b/drivers/regulator/max8998.c
+@@ -447,7 +447,7 @@ static int max8998_set_voltage_buck_time
+
+ difference = (new_selector - old_selector) * desc->step / 1000;
+ if (difference > 0)
+- return difference / ((val & 0x0f) + 1);
++ return DIV_ROUND_UP(difference, (val & 0x0f) + 1);
+
+ return 0;
+ }
+From 9120963578320532dfb3a9a7947e8d05b39900b5 Mon Sep 17 00:00:00 2001
+From: Ralf Baechle <ralf at linux-mips.org>
+Date: Thu, 20 Dec 2012 12:47:51 +0100
+Subject: Revert "MIPS: Optimise TLB handlers for MIPS32/64 R2 cores."
+
+From: Ralf Baechle <ralf at linux-mips.org>
+
+commit 9120963578320532dfb3a9a7947e8d05b39900b5 upstream.
+
+This reverts commit ff401e52100dcdc85e572d1ad376d3307b3fe28e.
+
+This breaks on MIPS64 R2 cores such as Broadcom's.
+
+Signed-off-by: Jayachandran C <jchandra at broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/mips/mm/tlbex.c | 16 ----------------
+ 1 file changed, 16 deletions(-)
+
+--- a/arch/mips/mm/tlbex.c
++++ b/arch/mips/mm/tlbex.c
+@@ -952,13 +952,6 @@ build_get_pgde32(u32 **p, unsigned int t
+ #endif
+ uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+-
+- if (cpu_has_mips_r2) {
+- uasm_i_ext(p, tmp, tmp, PGDIR_SHIFT, (32 - PGDIR_SHIFT));
+- uasm_i_ins(p, ptr, tmp, PGD_T_LOG2, (32 - PGDIR_SHIFT));
+- return;
+- }
+-
+ uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
+ uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
+ uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+@@ -994,15 +987,6 @@ static void __cpuinit build_adjust_conte
+
+ static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
+ {
+- if (cpu_has_mips_r2) {
+- /* PTE ptr offset is obtained from BadVAddr */
+- UASM_i_MFC0(p, tmp, C0_BADVADDR);
+- UASM_i_LW(p, ptr, 0, ptr);
+- uasm_i_ext(p, tmp, tmp, PAGE_SHIFT+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+- uasm_i_ins(p, ptr, tmp, PTE_T_LOG2+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+- return;
+- }
+-
+ /*
+ * Bug workaround for the Nevada. It seems as if under certain
+ * circumstances the move from cp0_context might produce a
+From e8088073c9610af017fd47fddd104a2c3afb32e8 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt at redhat.com>
+Date: Fri, 21 Dec 2012 20:23:31 +0000
+Subject: dm thin: fix race between simultaneous io and discards to same block
+
+From: Joe Thornber <ejt at redhat.com>
+
+commit e8088073c9610af017fd47fddd104a2c3afb32e8 upstream.
+
+There is a race when discard bios and non-discard bios are issued
+simultaneously to the same block.
+
+Discard support is expensive for all thin devices precisely because you
+have to be careful to quiesce the area you're discarding. DM thin must
+handle this conflicting IO pattern (simultaneous non-discard vs discard)
+even though a sane application shouldn't be issuing such IO.
+
+The race manifests as follows:
+
+1. A non-discard bio is mapped in thin_bio_map.
+ This doesn't lock out parallel activity to the same block.
+
+2. A discard bio is issued to the same block as the non-discard bio.
+
+3. The discard bio is locked in a dm_bio_prison_cell in process_discard
+ to lock out parallel activity against the same block.
+
+4. The non-discard bio's mapping continues and its all_io_entry is
+ incremented so the bio is accounted for in the thin pool's all_io_ds
+ which is a dm_deferred_set used to track time locality of non-discard IO.
+
+5. The non-discard bio is finally locked in a dm_bio_prison_cell in
+ process_bio.
+
+The race can result in deadlock, leaving the block layer hanging waiting
+for completion of a discard bio that never completes, e.g.:
+
+INFO: task ruby:15354 blocked for more than 120 seconds.
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+ruby D ffffffff8160f0e0 0 15354 15314 0x00000000
+ ffff8802fb08bc58 0000000000000082 ffff8802fb08bfd8 0000000000012900
+ ffff8802fb08a010 0000000000012900 0000000000012900 0000000000012900
+ ffff8802fb08bfd8 0000000000012900 ffff8803324b9480 ffff88032c6f14c0
+Call Trace:
+ [<ffffffff814e5a19>] schedule+0x29/0x70
+ [<ffffffff814e3d85>] schedule_timeout+0x195/0x220
+ [<ffffffffa06b9bc1>] ? _dm_request+0x111/0x160 [dm_mod]
+ [<ffffffff814e589e>] wait_for_common+0x11e/0x190
+ [<ffffffff8107a170>] ? try_to_wake_up+0x2b0/0x2b0
+ [<ffffffff814e59ed>] wait_for_completion+0x1d/0x20
+ [<ffffffff81233289>] blkdev_issue_discard+0x219/0x260
+ [<ffffffff81233e79>] blkdev_ioctl+0x6e9/0x7b0
+ [<ffffffff8119a65c>] block_ioctl+0x3c/0x40
+ [<ffffffff8117539c>] do_vfs_ioctl+0x8c/0x340
+ [<ffffffff8119a547>] ? block_llseek+0x67/0xb0
+ [<ffffffff811756f1>] sys_ioctl+0xa1/0xb0
+ [<ffffffff810561f6>] ? sys_rt_sigprocmask+0x86/0xd0
+ [<ffffffff814ef099>] system_call_fastpath+0x16/0x1b
+
+The thinp-test-suite's test_discard_random_sectors reliably hits this
+deadlock on fast SSD storage.
+
+The fix for this race is that the all_io_entry for a bio must be
+incremented whilst the dm_bio_prison_cell is held for the bio's
+associated virtual and physical blocks. That cell locking wasn't
+occurring early enough in thin_bio_map. This patch fixes this.
+
+Care is taken to always call the new function inc_all_io_entry() with
+the relevant cells locked, but they are generally unlocked before
+calling issue() to try to avoid holding the cells locked across
+generic_submit_request.
+
+Also, now that thin_bio_map may lock bios in a cell, process_bio() is no
+longer the only thread that will do so. Because of this we must be sure
+to use cell_defer_except() to release all non-holder entries, that
+were added by the other thread, because they must be deferred.
+
+This patch depends on "dm thin: replace dm_cell_release_singleton with
+cell_defer_except".
+
+Signed-off-by: Joe Thornber <ejt at redhat.com>
+Signed-off-by: Mike Snitzer <snitzer at redhat.com>
+Signed-off-by: Alasdair G Kergon <agk at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/md/dm-thin.c | 84 +++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 59 insertions(+), 25 deletions(-)
+
+--- a/drivers/md/dm-thin.c
++++ b/drivers/md/dm-thin.c
+@@ -368,6 +368,17 @@ static int bio_triggers_commit(struct th
+ dm_thin_changed_this_transaction(tc->td);
+ }
+
++static void inc_all_io_entry(struct pool *pool, struct bio *bio)
++{
++ struct dm_thin_endio_hook *h;
++
++ if (bio->bi_rw & REQ_DISCARD)
++ return;
++
++ h = dm_get_mapinfo(bio)->ptr;
++ h->all_io_entry = dm_deferred_entry_inc(pool->all_io_ds);
++}
++
+ static void issue(struct thin_c *tc, struct bio *bio)
+ {
+ struct pool *pool = tc->pool;
+@@ -596,13 +607,15 @@ static void process_prepared_discard_pas
+ {
+ struct thin_c *tc = m->tc;
+
++ inc_all_io_entry(tc->pool, m->bio);
++ cell_defer_except(tc, m->cell);
++ cell_defer_except(tc, m->cell2);
++
+ if (m->pass_discard)
+ remap_and_issue(tc, m->bio, m->data_block);
+ else
+ bio_endio(m->bio, 0);
+
+- cell_defer_except(tc, m->cell);
+- cell_defer_except(tc, m->cell2);
+ mempool_free(m, tc->pool->mapping_pool);
+ }
+
+@@ -710,6 +723,7 @@ static void schedule_copy(struct thin_c
+ h->overwrite_mapping = m;
+ m->bio = bio;
+ save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
++ inc_all_io_entry(pool, bio);
+ remap_and_issue(tc, bio, data_dest);
+ } else {
+ struct dm_io_region from, to;
+@@ -779,6 +793,7 @@ static void schedule_zero(struct thin_c
+ h->overwrite_mapping = m;
+ m->bio = bio;
+ save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio);
++ inc_all_io_entry(pool, bio);
+ remap_and_issue(tc, bio, data_block);
+ } else {
+ int r;
+@@ -961,13 +976,15 @@ static void process_discard(struct thin_
+ wake_worker(pool);
+ }
+ } else {
++ inc_all_io_entry(pool, bio);
++ cell_defer_except(tc, cell);
++ cell_defer_except(tc, cell2);
++
+ /*
+ * The DM core makes sure that the discard doesn't span
+ * a block boundary. So we submit the discard of a
+ * partial block appropriately.
+ */
+- cell_defer_except(tc, cell);
+- cell_defer_except(tc, cell2);
+ if ((!lookup_result.shared) && pool->pf.discard_passdown)
+ remap_and_issue(tc, bio, lookup_result.block);
+ else
+@@ -1039,8 +1056,9 @@ static void process_shared_bio(struct th
+ struct dm_thin_endio_hook *h = dm_get_mapinfo(bio)->ptr;
+
+ h->shared_read_entry = dm_deferred_entry_inc(pool->shared_read_ds);
+-
++ inc_all_io_entry(pool, bio);
+ cell_defer_except(tc, cell);
++
+ remap_and_issue(tc, bio, lookup_result->block);
+ }
+ }
+@@ -1055,7 +1073,9 @@ static void provision_block(struct thin_
+ * Remap empty bios (flushes) immediately, without provisioning.
+ */
+ if (!bio->bi_size) {
++ inc_all_io_entry(tc->pool, bio);
+ cell_defer_except(tc, cell);
++
+ remap_and_issue(tc, bio, 0);
+ return;
+ }
+@@ -1110,26 +1130,22 @@ static void process_bio(struct thin_c *t
+ r = dm_thin_find_block(tc->td, block, 1, &lookup_result);
+ switch (r) {
+ case 0:
+- /*
+- * We can release this cell now. This thread is the only
+- * one that puts bios into a cell, and we know there were
+- * no preceding bios.
+- */
+- /*
+- * TODO: this will probably have to change when discard goes
+- * back in.
+- */
+- cell_defer_except(tc, cell);
+-
+- if (lookup_result.shared)
++ if (lookup_result.shared) {
+ process_shared_bio(tc, bio, block, &lookup_result);
+- else
++ cell_defer_except(tc, cell);
++ } else {
++ inc_all_io_entry(tc->pool, bio);
++ cell_defer_except(tc, cell);
++
+ remap_and_issue(tc, bio, lookup_result.block);
++ }
+ break;
+
+ case -ENODATA:
+ if (bio_data_dir(bio) == READ && tc->origin_dev) {
++ inc_all_io_entry(tc->pool, bio);
+ cell_defer_except(tc, cell);
++
+ remap_to_origin_and_issue(tc, bio);
+ } else
+ provision_block(tc, bio, block, cell);
+@@ -1155,8 +1171,10 @@ static void process_bio_read_only(struct
+ case 0:
+ if (lookup_result.shared && (rw == WRITE) && bio->bi_size)
+ bio_io_error(bio);
+- else
++ else {
++ inc_all_io_entry(tc->pool, bio);
+ remap_and_issue(tc, bio, lookup_result.block);
++ }
+ break;
+
+ case -ENODATA:
+@@ -1166,6 +1184,7 @@ static void process_bio_read_only(struct
+ }
+
+ if (tc->origin_dev) {
++ inc_all_io_entry(tc->pool, bio);
+ remap_to_origin_and_issue(tc, bio);
+ break;
+ }
+@@ -1346,7 +1365,7 @@ static struct dm_thin_endio_hook *thin_h
+
+ h->tc = tc;
+ h->shared_read_entry = NULL;
+- h->all_io_entry = bio->bi_rw & REQ_DISCARD ? NULL : dm_deferred_entry_inc(pool->all_io_ds);
++ h->all_io_entry = NULL;
+ h->overwrite_mapping = NULL;
+
+ return h;
+@@ -1363,6 +1382,8 @@ static int thin_bio_map(struct dm_target
+ dm_block_t block = get_bio_block(tc, bio);
+ struct dm_thin_device *td = tc->td;
+ struct dm_thin_lookup_result result;
++ struct dm_bio_prison_cell *cell1, *cell2;
++ struct dm_cell_key key;
+
+ map_context->ptr = thin_hook_bio(tc, bio);
+
+@@ -1399,12 +1420,25 @@ static int thin_bio_map(struct dm_target
+ * shared flag will be set in their case.
+ */
+ thin_defer_bio(tc, bio);
+- r = DM_MAPIO_SUBMITTED;
+- } else {
+- remap(tc, bio, result.block);
+- r = DM_MAPIO_REMAPPED;
++ return DM_MAPIO_SUBMITTED;
+ }
+- break;
++
++ build_virtual_key(tc->td, block, &key);
++ if (dm_bio_detain(tc->pool->prison, &key, bio, &cell1))
++ return DM_MAPIO_SUBMITTED;
++
++ build_data_key(tc->td, result.block, &key);
++ if (dm_bio_detain(tc->pool->prison, &key, bio, &cell2)) {
++ cell_defer_except(tc, cell1);
++ return DM_MAPIO_SUBMITTED;
++ }
++
++ inc_all_io_entry(tc->pool, bio);
++ cell_defer_except(tc, cell2);
++ cell_defer_except(tc, cell1);
++
++ remap(tc, bio, result.block);
++ return DM_MAPIO_REMAPPED;
+
+ case -ENODATA:
+ if (get_pool_mode(tc->pool) == PM_READ_ONLY) {
+From ab9d6e4ffe192427ce9e93d4f927b0faaa8a941e Mon Sep 17 00:00:00 2001
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+Date: Mon, 3 Dec 2012 12:59:04 +0100
+Subject: Revert: "rt2x00: Don't let mac80211 send a BAR when an AMPDU subframe fails"
+
+From: Stanislaw Gruszka <sgruszka at redhat.com>
+
+commit ab9d6e4ffe192427ce9e93d4f927b0faaa8a941e upstream.
+
+This revert:
+
+commit be03d4a45c09ee5100d3aaaedd087f19bc20d01f
+Author: Andreas Hartmann <andihartmann at 01019freenet.de>
+Date: Tue Apr 17 00:25:28 2012 +0200
+
+ rt2x00: Don't let mac80211 send a BAR when an AMPDU subframe fails
+
+To fix problem workaround by above commit use
+IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL flag (see change log for
+"mac80211: introduce IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL" patch).
+
+Resolve: https://bugzilla.kernel.org/show_bug.cgi?id=42828
+Bisected-by: Francisco Pina Martins <f.pinamartins at gmail.com>
+Signed-off-by: Stanislaw Gruszka <sgruszka at redhat.com>
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 3 ++-
+ drivers/net/wireless/rt2x00/rt2x00dev.c | 7 +++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -5036,7 +5036,8 @@ static int rt2800_probe_hw_mode(struct r
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_AMPDU_AGGREGATION |
+- IEEE80211_HW_REPORTS_TX_ACK_STATUS;
++ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
++ IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL;
+
+ /*
+ * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices
+--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
+@@ -391,10 +391,9 @@ void rt2x00lib_txdone(struct queue_entry
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
+ tx_info->status.ampdu_len = 1;
+ tx_info->status.ampdu_ack_len = success ? 1 : 0;
+- /*
+- * TODO: Need to tear down BA session here
+- * if not successful.
+- */
++
++ if (!success)
++ tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+ }
+
+ if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+From 311bd84247ee0bedae6cdfbfc5e2c3450f9decd1 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov at openvz.org>
+Date: Fri, 14 Dec 2012 15:03:10 +0400
+Subject: EDAC: Fix kernel panic on module unloading
+
+From: Konstantin Khlebnikov <khlebnikov at openvz.org>
+
+commit 311bd84247ee0bedae6cdfbfc5e2c3450f9decd1 upstream.
+
+This patch fixes use-after-free and double-free bugs in
+edac_mc_sysfs_exit(). mci_pdev has single reference and put_device()
+calls mc_attr_release() which calls kfree(). The following
+device_del() works with already released memory. An another kfree() in
+edac_mc_sysfs_exit() releses the same memory again. Great.
+
+Signed-off-by: Konstantin Khlebnikov <khlebnikov at openvz.org>
+Cc: Denis Kirjanov <kirjanov at gmail.com>
+Cc: Mauro Carvalho Chehab <mchehab at redhat.com>
+Link: http://lkml.kernel.org/r/20121214110310.11019.21098.stgit@zurg
+Signed-off-by: Borislav Petkov <bp at alien8.de>
+[ a partial 3.7.y backport ]
+Signed-off-by: Borislav Petkov <bp at suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/edac/edac_mc_sysfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/edac/edac_mc_sysfs.c
++++ b/drivers/edac/edac_mc_sysfs.c
+@@ -1145,7 +1145,7 @@ int __init edac_mc_sysfs_init(void)
+
+ void __exit edac_mc_sysfs_exit(void)
+ {
+- put_device(mci_pdev);
+ device_del(mci_pdev);
++ put_device(mci_pdev);
+ edac_put_sysfs_subsys();
+ }
+From 539526b4137bc0e7a8806c38c8522f226814a0e6 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Sat, 8 Dec 2012 12:58:33 +0100
+Subject: drm/i915: disable cpt phase pointer fdi rx workaround
+
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+
+commit 539526b4137bc0e7a8806c38c8522f226814a0e6 upstream.
+
+We've originally added this in
+
+commit 291427f5fdadec6e4be2924172e83588880e1539
+Author: Jesse Barnes <jbarnes at virtuousgeek.org>
+Date: Fri Jul 29 12:42:37 2011 -0700
+
+ drm/i915: apply phase pointer override on SNB+ too
+
+and then copy-pasted it over to ivb/ppt. The w/a was originally added
+for ilk/ibx in
+
+commit 5b2adf897146edeac6a1e438fb67b5a53dbbdf34
+Author: Jesse Barnes <jbarnes at virtuousgeek.org>
+Date: Thu Oct 7 16:01:15 2010 -0700
+
+ drm/i915: add Ironlake clock gating workaround for FDI link training
+
+and fixed up a bit in
+
+commit 6f06ce184c765fd8d50669a8d12fdd566c920859
+Author: Jesse Barnes <jbarnes at virtuousgeek.org>
+Date: Tue Jan 4 15:09:38 2011 -0800
+
+ drm/i915: set phase sync pointer override enable before setting phase sync pointer
+
+It turns out that this w/a isn't actually required on cpt/ppt and
+positively harmful on ivb/ppt when using fdi B/C links - it results in
+a black screen occasionally, with seemingfully everything working as
+it should. The only failure indication I've found in the hw is that
+eventually (but not right after the modeset completes) a pipe underrun
+is signalled.
+
+Big thanks to Arthur Runyan for all the ideas for registers to check
+and changes to test, otherwise I couldn't ever have tracked this down!
+
+Cc: "Runyan, Arthur J" <arthur.j.runyan at intel.com>
+Cc: stable at vger.kernel.org
+Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: CAI Qian <caiqian at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 31 -------------------------------
+ 1 file changed, 31 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -2302,18 +2302,6 @@ static void intel_fdi_normal_train(struc
+ FDI_FE_ERRC_ENABLE);
+ }
+
+-static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe)
+-{
+- struct drm_i915_private *dev_priv = dev->dev_private;
+- u32 flags = I915_READ(SOUTH_CHICKEN1);
+-
+- flags |= FDI_PHASE_SYNC_OVR(pipe);
+- I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
+- flags |= FDI_PHASE_SYNC_EN(pipe);
+- I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
+- POSTING_READ(SOUTH_CHICKEN1);
+-}
+-
+ /* The FDI link training functions for ILK/Ibexpeak. */
+ static void ironlake_fdi_link_train(struct drm_crtc *crtc)
+ {
+@@ -2464,9 +2452,6 @@ static void gen6_fdi_link_train(struct d
+ POSTING_READ(reg);
+ udelay(150);
+
+- if (HAS_PCH_CPT(dev))
+- cpt_phase_pointer_enable(dev, pipe);
+-
+ for (i = 0; i < 4; i++) {
+ reg = FDI_TX_CTL(pipe);
+ temp = I915_READ(reg);
+@@ -2593,9 +2578,6 @@ static void ivb_manual_fdi_link_train(st
+ POSTING_READ(reg);
+ udelay(150);
+
+- if (HAS_PCH_CPT(dev))
+- cpt_phase_pointer_enable(dev, pipe);
+-
+ for (i = 0; i < 4; i++) {
+ reg = FDI_TX_CTL(pipe);
+ temp = I915_READ(reg);
+@@ -2737,17 +2719,6 @@ static void ironlake_fdi_pll_disable(str
+ udelay(100);
+ }
+
+-static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
+-{
+- struct drm_i915_private *dev_priv = dev->dev_private;
+- u32 flags = I915_READ(SOUTH_CHICKEN1);
+-
+- flags &= ~(FDI_PHASE_SYNC_EN(pipe));
+- I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */
+- flags &= ~(FDI_PHASE_SYNC_OVR(pipe));
+- I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */
+- POSTING_READ(SOUTH_CHICKEN1);
+-}
+ static void ironlake_fdi_disable(struct drm_crtc *crtc)
+ {
+ struct drm_device *dev = crtc->dev;
+@@ -2777,8 +2748,6 @@ static void ironlake_fdi_disable(struct
+ I915_WRITE(FDI_RX_CHICKEN(pipe),
+ I915_READ(FDI_RX_CHICKEN(pipe) &
+ ~FDI_RX_PHASE_SYNC_POINTER_EN));
+- } else if (HAS_PCH_CPT(dev)) {
+- cpt_phase_pointer_disable(dev, pipe);
+ }
+
+ /* still set train pattern 1 */
+From e43a028752fed049e4bd94ef895542f96d79fa74 Mon Sep 17 00:00:00 2001
+From: Alexander Graf <agraf at suse.de>
+Date: Sat, 6 Oct 2012 03:56:35 +0200
+Subject: KVM: PPC: 44x: fix DCR read/write
+
+From: Alexander Graf <agraf at suse.de>
+
+commit e43a028752fed049e4bd94ef895542f96d79fa74 upstream.
+
+When remembering the direction of a DCR transaction, we should write
+to the same variable that we interpret on later when doing vcpu_run
+again.
+
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: CAI Qian <caiqian at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ arch/powerpc/kvm/44x_emulate.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/powerpc/kvm/44x_emulate.c
++++ b/arch/powerpc/kvm/44x_emulate.c
+@@ -76,6 +76,7 @@ int kvmppc_core_emulate_op(struct kvm_ru
+ run->dcr.dcrn = dcrn;
+ run->dcr.data = 0;
+ run->dcr.is_write = 0;
++ vcpu->arch.dcr_is_write = 0;
+ vcpu->arch.io_gpr = rt;
+ vcpu->arch.dcr_needed = 1;
+ kvmppc_account_exit(vcpu, DCR_EXITS);
+@@ -94,6 +95,7 @@ int kvmppc_core_emulate_op(struct kvm_ru
+ run->dcr.dcrn = dcrn;
+ run->dcr.data = kvmppc_get_gpr(vcpu, rs);
+ run->dcr.is_write = 1;
++ vcpu->arch.dcr_is_write = 1;
+ vcpu->arch.dcr_needed = 1;
+ kvmppc_account_exit(vcpu, DCR_EXITS);
+ emulated = EMULATE_DO_DCR;
+From 3751809df766c05bcce372fcfa4a886b9aaca44b Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Fri, 7 Dec 2012 19:50:07 -0600
+Subject: libceph: socket can close in any connection state
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 7bb21d68c535ad8be38e14a715632ae398b37ac1)
+
+A connection's socket can close for any reason, independent of the
+state of the connection (and without irrespective of the connection
+mutex). As a result, the connectino can be in pretty much any state
+at the time its socket is closed.
+
+Handle those other cases at the top of con_work(). Pull this whole
+block of code into a separate function to reduce the clutter.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/messenger.c | 47 ++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 17 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -2262,6 +2262,35 @@ static void queue_con(struct ceph_connec
+ }
+ }
+
++static bool con_sock_closed(struct ceph_connection *con)
++{
++ if (!test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags))
++ return false;
++
++#define CASE(x) \
++ case CON_STATE_ ## x: \
++ con->error_msg = "socket closed (con state " #x ")"; \
++ break;
++
++ switch (con->state) {
++ CASE(CLOSED);
++ CASE(PREOPEN);
++ CASE(CONNECTING);
++ CASE(NEGOTIATING);
++ CASE(OPEN);
++ CASE(STANDBY);
++ default:
++ pr_warning("%s con %p unrecognized state %lu\n",
++ __func__, con, con->state);
++ con->error_msg = "unrecognized con state";
++ BUG();
++ break;
++ }
++#undef CASE
++
++ return true;
++}
++
+ /*
+ * Do some work on a connection. Drop a connection ref when we're done.
+ */
+@@ -2273,24 +2302,8 @@ static void con_work(struct work_struct
+
+ mutex_lock(&con->mutex);
+ restart:
+- if (test_and_clear_bit(CON_FLAG_SOCK_CLOSED, &con->flags)) {
+- switch (con->state) {
+- case CON_STATE_CONNECTING:
+- con->error_msg = "connection failed";
+- break;
+- case CON_STATE_NEGOTIATING:
+- con->error_msg = "negotiation failed";
+- break;
+- case CON_STATE_OPEN:
+- con->error_msg = "socket closed";
+- break;
+- default:
+- dout("unrecognized con state %d\n", (int)con->state);
+- con->error_msg = "unrecognized con state";
+- BUG();
+- }
++ if (con_sock_closed(con))
+ goto fault;
+- }
+
+ if (test_and_clear_bit(CON_FLAG_BACKOFF, &con->flags)) {
+ dout("con_work %p backing off\n", con);
+From 5f64737fb44ee280362a1be280f26adb38c689e4 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Fri, 14 Dec 2012 16:47:41 -0600
+Subject: libceph: report connection fault with warning
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 28362986f8743124b3a0fda20a8ed3e80309cce1)
+
+When a connection's socket disconnects, or if there's a protocol
+error of some kind on the connection, a fault is signaled and
+the connection is reset (closed and reopened, basically). We
+currently get an error message on the log whenever this occurs.
+
+A ceph connection will attempt to reestablish a socket connection
+repeatedly if a fault occurs. This means that these error messages
+will get repeatedly added to the log, which is undesirable.
+
+Change the error message to be a warning, so they don't get
+logged by default.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/messenger.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -2369,7 +2369,7 @@ fault:
+ static void ceph_fault(struct ceph_connection *con)
+ __releases(con->mutex)
+ {
+- pr_err("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
++ pr_warning("%s%lld %s %s\n", ENTITY_NAME(con->peer_name),
+ ceph_pr_addr(&con->peer_addr.in_addr), con->error_msg);
+ dout("fault %p state %lu to peer %s\n",
+ con, con->state, ceph_pr_addr(&con->peer_addr.in_addr));
+From d49d943a24d4addbb5c6d1e4feb45bb98b2885fa Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Thu, 6 Dec 2012 07:22:04 -0600
+Subject: libceph: init osd->o_node in create_osd()
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit f407731d12214e7686819018f3a1e9d7b6f83a02)
+
+The red-black node node in the ceph osd structure is not initialized
+in create_osd(). Because this node can be the subject of a
+RB_EMPTY_NODE() call later on, we should ensure the node is
+initialized properly for that. Add a call to RB_CLEAR_NODE()
+initialize it.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -647,6 +647,7 @@ static struct ceph_osd *create_osd(struc
+ atomic_set(&osd->o_ref, 1);
+ osd->o_osdc = osdc;
+ osd->o_osd = onum;
++ RB_CLEAR_NODE(&osd->o_node);
+ INIT_LIST_HEAD(&osd->o_requests);
+ INIT_LIST_HEAD(&osd->o_linger_requests);
+ INIT_LIST_HEAD(&osd->o_osd_lru);
+From b4c0c6243efad1ae18a8aa17694952fd6c13bbaa Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Mon, 17 Dec 2012 12:23:48 -0600
+Subject: libceph: init event->node in ceph_osdc_create_event()
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 3ee5234df68d253c415ba4f2db72ad250d9c21a9)
+
+The red-black node node in the ceph osd event structure is not
+initialized in create_osdc_create_event(). Because this node can
+be the subject of a RB_EMPTY_NODE() call later on, we should ensure
+the node is initialized properly for that.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1600,6 +1600,7 @@ int ceph_osdc_create_event(struct ceph_o
+ event->data = data;
+ event->osdc = osdc;
+ INIT_LIST_HEAD(&event->osd_node);
++ RB_CLEAR_NODE(&event->node);
+ kref_init(&event->kref); /* one ref for us */
+ kref_get(&event->kref); /* one ref for the caller */
+ init_completion(&event->completion);
+From f660813d76b3634c39c2b3ed8715af7e9db14f9c Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Mon, 17 Dec 2012 12:23:48 -0600
+Subject: libceph: don't use rb_init_node() in ceph_osdc_alloc_request()
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit a978fa20fb657548561dddbfb605fe43654f0825)
+
+The red-black node in the ceph osd request structure is initialized
+in ceph_osdc_alloc_request() using rbd_init_node(). We do need to
+initialize this, because in __unregister_request() we call
+RB_EMPTY_NODE(), which expects the node it's checking to have
+been initialized. But rb_init_node() is apparently overkill, and
+may in fact be on its way out. So use RB_CLEAR_NODE() instead.
+
+For a little more background, see this commit:
+ 4c199a93 rbtree: empty nodes have no color"
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -221,6 +221,7 @@ struct ceph_osd_request *ceph_osdc_alloc
+ kref_init(&req->r_kref);
+ init_completion(&req->r_completion);
+ init_completion(&req->r_safe_completion);
++ RB_CLEAR_NODE(&req->r_node);
+ INIT_LIST_HEAD(&req->r_unsafe_item);
+ INIT_LIST_HEAD(&req->r_linger_item);
+ INIT_LIST_HEAD(&req->r_linger_osd);
+From c9ddd2cac5e5e9bf278a9c08976592972a2d15c1 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Thu, 6 Dec 2012 07:22:04 -0600
+Subject: libceph: register request before unregister linger
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit c89ce05e0c5a01a256100ac6a6019f276bdd1ca6)
+
+In kick_requests(), we need to register the request before we
+unregister the linger request. Otherwise the unregister will
+reset the request's osd pointer to NULL.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1366,8 +1366,8 @@ static void kick_requests(struct ceph_os
+
+ dout("kicking lingering %p tid %llu osd%d\n", req, req->r_tid,
+ req->r_osd ? req->r_osd->o_osd : -1);
+- __unregister_linger_request(osdc, req);
+ __register_request(osdc, req);
++ __unregister_linger_request(osdc, req);
+ }
+ mutex_unlock(&osdc->request_mutex);
+
+From d92a42b79c755e911495bd36316d2573804293ea Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Wed, 19 Dec 2012 15:52:36 -0600
+Subject: libceph: move linger requests sooner in kick_requests()
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit ab60b16d3c31b9bd9fd5b39f97dc42c52a50b67d)
+
+The kick_requests() function is called by ceph_osdc_handle_map()
+when an osd map change has been indicated. Its purpose is to
+re-queue any request whose target osd is different from what it
+was when it was originally sent.
+
+It is structured as two loops, one for incomplete but registered
+requests, and a second for handling completed linger requests.
+As a special case, in the first loop if a request marked to linger
+has not yet completed, it is moved from the request list to the
+linger list. This is as a quick and dirty way to have the second
+loop handle sending the request along with all the other linger
+requests.
+
+Because of the way it's done now, however, this quick and dirty
+solution can result in these incomplete linger requests never
+getting re-sent as desired. The problem lies in the fact that
+the second loop only arranges for a linger request to be sent
+if it appears its target osd has changed. This is the proper
+handling for *completed* linger requests (it avoids issuing
+the same linger request twice to the same osd).
+
+But although the linger requests added to the list in the first loop
+may have been sent, they have not yet completed, so they need to be
+re-sent regardless of whether their target osd has changed.
+
+The first required fix is we need to avoid calling __map_request()
+on any incomplete linger request. Otherwise the subsequent
+__map_request() call in the second loop will find the target osd
+has not changed and will therefore not re-send the request.
+
+Second, we need to be sure that a sent but incomplete linger request
+gets re-sent. If the target osd is the same with the new osd map as
+it was when the request was originally sent, this won't happen.
+This can be fixed through careful handling when we move these
+requests from the request list to the linger list, by unregistering
+the request *before* it is registered as a linger request. This
+works because a side-effect of unregistering the request is to make
+the request's r_osd pointer be NULL, and *that* will ensure the
+second loop actually re-sends the linger request.
+
+Processing of such a request is done at that point, so continue with
+the next one once it's been moved.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 30 +++++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 11 deletions(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1322,6 +1322,24 @@ static void kick_requests(struct ceph_os
+ for (p = rb_first(&osdc->requests); p; ) {
+ req = rb_entry(p, struct ceph_osd_request, r_node);
+ p = rb_next(p);
++
++ /*
++ * For linger requests that have not yet been
++ * registered, move them to the linger list; they'll
++ * be sent to the osd in the loop below. Unregister
++ * the request before re-registering it as a linger
++ * request to ensure the __map_request() below
++ * will decide it needs to be sent.
++ */
++ if (req->r_linger && list_empty(&req->r_linger_item)) {
++ dout("%p tid %llu restart on osd%d\n",
++ req, req->r_tid,
++ req->r_osd ? req->r_osd->o_osd : -1);
++ __unregister_request(osdc, req);
++ __register_linger_request(osdc, req);
++ continue;
++ }
++
+ err = __map_request(osdc, req, force_resend);
+ if (err < 0)
+ continue; /* error */
+@@ -1336,17 +1354,6 @@ static void kick_requests(struct ceph_os
+ req->r_flags |= CEPH_OSD_FLAG_RETRY;
+ }
+ }
+- if (req->r_linger && list_empty(&req->r_linger_item)) {
+- /*
+- * register as a linger so that we will
+- * re-submit below and get a new tid
+- */
+- dout("%p tid %llu restart on osd%d\n",
+- req, req->r_tid,
+- req->r_osd ? req->r_osd->o_osd : -1);
+- __register_linger_request(osdc, req);
+- __unregister_request(osdc, req);
+- }
+ }
+
+ list_for_each_entry_safe(req, nreq, &osdc->req_linger,
+@@ -1354,6 +1361,7 @@ static void kick_requests(struct ceph_os
+ dout("linger req=%p req->r_osd=%p\n", req, req->r_osd);
+
+ err = __map_request(osdc, req, force_resend);
++ dout("__map_request returned %d\n", err);
+ if (err == 0)
+ continue; /* no change and no osd was specified */
+ if (err < 0)
+From 8cc1491a5d9e720f0b6f69244fc1548597bb868b Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Wed, 26 Dec 2012 14:31:40 -0600
+Subject: libceph: always reset osds when kicking
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit e6d50f67a6b1a6252a616e6e629473b5c4277218)
+
+When ceph_osdc_handle_map() is called to process a new osd map,
+kick_requests() is called to ensure all affected requests are
+updated if necessary to reflect changes in the osd map. This
+happens in two cases: whenever an incremental map update is
+processed; and when a full map update (or the last one if there is
+more than one) gets processed.
+
+In the former case, the kick_requests() call is followed immediately
+by a call to reset_changed_osds() to ensure any connections to osds
+affected by the map change are reset. But for full map updates
+this isn't done.
+
+Both cases should be doing this osd reset.
+
+Rather than duplicating the reset_changed_osds() call, move it into
+the end of kick_requests().
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -1308,7 +1308,7 @@ static void reset_changed_osds(struct ce
+ * Requeue requests whose mapping to an OSD has changed. If requests map to
+ * no osd, request a new map.
+ *
+- * Caller should hold map_sem for read and request_mutex.
++ * Caller should hold map_sem for read.
+ */
+ static void kick_requests(struct ceph_osd_client *osdc, int force_resend)
+ {
+@@ -1383,6 +1383,7 @@ static void kick_requests(struct ceph_os
+ dout("%d requests for down osds, need new map\n", needmap);
+ ceph_monc_request_next_osdmap(&osdc->client->monc);
+ }
++ reset_changed_osds(osdc);
+ }
+
+
+@@ -1439,7 +1440,6 @@ void ceph_osdc_handle_map(struct ceph_os
+ osdc->osdmap = newmap;
+ }
+ kick_requests(osdc, 0);
+- reset_changed_osds(osdc);
+ } else {
+ dout("ignoring incremental map %u len %d\n",
+ epoch, maplen);
+From b95ad0140dc8d2375bff4b0f30f6832cbb29e17c Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Wed, 26 Dec 2012 10:43:57 -0600
+Subject: libceph: WARN, don't BUG on unexpected connection states
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 122070a2ffc91f87fe8e8493eb0ac61986c5557c)
+
+A number of assertions in the ceph messenger are implemented with
+BUG_ON(), killing the system if connection's state doesn't match
+what's expected. At this point our state model is (evidently) not
+well understood enough for these assertions to trigger a BUG().
+Convert all BUG_ON(con->state...) calls to be WARN_ON(con->state...)
+so we learn about these issues without killing the machine.
+
+We now recognize that a connection fault can occur due to a socket
+closure at any time, regardless of the state of the connection. So
+there is really nothing we can assert about the state of the
+connection at that point so eliminate that assertion.
+
+Reported-by: Ugis <ugis22 at gmail.com>
+Tested-by: Ugis <ugis22 at gmail.com>
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/messenger.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -561,7 +561,7 @@ void ceph_con_open(struct ceph_connectio
+ mutex_lock(&con->mutex);
+ dout("con_open %p %s\n", con, ceph_pr_addr(&addr->in_addr));
+
+- BUG_ON(con->state != CON_STATE_CLOSED);
++ WARN_ON(con->state != CON_STATE_CLOSED);
+ con->state = CON_STATE_PREOPEN;
+
+ con->peer_name.type = (__u8) entity_type;
+@@ -1509,7 +1509,7 @@ static int process_banner(struct ceph_co
+ static void fail_protocol(struct ceph_connection *con)
+ {
+ reset_connection(con);
+- BUG_ON(con->state != CON_STATE_NEGOTIATING);
++ WARN_ON(con->state != CON_STATE_NEGOTIATING);
+ con->state = CON_STATE_CLOSED;
+ }
+
+@@ -1635,7 +1635,7 @@ static int process_connect(struct ceph_c
+ return -1;
+ }
+
+- BUG_ON(con->state != CON_STATE_NEGOTIATING);
++ WARN_ON(con->state != CON_STATE_NEGOTIATING);
+ con->state = CON_STATE_OPEN;
+
+ con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+@@ -2132,7 +2132,6 @@ more:
+ if (ret < 0)
+ goto out;
+
+- BUG_ON(con->state != CON_STATE_CONNECTING);
+ con->state = CON_STATE_NEGOTIATING;
+
+ /*
+@@ -2160,7 +2159,7 @@ more:
+ goto more;
+ }
+
+- BUG_ON(con->state != CON_STATE_OPEN);
++ WARN_ON(con->state != CON_STATE_OPEN);
+
+ if (con->in_base_pos < 0) {
+ /*
+@@ -2374,7 +2373,7 @@ static void ceph_fault(struct ceph_conne
+ dout("fault %p state %lu to peer %s\n",
+ con, con->state, ceph_pr_addr(&con->peer_addr.in_addr));
+
+- BUG_ON(con->state != CON_STATE_CONNECTING &&
++ WARN_ON(con->state != CON_STATE_CONNECTING &&
+ con->state != CON_STATE_NEGOTIATING &&
+ con->state != CON_STATE_OPEN);
+
+From 48e858340dae43189a4e55647f6eac736766f828 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Mon, 7 Jan 2013 10:27:13 +0100
+Subject: Revert "drm/i915: no lvds quirk for Zotac ZDBOX SD ID12/ID13"
+
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+
+commit 48e858340dae43189a4e55647f6eac736766f828 upstream.
+
+This reverts commit 9756fe38d10b2bf90c81dc4d2f17d5632e135364.
+
+The bogus lvds output is actually a lvds->hdmi bridge, which we don't
+really support. But unconditionally disabling it breaks some existing
+setups.
+
+Reported-by: John Tapsell <johnflux at gmail.com>
+References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/17237
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Cc: Luis Henriques <luis.henriques at canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+
+---
+ drivers/gpu/drm/i915/intel_lvds.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -763,14 +763,6 @@ static const struct dmi_system_id intel_
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
+- .ident = "ZOTAC ZBOXSD-ID12/ID13",
+- .matches = {
+- DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"),
+- DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),
+- },
+- },
+- {
+- .callback = intel_no_lvds_dmi_callback,
+ .ident = "Gigabyte GA-D525TUD",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
+From f10a18433a1b3192e71eecffeaeca5f5f1694016 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage at inktank.com>
+Date: Thu, 27 Dec 2012 20:27:04 -0600
+Subject: libceph: fix protocol feature mismatch failure path
+
+
+From: Sage Weil <sage at inktank.com>
+
+(cherry picked from commit 0fa6ebc600bc8e830551aee47a0e929e818a1868)
+
+We should not set con->state to CLOSED here; that happens in
+ceph_fault() in the caller, where it first asserts that the state
+is not yet CLOSED. Avoids a BUG when the features don't match.
+
+Since the fail_protocol() has become a trivial wrapper, replace
+calls to it with direct calls to reset_connection().
+
+Signed-off-by: Sage Weil <sage at inktank.com>
+Reviewed-by: Alex Elder <elder at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/messenger.c | 14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -506,6 +506,7 @@ static void reset_connection(struct ceph
+ {
+ /* reset connection, out_queue, msg_ and connect_seq */
+ /* discard existing out_queue and msg_seq */
++ dout("reset_connection %p\n", con);
+ ceph_msg_remove_list(&con->out_queue);
+ ceph_msg_remove_list(&con->out_sent);
+
+@@ -1506,13 +1507,6 @@ static int process_banner(struct ceph_co
+ return 0;
+ }
+
+-static void fail_protocol(struct ceph_connection *con)
+-{
+- reset_connection(con);
+- WARN_ON(con->state != CON_STATE_NEGOTIATING);
+- con->state = CON_STATE_CLOSED;
+-}
+-
+ static int process_connect(struct ceph_connection *con)
+ {
+ u64 sup_feat = con->msgr->supported_features;
+@@ -1530,7 +1524,7 @@ static int process_connect(struct ceph_c
+ ceph_pr_addr(&con->peer_addr.in_addr),
+ sup_feat, server_feat, server_feat & ~sup_feat);
+ con->error_msg = "missing required protocol features";
+- fail_protocol(con);
++ reset_connection(con);
+ return -1;
+
+ case CEPH_MSGR_TAG_BADPROTOVER:
+@@ -1541,7 +1535,7 @@ static int process_connect(struct ceph_c
+ le32_to_cpu(con->out_connect.protocol_version),
+ le32_to_cpu(con->in_reply.protocol_version));
+ con->error_msg = "protocol version mismatch";
+- fail_protocol(con);
++ reset_connection(con);
+ return -1;
+
+ case CEPH_MSGR_TAG_BADAUTHORIZER:
+@@ -1631,7 +1625,7 @@ static int process_connect(struct ceph_c
+ ceph_pr_addr(&con->peer_addr.in_addr),
+ req_feat, server_feat, req_feat & ~server_feat);
+ con->error_msg = "missing required protocol features";
+- fail_protocol(con);
++ reset_connection(con);
+ return -1;
+ }
+
+From 71630f053c8da3b7d8e52c99ff2592f44dd28979 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage at inktank.com>
+Date: Mon, 29 Oct 2012 11:01:42 -0700
+Subject: libceph: fix osdmap decode error paths
+
+
+From: Sage Weil <sage at inktank.com>
+
+(cherry picked from commit 0ed7285e0001b960c888e5455ae982025210ed3d)
+
+Ensure that we set the err value correctly so that we do not pass a 0
+value to ERR_PTR and confuse the calling code. (In particular,
+osd_client.c handle_map() will BUG(!newmap)).
+
+Signed-off-by: Sage Weil <sage at inktank.com>
+Reviewed-by: Alex Elder <elder at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osdmap.c | 31 ++++++++++++++++++++-----------
+ 1 file changed, 20 insertions(+), 11 deletions(-)
+
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -645,10 +645,12 @@ struct ceph_osdmap *osdmap_decode(void *
+ ceph_decode_32_safe(p, end, max, bad);
+ while (max--) {
+ ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
++ err = -ENOMEM;
+ pi = kzalloc(sizeof(*pi), GFP_NOFS);
+ if (!pi)
+ goto bad;
+ pi->id = ceph_decode_32(p);
++ err = -EINVAL;
+ ev = ceph_decode_8(p); /* encoding version */
+ if (ev > CEPH_PG_POOL_VERSION) {
+ pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+@@ -664,8 +666,13 @@ struct ceph_osdmap *osdmap_decode(void *
+ __insert_pg_pool(&map->pg_pools, pi);
+ }
+
+- if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+- goto bad;
++ if (version >= 5) {
++ err = __decode_pool_names(p, end, map);
++ if (err < 0) {
++ dout("fail to decode pool names");
++ goto bad;
++ }
++ }
+
+ ceph_decode_32_safe(p, end, map->pool_max, bad);
+
+@@ -745,7 +752,7 @@ struct ceph_osdmap *osdmap_decode(void *
+ return map;
+
+ bad:
+- dout("osdmap_decode fail\n");
++ dout("osdmap_decode fail err %d\n", err);
+ ceph_osdmap_destroy(map);
+ return ERR_PTR(err);
+ }
+@@ -839,6 +846,7 @@ struct ceph_osdmap *osdmap_apply_increme
+ if (ev > CEPH_PG_POOL_VERSION) {
+ pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
+ ev, CEPH_PG_POOL_VERSION);
++ err = -EINVAL;
+ goto bad;
+ }
+ pi = __lookup_pg_pool(&map->pg_pools, pool);
+@@ -855,8 +863,11 @@ struct ceph_osdmap *osdmap_apply_increme
+ if (err < 0)
+ goto bad;
+ }
+- if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+- goto bad;
++ if (version >= 5) {
++ err = __decode_pool_names(p, end, map);
++ if (err < 0)
++ goto bad;
++ }
+
+ /* old_pool */
+ ceph_decode_32_safe(p, end, len, bad);
+@@ -932,15 +943,13 @@ struct ceph_osdmap *osdmap_apply_increme
+ (void) __remove_pg_mapping(&map->pg_temp, pgid);
+
+ /* insert */
+- if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32)) {
+- err = -EINVAL;
++ err = -EINVAL;
++ if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
+ goto bad;
+- }
++ err = -ENOMEM;
+ pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
+- if (!pg) {
+- err = -ENOMEM;
++ if (!pg)
+ goto bad;
+- }
+ pg->pgid = pgid;
+ pg->len = pglen;
+ for (j = 0; j < pglen; j++)
+From f4a3fea610cb6a9fc9cb722a0765194e19b82e7b Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Fri, 7 Dec 2012 09:57:58 -0600
+Subject: libceph: avoid using freed osd in __kick_osd_requests()
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 685a7555ca69030739ddb57a47f0ea8ea80196a4)
+
+If an osd has no requests and no linger requests, __reset_osd()
+will just remove it with a call to __remove_osd(). That drops
+a reference to the osd, and therefore the osd may have been free
+by the time __reset_osd() returns. That function offers no
+indication this may have occurred, and as a result the osd will
+continue to be used even when it's no longer valid.
+
+Change__reset_osd() so it returns an error (ENODEV) when it
+deletes the osd being reset. And change __kick_osd_requests() so it
+returns immediately (before referencing osd again) if __reset_osd()
+returns *any* error.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -581,7 +581,7 @@ static void __kick_osd_requests(struct c
+
+ dout("__kick_osd_requests osd%d\n", osd->o_osd);
+ err = __reset_osd(osdc, osd);
+- if (err == -EAGAIN)
++ if (err)
+ return;
+
+ list_for_each_entry(req, &osd->o_requests, r_osd_item) {
+@@ -752,6 +752,7 @@ static int __reset_osd(struct ceph_osd_c
+ if (list_empty(&osd->o_requests) &&
+ list_empty(&osd->o_linger_requests)) {
+ __remove_osd(osdc, osd);
++ ret = -ENODEV;
+ } else if (memcmp(&osdc->osdmap->osd_addr[osd->o_osd],
+ &osd->o_con.peer_addr,
+ sizeof(osd->o_con.peer_addr)) == 0 &&
+From aa852ff17166b53b1d29388af472bb9c32297f05 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage at inktank.com>
+Date: Wed, 28 Nov 2012 12:28:24 -0800
+Subject: libceph: remove 'osdtimeout' option
+
+
+From: Sage Weil <sage at inktank.com>
+
+(cherry picked from commit 83aff95eb9d60aff5497e9f44a2ae906b86d8e88)
+
+This would reset a connection with any OSD that had an outstanding
+request that was taking more than N seconds. The idea was that if the
+OSD was buggy, the client could compensate by resending the request.
+
+In reality, this only served to hide server bugs, and we haven't
+actually seen such a bug in quite a while. Moreover, the userspace
+client code never did this.
+
+More importantly, often the request is taking a long time because the
+OSD is trying to recover, or overloaded, and killing the connection
+and retrying would only make the situation worse by giving the OSD
+more work to do.
+
+Signed-off-by: Sage Weil <sage at inktank.com>
+Reviewed-by: Alex Elder <elder at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/super.c | 2 -
+ include/linux/ceph/libceph.h | 2 -
+ net/ceph/ceph_common.c | 3 --
+ net/ceph/osd_client.c | 47 +++----------------------------------------
+ 4 files changed, 5 insertions(+), 49 deletions(-)
+
+--- a/fs/ceph/super.c
++++ b/fs/ceph/super.c
+@@ -403,8 +403,6 @@ static int ceph_show_options(struct seq_
+ seq_printf(m, ",mount_timeout=%d", opt->mount_timeout);
+ if (opt->osd_idle_ttl != CEPH_OSD_IDLE_TTL_DEFAULT)
+ seq_printf(m, ",osd_idle_ttl=%d", opt->osd_idle_ttl);
+- if (opt->osd_timeout != CEPH_OSD_TIMEOUT_DEFAULT)
+- seq_printf(m, ",osdtimeout=%d", opt->osd_timeout);
+ if (opt->osd_keepalive_timeout != CEPH_OSD_KEEPALIVE_DEFAULT)
+ seq_printf(m, ",osdkeepalivetimeout=%d",
+ opt->osd_keepalive_timeout);
+--- a/include/linux/ceph/libceph.h
++++ b/include/linux/ceph/libceph.h
+@@ -43,7 +43,6 @@ struct ceph_options {
+ struct ceph_entity_addr my_addr;
+ int mount_timeout;
+ int osd_idle_ttl;
+- int osd_timeout;
+ int osd_keepalive_timeout;
+
+ /*
+@@ -63,7 +62,6 @@ struct ceph_options {
+ * defaults
+ */
+ #define CEPH_MOUNT_TIMEOUT_DEFAULT 60
+-#define CEPH_OSD_TIMEOUT_DEFAULT 60 /* seconds */
+ #define CEPH_OSD_KEEPALIVE_DEFAULT 5
+ #define CEPH_OSD_IDLE_TTL_DEFAULT 60
+
+--- a/net/ceph/ceph_common.c
++++ b/net/ceph/ceph_common.c
+@@ -305,7 +305,6 @@ ceph_parse_options(char *options, const
+
+ /* start with defaults */
+ opt->flags = CEPH_OPT_DEFAULT;
+- opt->osd_timeout = CEPH_OSD_TIMEOUT_DEFAULT;
+ opt->osd_keepalive_timeout = CEPH_OSD_KEEPALIVE_DEFAULT;
+ opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT; /* seconds */
+ opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT; /* seconds */
+@@ -391,7 +390,7 @@ ceph_parse_options(char *options, const
+
+ /* misc */
+ case Opt_osdtimeout:
+- opt->osd_timeout = intval;
++ pr_warning("ignoring deprecated osdtimeout option\n");
+ break;
+ case Opt_osdkeepalivetimeout:
+ opt->osd_keepalive_timeout = intval;
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -608,14 +608,6 @@ static void __kick_osd_requests(struct c
+ }
+ }
+
+-static void kick_osd_requests(struct ceph_osd_client *osdc,
+- struct ceph_osd *kickosd)
+-{
+- mutex_lock(&osdc->request_mutex);
+- __kick_osd_requests(osdc, kickosd);
+- mutex_unlock(&osdc->request_mutex);
+-}
+-
+ /*
+ * If the osd connection drops, we need to resubmit all requests.
+ */
+@@ -629,7 +621,9 @@ static void osd_reset(struct ceph_connec
+ dout("osd_reset osd%d\n", osd->o_osd);
+ osdc = osd->o_osdc;
+ down_read(&osdc->map_sem);
+- kick_osd_requests(osdc, osd);
++ mutex_lock(&osdc->request_mutex);
++ __kick_osd_requests(osdc, osd);
++ mutex_unlock(&osdc->request_mutex);
+ send_queued(osdc);
+ up_read(&osdc->map_sem);
+ }
+@@ -1093,12 +1087,10 @@ static void handle_timeout(struct work_s
+ {
+ struct ceph_osd_client *osdc =
+ container_of(work, struct ceph_osd_client, timeout_work.work);
+- struct ceph_osd_request *req, *last_req = NULL;
++ struct ceph_osd_request *req;
+ struct ceph_osd *osd;
+- unsigned long timeout = osdc->client->options->osd_timeout * HZ;
+ unsigned long keepalive =
+ osdc->client->options->osd_keepalive_timeout * HZ;
+- unsigned long last_stamp = 0;
+ struct list_head slow_osds;
+ dout("timeout\n");
+ down_read(&osdc->map_sem);
+@@ -1108,37 +1100,6 @@ static void handle_timeout(struct work_s
+ mutex_lock(&osdc->request_mutex);
+
+ /*
+- * reset osds that appear to be _really_ unresponsive. this
+- * is a failsafe measure.. we really shouldn't be getting to
+- * this point if the system is working properly. the monitors
+- * should mark the osd as failed and we should find out about
+- * it from an updated osd map.
+- */
+- while (timeout && !list_empty(&osdc->req_lru)) {
+- req = list_entry(osdc->req_lru.next, struct ceph_osd_request,
+- r_req_lru_item);
+-
+- /* hasn't been long enough since we sent it? */
+- if (time_before(jiffies, req->r_stamp + timeout))
+- break;
+-
+- /* hasn't been long enough since it was acked? */
+- if (req->r_request->ack_stamp == 0 ||
+- time_before(jiffies, req->r_request->ack_stamp + timeout))
+- break;
+-
+- BUG_ON(req == last_req && req->r_stamp == last_stamp);
+- last_req = req;
+- last_stamp = req->r_stamp;
+-
+- osd = req->r_osd;
+- BUG_ON(!osd);
+- pr_warning(" tid %llu timed out on osd%d, will reset osd\n",
+- req->r_tid, osd->o_osd);
+- __kick_osd_requests(osdc, osd);
+- }
+-
+- /*
+ * ping osds that are a bit slow. this ensures that if there
+ * is a break in the TCP connection we will notice, and reopen
+ * a connection with that osd (from the fault callback).
+From a6bbcd6741d53b326a2a3a7edef6e15334de6ea3 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Thu, 29 Nov 2012 08:37:03 -0600
+Subject: ceph: don't reference req after put
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 7d5f24812bd182a2471cb69c1c2baf0648332e1f)
+
+In __unregister_request(), there is a call to list_del_init()
+referencing a request that was the subject of a call to
+ceph_osdc_put_request() on the previous line. This is not
+safe, because the request structure could have been freed
+by the time we reach the list_del_init().
+
+Fix this by reversing the order of these lines.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -873,9 +873,9 @@ static void __unregister_request(struct
+ req->r_osd = NULL;
+ }
+
++ list_del_init(&req->r_req_lru_item);
+ ceph_osdc_put_request(req);
+
+- list_del_init(&req->r_req_lru_item);
+ if (osdc->num_requests == 0) {
+ dout(" no requests, canceling timeout\n");
+ __cancel_osd_timeout(osdc);
+From 8824d0eb9dee3bad29e9dba796d5d7953cab6719 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Wed, 10 Oct 2012 21:19:13 -0700
+Subject: rbd: fix bug in rbd_dev_id_put()
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit b213e0b1a62637b2a9395a34349b13d73ca2b90a)
+
+In rbd_dev_id_put(), there's a loop that's intended to determine
+the maximum device id in use. But it isn't doing that at all,
+the effect of how it's written is to simply use the just-put id
+number, which ignores whole purpose of this function.
+
+Fix the bug.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Josh Durgin <josh.durgin at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -2621,8 +2621,8 @@ static void rbd_dev_id_put(struct rbd_de
+ struct rbd_device *rbd_dev;
+
+ rbd_dev = list_entry(tmp, struct rbd_device, node);
+- if (rbd_id > max_id)
+- max_id = rbd_id;
++ if (rbd_dev->dev_id > max_id)
++ max_id = rbd_dev->dev_id;
+ }
+ spin_unlock(&rbd_dev_list_lock);
+
+From cc8b5fcd343b3c99468fc9f0b4c3e03a7eafa7fc Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Wed, 10 Oct 2012 21:19:13 -0700
+Subject: rbd: zero return code in rbd_dev_image_id()
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit a0ea3a40fd20b8c66381f747c454f89d6d1f50d4)
+
+When rbd_dev_probe() calls rbd_dev_image_id() it expects to get
+a 0 return code if successful, but it is getting a positive value.
+
+The reason is that rbd_dev_image_id() returns the value it gets from
+rbd_req_sync_exec(), which returns the number of bytes read in as a
+result of the request. (This ultimately comes from
+ceph_copy_from_page_vector() in rbd_req_sync_op()).
+
+Force the return value to 0 when successful in rbd_dev_image_id().
+Do the same in rbd_dev_v2_object_prefix().
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Josh Durgin <josh.durgin at inktank.com>
+Reviewed-by: Dan Mick <dan.mick at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -2189,6 +2189,7 @@ static int rbd_dev_v2_object_prefix(stru
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
++ ret = 0; /* rbd_req_sync_exec() can return positive */
+
+ p = reply_buf;
+ rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
+@@ -2841,6 +2842,7 @@ static int rbd_dev_image_id(struct rbd_d
+ dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+ if (ret < 0)
+ goto out;
++ ret = 0; /* rbd_req_sync_exec() can return positive */
+
+ p = response;
+ rbd_dev->image_id = ceph_extract_encoded_string(&p,
+From 9aca7b487cf1c996a13ff5abf0ea4ac560ea1dd4 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Mon, 22 Oct 2012 11:31:26 -0500
+Subject: rbd: fix read-only option name
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit be466c1cc36621590ef17b05a6d342dfd33f7280)
+
+The name of the "read-only" mapping option was inadvertently changed
+in this commit:
+
+ f84344f3 rbd: separate mapping info in rbd_dev
+
+Revert that hunk to return it to what it should be.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Dan Mick <dan.mick at inktank.com>
+Reviewed-by: Josh Durgin <josh.durgin at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -388,7 +388,7 @@ enum {
+ static match_table_t rbd_opts_tokens = {
+ /* int args above */
+ /* string args above */
+- {Opt_read_only, "mapping.read_only"},
++ {Opt_read_only, "read_only"},
+ {Opt_read_only, "ro"}, /* Alternate spelling */
+ {Opt_read_write, "read_write"},
+ {Opt_read_write, "rw"}, /* Alternate spelling */
+From 1306be442fda1b7a92b879ab18a535f56da5ab0a Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Tue, 3 Jul 2012 16:01:19 -0500
+Subject: rbd: increase maximum snapshot name length
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit d4b125e9eb43babd14538ba61718e3db71a98d29)
+
+Change RBD_MAX_SNAP_NAME_LEN to be based on NAME_MAX. That is a
+practical limit for the length of a snapshot name (based on the
+presence of a directory using the name under /sys/bus/rbd to
+represent the snapshot).
+
+The /sys entry is created by prefixing it with "snap_"; define that
+prefix symbolically, and take its length into account in defining
+the snapshot name length limit.
+
+Enforce the limit in rbd_add_parse_args(). Also delete a dout()
+call in that function that was not meant to be committed.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Dan Mick <dan.mick at inktank.com>
+Reviewed-by: Josh Durgin <josh.durgin at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -61,7 +61,10 @@
+
+ #define RBD_MINORS_PER_MAJOR 256 /* max minors per blkdev */
+
+-#define RBD_MAX_SNAP_NAME_LEN 32
++#define RBD_SNAP_DEV_NAME_PREFIX "snap_"
++#define RBD_MAX_SNAP_NAME_LEN \
++ (NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
++
+ #define RBD_MAX_SNAP_COUNT 510 /* allows max snapc to fit in 4KB */
+ #define RBD_MAX_OPT_LEN 1024
+
+@@ -2073,7 +2076,7 @@ static int rbd_register_snap_dev(struct
+ dev->type = &rbd_snap_device_type;
+ dev->parent = parent;
+ dev->release = rbd_snap_dev_release;
+- dev_set_name(dev, "snap_%s", snap->name);
++ dev_set_name(dev, "%s%s", RBD_SNAP_DEV_NAME_PREFIX, snap->name);
+ dout("%s: registering device for snapshot %s\n", __func__, snap->name);
+
+ ret = device_register(dev);
+@@ -2766,8 +2769,13 @@ static char *rbd_add_parse_args(struct r
+ if (!rbd_dev->image_name)
+ goto out_err;
+
+- /* Snapshot name is optional */
++ /* Snapshot name is optional; default is to use "head" */
++
+ len = next_token(&buf);
++ if (len > RBD_MAX_SNAP_NAME_LEN) {
++ err_ptr = ERR_PTR(-ENAMETOOLONG);
++ goto out_err;
++ }
+ if (!len) {
+ buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
+ len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
+@@ -2778,8 +2786,6 @@ static char *rbd_add_parse_args(struct r
+ memcpy(snap_name, buf, len);
+ *(snap_name + len) = '\0';
+
+-dout(" SNAP_NAME is <%s>, len is %zd\n", snap_name, len);
+-
+ return snap_name;
+
+ out_err:
+From 21bc037520c252304c04d3bb8131fb3d4ba5b2c5 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Thu, 25 Oct 2012 23:34:40 -0500
+Subject: rbd: remove snapshots on error in rbd_add()
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 41f38c2b2f8b66b176a0e548ef06294343a7bfa2)
+
+If rbd_dev_snaps_update() has ever been called for an rbd device
+structure there could be snapshot structures on its snaps list.
+In rbd_add(), this function is called but a subsequent error
+path neglected to clean up any of these snapshots.
+
+Add a call to rbd_remove_all_snaps() in the appropriate spot to
+remedy this. Change a couple of error labels to be a little
+clearer while there.
+
+Drop the leading underscores from the function name; there's nothing
+special about that function that they might signify. As suggested
+in review, the leading underscores in __rbd_remove_snap_dev() have
+been removed as well.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Josh Durgin <josh.durgin at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -221,7 +221,7 @@ static int rbd_dev_snaps_update(struct r
+ static int rbd_dev_snaps_register(struct rbd_device *rbd_dev);
+
+ static void rbd_dev_release(struct device *dev);
+-static void __rbd_remove_snap_dev(struct rbd_snap *snap);
++static void rbd_remove_snap_dev(struct rbd_snap *snap);
+
+ static ssize_t rbd_add(struct bus_type *bus, const char *buf,
+ size_t count);
+@@ -1710,13 +1710,13 @@ static int rbd_read_header(struct rbd_de
+ return ret;
+ }
+
+-static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
++static void rbd_remove_all_snaps(struct rbd_device *rbd_dev)
+ {
+ struct rbd_snap *snap;
+ struct rbd_snap *next;
+
+ list_for_each_entry_safe(snap, next, &rbd_dev->snaps, node)
+- __rbd_remove_snap_dev(snap);
++ rbd_remove_snap_dev(snap);
+ }
+
+ /*
+@@ -2060,7 +2060,7 @@ static bool rbd_snap_registered(struct r
+ return ret;
+ }
+
+-static void __rbd_remove_snap_dev(struct rbd_snap *snap)
++static void rbd_remove_snap_dev(struct rbd_snap *snap)
+ {
+ list_del(&snap->node);
+ if (device_is_registered(&snap->dev))
+@@ -2442,7 +2442,7 @@ static int rbd_dev_snaps_update(struct r
+
+ if (rbd_dev->mapping.snap_id == snap->id)
+ rbd_dev->mapping.snap_exists = false;
+- __rbd_remove_snap_dev(snap);
++ rbd_remove_snap_dev(snap);
+ dout("%ssnap id %llu has been removed\n",
+ rbd_dev->mapping.snap_id == snap->id ?
+ "mapped " : "",
+@@ -3053,11 +3053,11 @@ static ssize_t rbd_add(struct bus_type *
+ /* no need to lock here, as rbd_dev is not registered yet */
+ rc = rbd_dev_snaps_update(rbd_dev);
+ if (rc)
+- goto err_out_header;
++ goto err_out_probe;
+
+ rc = rbd_dev_set_mapping(rbd_dev, snap_name);
+ if (rc)
+- goto err_out_header;
++ goto err_out_snaps;
+
+ /* generate unique id: find highest unique id, add one */
+ rbd_dev_id_get(rbd_dev);
+@@ -3121,7 +3121,9 @@ err_out_blkdev:
+ unregister_blkdev(rbd_dev->major, rbd_dev->name);
+ err_out_id:
+ rbd_dev_id_put(rbd_dev);
+-err_out_header:
++err_out_snaps:
++ rbd_remove_all_snaps(rbd_dev);
++err_out_probe:
+ rbd_header_free(&rbd_dev->header);
+ err_out_client:
+ kfree(rbd_dev->header_name);
+@@ -3219,7 +3221,7 @@ static ssize_t rbd_remove(struct bus_typ
+ goto done;
+ }
+
+- __rbd_remove_all_snaps(rbd_dev);
++ rbd_remove_all_snaps(rbd_dev);
+ rbd_bus_del_dev(rbd_dev);
+
+ done:
+From 730406993ec6d044a81115fc19091ba6abfcbb15 Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Fri, 16 Nov 2012 09:29:16 -0600
+Subject: rbd: do not allow remove of mounted-on image
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 42382b709bd1d143b9f0fa93e0a3a1f2f4210707)
+
+There is no check in rbd_remove() to see if anybody holds open the
+image being removed. That's not cool.
+
+Add a simple open count that goes up and down with opens and closes
+(releases) of the device, and don't allow an rbd image to be removed
+if the count is non-zero.
+
+Protect the updates of the open count value with ctl_mutex to ensure
+the underlying rbd device doesn't get removed while concurrently
+being opened.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -207,6 +207,7 @@ struct rbd_device {
+
+ /* sysfs related */
+ struct device dev;
++ unsigned long open_count;
+ };
+
+ static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */
+@@ -280,8 +281,11 @@ static int rbd_open(struct block_device
+ if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only)
+ return -EROFS;
+
++ mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+ rbd_get_dev(rbd_dev);
+ set_device_ro(bdev, rbd_dev->mapping.read_only);
++ rbd_dev->open_count++;
++ mutex_unlock(&ctl_mutex);
+
+ return 0;
+ }
+@@ -290,7 +294,11 @@ static int rbd_release(struct gendisk *d
+ {
+ struct rbd_device *rbd_dev = disk->private_data;
+
++ mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
++ rbd_assert(rbd_dev->open_count > 0);
++ rbd_dev->open_count--;
+ rbd_put_dev(rbd_dev);
++ mutex_unlock(&ctl_mutex);
+
+ return 0;
+ }
+@@ -3221,6 +3229,11 @@ static ssize_t rbd_remove(struct bus_typ
+ goto done;
+ }
+
++ if (rbd_dev->open_count) {
++ ret = -EBUSY;
++ goto done;
++ }
++
+ rbd_remove_all_snaps(rbd_dev);
+ rbd_bus_del_dev(rbd_dev);
+
+From 965f03ad3d796d03ec16f9809cb0096a64f6523d Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Fri, 9 Nov 2012 15:05:54 -0600
+Subject: rbd: get rid of RBD_MAX_SEG_NAME_LEN
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 2fd82b9e92c2a718ae81fc987b4468ceeee6979b)
+
+RBD_MAX_SEG_NAME_LEN represents the maximum length of an rbd object
+name (i.e., one of the objects providing storage backing an rbd
+image).
+
+Another symbol, MAX_OBJ_NAME_SIZE, is used in the osd client code to
+define the maximum length of any object name in an osd request.
+
+Right now they disagree, with RBD_MAX_SEG_NAME_LEN being too big.
+
+There's no real benefit at this point to defining the rbd object
+name length limit separate from any other object name, so just
+get rid of RBD_MAX_SEG_NAME_LEN and use MAX_OBJ_NAME_SIZE in its
+place.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ drivers/block/rbd.c | 6 +++---
+ drivers/block/rbd_types.h | 2 --
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -706,13 +706,13 @@ static char *rbd_segment_name(struct rbd
+ u64 segment;
+ int ret;
+
+- name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
++ name = kmalloc(MAX_OBJ_NAME_SIZE + 1, GFP_NOIO);
+ if (!name)
+ return NULL;
+ segment = offset >> rbd_dev->header.obj_order;
+- ret = snprintf(name, RBD_MAX_SEG_NAME_LEN, "%s.%012llx",
++ ret = snprintf(name, MAX_OBJ_NAME_SIZE + 1, "%s.%012llx",
+ rbd_dev->header.object_prefix, segment);
+- if (ret < 0 || ret >= RBD_MAX_SEG_NAME_LEN) {
++ if (ret < 0 || ret > MAX_OBJ_NAME_SIZE) {
+ pr_err("error formatting segment name for #%llu (%d)\n",
+ segment, ret);
+ kfree(name);
+--- a/drivers/block/rbd_types.h
++++ b/drivers/block/rbd_types.h
+@@ -46,8 +46,6 @@
+ #define RBD_MIN_OBJ_ORDER 16
+ #define RBD_MAX_OBJ_ORDER 30
+
+-#define RBD_MAX_SEG_NAME_LEN 128
+-
+ #define RBD_COMP_NONE 0
+ #define RBD_CRYPT_NONE 0
+
+From 942784e7a6e2ef8f861043f65b054eb3ef10b2fd Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder at inktank.com>
+Date: Thu, 6 Dec 2012 09:37:23 -0600
+Subject: rbd: remove linger unconditionally
+
+
+From: Alex Elder <elder at inktank.com>
+
+(cherry picked from commit 61c74035626beb25a39b0273ccf7d75510bc36a1)
+
+In __unregister_linger_request(), the request is being removed
+from the osd client's req_linger list only when the request
+has a non-null osd pointer. It should be done whether or not
+the request currently has an osd.
+
+This is most likely a non-issue because I believe the request
+will always have an osd when this function is called.
+
+Signed-off-by: Alex Elder <elder at inktank.com>
+Reviewed-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ net/ceph/osd_client.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -907,8 +907,8 @@ static void __unregister_linger_request(
+ struct ceph_osd_request *req)
+ {
+ dout("__unregister_linger_request %p\n", req);
++ list_del_init(&req->r_linger_item);
+ if (req->r_osd) {
+- list_del_init(&req->r_linger_item);
+ list_del_init(&req->r_linger_osd);
+
+ if (list_empty(&req->r_osd->o_requests) &&
+From 76c834d784c36bda3a8d56f5cdf3e1282b0979f9 Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+Date: Mon, 19 Nov 2012 10:49:04 +0800
+Subject: ceph: Don't update i_max_size when handling non-auth cap
+
+
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+
+(cherry picked from commit 5e62ad30157d0da04cf40c6d1a2f4bc840948b9c)
+
+The cap from non-auth mds doesn't have a meaningful max_size value.
+
+Signed-off-by: Yan, Zheng <zheng.z.yan at intel.com>
+Signed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/caps.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2388,7 +2388,7 @@ static void handle_cap_grant(struct inod
+ &atime);
+
+ /* max size increase? */
+- if (max_size != ci->i_max_size) {
++ if (ci->i_auth_cap == cap && max_size != ci->i_max_size) {
+ dout("max_size %lld -> %llu\n", ci->i_max_size, max_size);
+ ci->i_max_size = max_size;
+ if (max_size >= ci->i_wanted_max_size) {
+From 0fd2af5e838e87cf449c657b6e19535b64da6c4c Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+Date: Mon, 19 Nov 2012 10:49:06 +0800
+Subject: ceph: Fix infinite loop in __wake_requests
+
+
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+
+(cherry picked from commit ed75ec2cd19b47efcd292b6e23f58e56f4c5bc34)
+
+__wake_requests() will enter infinite loop if we use it to wake
+requests in the session->s_waiting list. __wake_requests() deletes
+requests from the list and __do_request() adds requests back to
+the list.
+
+Signed-off-by: Yan, Zheng <zheng.z.yan at intel.com>
+Signed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/mds_client.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1876,9 +1876,14 @@ finish:
+ static void __wake_requests(struct ceph_mds_client *mdsc,
+ struct list_head *head)
+ {
+- struct ceph_mds_request *req, *nreq;
++ struct ceph_mds_request *req;
++ LIST_HEAD(tmp_list);
+
+- list_for_each_entry_safe(req, nreq, head, r_wait) {
++ list_splice_init(head, &tmp_list);
++
++ while (!list_empty(&tmp_list)) {
++ req = list_entry(tmp_list.next,
++ struct ceph_mds_request, r_wait);
+ list_del_init(&req->r_wait);
+ __do_request(mdsc, req);
+ }
+From f409f158fb190ab9915fd94dce367e462a0c02f6 Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+Date: Mon, 19 Nov 2012 10:49:07 +0800
+Subject: ceph: Don't add dirty inode to dirty list if caps is in migration
+
+
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+
+(cherry picked from commit 0685235ffd9dbdb9ccbda587f8a3c83ad1d5a921)
+
+Add dirty inode to cap_dirty_migrating list instead, this can avoid
+ceph_flush_dirty_caps() entering infinite loop.
+
+Signed-off-by: Yan, Zheng <zheng.z.yan at intel.com>
+Signed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/caps.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -1349,11 +1349,15 @@ int __ceph_mark_dirty_caps(struct ceph_i
+ if (!ci->i_head_snapc)
+ ci->i_head_snapc = ceph_get_snap_context(
+ ci->i_snap_realm->cached_context);
+- dout(" inode %p now dirty snapc %p\n", &ci->vfs_inode,
+- ci->i_head_snapc);
++ dout(" inode %p now dirty snapc %p auth cap %p\n",
++ &ci->vfs_inode, ci->i_head_snapc, ci->i_auth_cap);
+ BUG_ON(!list_empty(&ci->i_dirty_item));
+ spin_lock(&mdsc->cap_dirty_lock);
+- list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
++ if (ci->i_auth_cap)
++ list_add(&ci->i_dirty_item, &mdsc->cap_dirty);
++ else
++ list_add(&ci->i_dirty_item,
++ &mdsc->cap_dirty_migrating);
+ spin_unlock(&mdsc->cap_dirty_lock);
+ if (ci->i_flushing_caps == 0) {
+ ihold(inode);
+From 0e6789acaba2e40768a778a1e553c92723a19a30 Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+Date: Mon, 19 Nov 2012 10:49:08 +0800
+Subject: ceph: Fix __ceph_do_pending_vmtruncate
+
+
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+
+(cherry picked from commit a85f50b6ef93fbbb2ae932ce9b2376509d172796)
+
+we should set i_truncate_pending to 0 after page cache is truncated
+to i_truncate_size
+
+Signed-off-by: Yan, Zheng <zheng.z.yan at intel.com>
+Signed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/inode.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/fs/ceph/inode.c
++++ b/fs/ceph/inode.c
+@@ -1466,7 +1466,7 @@ void __ceph_do_pending_vmtruncate(struct
+ {
+ struct ceph_inode_info *ci = ceph_inode(inode);
+ u64 to;
+- int wrbuffer_refs, wake = 0;
++ int wrbuffer_refs, finish = 0;
+
+ retry:
+ spin_lock(&ci->i_ceph_lock);
+@@ -1498,15 +1498,18 @@ retry:
+ truncate_inode_pages(inode->i_mapping, to);
+
+ spin_lock(&ci->i_ceph_lock);
+- ci->i_truncate_pending--;
+- if (ci->i_truncate_pending == 0)
+- wake = 1;
++ if (to == ci->i_truncate_size) {
++ ci->i_truncate_pending = 0;
++ finish = 1;
++ }
+ spin_unlock(&ci->i_ceph_lock);
++ if (!finish)
++ goto retry;
+
+ if (wrbuffer_refs == 0)
+ ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
+- if (wake)
+- wake_up_all(&ci->i_cap_wq);
++
++ wake_up_all(&ci->i_cap_wq);
+ }
+
+
+From 0747d15ddb5eac0e83376e2722e3654ae01d252f Mon Sep 17 00:00:00 2001
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+Date: Mon, 19 Nov 2012 10:49:09 +0800
+Subject: ceph: call handle_cap_grant() for cap import message
+
+
+From: "Yan, Zheng" <zheng.z.yan at intel.com>
+
+(cherry picked from commit 0e5e1774a92e6fe9c511585de8f078b4c4c68dbb)
+
+If client sends cap message that requests new max size during
+exporting caps, the exporting MDS will drop the message quietly.
+So the client may wait for the reply that updates the max size
+forever. call handle_cap_grant() for cap import message can
+avoid this issue.
+
+Signed-off-by: Yan, Zheng <zheng.z.yan at intel.com>
+Signed-off-by: Sage Weil <sage at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/caps.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -2749,6 +2749,7 @@ static void handle_cap_import(struct cep
+
+ /* make sure we re-request max_size, if necessary */
+ spin_lock(&ci->i_ceph_lock);
++ ci->i_wanted_max_size = 0; /* reset */
+ ci->i_requested_max_size = 0;
+ spin_unlock(&ci->i_ceph_lock);
+ }
+@@ -2844,8 +2845,6 @@ void ceph_handle_caps(struct ceph_mds_se
+ case CEPH_CAP_OP_IMPORT:
+ handle_cap_import(mdsc, inode, h, session,
+ snaptrace, snaptrace_len);
+- ceph_check_caps(ceph_inode(inode), 0, session);
+- goto done_unlocked;
+ }
+
+ /* the rest require a cap */
+@@ -2862,6 +2861,7 @@ void ceph_handle_caps(struct ceph_mds_se
+ switch (op) {
+ case CEPH_CAP_OP_REVOKE:
+ case CEPH_CAP_OP_GRANT:
++ case CEPH_CAP_OP_IMPORT:
+ handle_cap_grant(inode, h, session, cap, msg->middle);
+ goto done_unlocked;
+
+From 9fa5ba96f32fbea354457fc7ece06b2ee81b1b71 Mon Sep 17 00:00:00 2001
+From: David Zafman <david.zafman at inktank.com>
+Date: Mon, 3 Dec 2012 19:14:05 -0800
+Subject: libceph: Unlock unprocessed pages in start_read() error path
+
+
+From: David Zafman <david.zafman at inktank.com>
+
+(cherry picked from commit 8884d53dd63b1d9315b343564fcbe1ede004a99e)
+
+Function start_read() can get an error before processing all pages.
+It must not only release the remaining pages, but unlock them too.
+
+This fixes http://tracker.newdream.net/issues/3370
+
+Signed-off-by: David Zafman <david.zafman at inktank.com>
+Reviewed-by: Alex Elder <elder at inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+---
+ fs/ceph/addr.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -267,6 +267,14 @@ static void finish_read(struct ceph_osd_
+ kfree(req->r_pages);
+ }
+
++static void ceph_unlock_page_vector(struct page **pages, int num_pages)
++{
++ int i;
++
++ for (i = 0; i < num_pages; i++)
++ unlock_page(pages[i]);
++}
++
+ /*
+ * start an async read(ahead) operation. return nr_pages we submitted
+ * a read for on success, or negative error code.
+@@ -347,6 +355,7 @@ static int start_read(struct inode *inod
+ return nr_pages;
+
+ out_pages:
++ ceph_unlock_page_vector(pages, nr_pages);
+ ceph_release_page_vector(pages, nr_pages);
+ out:
+ ceph_osdc_put_request(req);
+From 45e2b5f640b3766da3eda48f6c35f088155c06f3 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Fri, 23 Nov 2012 18:16:34 +0100
+Subject: drm/i915: force restore on lid open
+
+From: Daniel Vetter <daniel.vetter at ffwll.ch>
+
+commit 45e2b5f640b3766da3eda48f6c35f088155c06f3 upstream.
+
+There seem to be indeed some awkwards machines around, mostly those
+without OpRegion support, where the firmware changes the display hw
+state behind our backs when closing the lid.
+
+This force-restore logic has been originally introduced in
+
+commit c1c7af60892070e4b82ad63bbfb95ae745056de0
+Author: Jesse Barnes <jbarnes at virtuousgeek.org>
+Date: Thu Sep 10 15:28:03 2009 -0700
+
+ drm/i915: force mode set at lid open time
+
+but after the modeset-rework we've disabled it in the vain hope that
+it's no longer required:
+
+commit 3b7a89fce3e3dc96b549d6d829387b4439044d0d
+Author: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Mon Sep 17 22:27:21 2012 +0200
+
+ drm/i915: fix OOPS in lid_notify
+
+Alas, no.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54677
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57434
+Tested-by: Krzysztof Mazur <krzysiek at podlesie.net>
+Reviewed-by: Jesse Barnes <jbarnes at virtuousgeek.org>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: CAI Qian <caiqian at redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/i915_drv.c | 2 +-
+ drivers/gpu/drm/i915/i915_drv.h | 3 ++-
+ drivers/gpu/drm/i915/intel_display.c | 15 ++++++++++++---
+ drivers/gpu/drm/i915/intel_lvds.c | 2 +-
+ 4 files changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -552,7 +552,7 @@ static int i915_drm_thaw(struct drm_devi
+ mutex_unlock(&dev->struct_mutex);
+
+ intel_modeset_init_hw(dev);
+- intel_modeset_setup_hw_state(dev);
++ intel_modeset_setup_hw_state(dev, false);
+ drm_mode_config_reset(dev);
+ drm_irq_install(dev);
+ }
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1595,7 +1595,8 @@ extern void intel_modeset_init(struct dr
+ extern void intel_modeset_gem_init(struct drm_device *dev);
+ extern void intel_modeset_cleanup(struct drm_device *dev);
+ extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
+-extern void intel_modeset_setup_hw_state(struct drm_device *dev);
++extern void intel_modeset_setup_hw_state(struct drm_device *dev,
++ bool force_restore);
+ extern bool intel_fbc_enabled(struct drm_device *dev);
+ extern void intel_disable_fbc(struct drm_device *dev);
+ extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -8250,7 +8250,8 @@ static void intel_sanitize_encoder(struc
+
+ /* Scan out the current hw modeset state, sanitizes it and maps it into the drm
+ * and i915 state tracking structures. */
+-void intel_modeset_setup_hw_state(struct drm_device *dev)
++void intel_modeset_setup_hw_state(struct drm_device *dev,
++ bool force_restore)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum pipe pipe;
+@@ -8321,7 +8322,15 @@ void intel_modeset_setup_hw_state(struct
+ intel_sanitize_crtc(crtc);
+ }
+
+- intel_modeset_update_staged_output_state(dev);
++ if (force_restore) {
++ for_each_pipe(pipe) {
++ crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
++ intel_set_mode(&crtc->base, &crtc->base.mode,
++ crtc->base.x, crtc->base.y, crtc->base.fb);
++ }
++ } else {
++ intel_modeset_update_staged_output_state(dev);
++ }
+
+ intel_modeset_check_state(dev);
+ }
+@@ -8332,7 +8341,7 @@ void intel_modeset_gem_init(struct drm_d
+
+ intel_setup_overlay(dev);
+
+- intel_modeset_setup_hw_state(dev);
++ intel_modeset_setup_hw_state(dev, false);
+ }
+
+ void intel_modeset_cleanup(struct drm_device *dev)
+--- a/drivers/gpu/drm/i915/intel_lvds.c
++++ b/drivers/gpu/drm/i915/intel_lvds.c
+@@ -526,7 +526,7 @@ static int intel_lid_notify(struct notif
+ dev_priv->modeset_on_lid = 0;
+
+ mutex_lock(&dev->mode_config.mutex);
+- intel_modeset_check_state(dev);
++ intel_modeset_setup_hw_state(dev, true);
+ mutex_unlock(&dev->mode_config.mutex);
+
+ return NOTIFY_OK;
+From 0fde901f1ddd2ce0e380a6444f1fb7ca555859e9 Mon Sep 17 00:00:00 2001
+From: Krzysztof Mazur <krzysiek at podlesie.net>
+Date: Wed, 19 Dec 2012 11:03:41 +0100
+Subject: i915: ensure that VGA plane is disabled
+
+From: Krzysztof Mazur <krzysiek at podlesie.net>
+
+commit 0fde901f1ddd2ce0e380a6444f1fb7ca555859e9 upstream.
+
+Some broken systems (like HP nc6120) in some cases, usually after LID
+close/open, enable VGA plane, making display unusable (black screen on LVDS,
+some strange mode on VGA output). We used to disable VGA plane only once at
+startup. Now we also check, if VGA plane is still disabled while changing
+mode, and fix that if something changed it.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57434
+Signed-off-by: Krzysztof Mazur <krzysiek at podlesie.net>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_display.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -8248,6 +8248,23 @@ static void intel_sanitize_encoder(struc
+ * the crtc fixup. */
+ }
+
++static void i915_redisable_vga(struct drm_device *dev)
++{
++ struct drm_i915_private *dev_priv = dev->dev_private;
++ u32 vga_reg;
++
++ if (HAS_PCH_SPLIT(dev))
++ vga_reg = CPU_VGACNTRL;
++ else
++ vga_reg = VGACNTRL;
++
++ if (I915_READ(vga_reg) != VGA_DISP_DISABLE) {
++ DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
++ I915_WRITE(vga_reg, VGA_DISP_DISABLE);
++ POSTING_READ(vga_reg);
++ }
++}
++
+ /* Scan out the current hw modeset state, sanitizes it and maps it into the drm
+ * and i915 state tracking structures. */
+ void intel_modeset_setup_hw_state(struct drm_device *dev,
+@@ -8328,6 +8345,8 @@ void intel_modeset_setup_hw_state(struct
+ intel_set_mode(&crtc->base, &crtc->base.mode,
+ crtc->base.x, crtc->base.y, crtc->base.fb);
+ }
++
++ i915_redisable_vga(dev);
+ } else {
+ intel_modeset_update_staged_output_state(dev);
+ }
+From 3490ea5de6ac4af309c3df8a26a5cca61306334c Mon Sep 17 00:00:00 2001
+From: Chris Wilson <chris at chris-wilson.co.uk>
+Date: Mon, 7 Jan 2013 10:11:40 +0000
+Subject: drm/i915: Treat crtc->mode.clock == 0 as disabled
+
+From: Chris Wilson <chris at chris-wilson.co.uk>
+
+commit 3490ea5de6ac4af309c3df8a26a5cca61306334c upstream.
+
+Prevent a divide-by-zero by consistently treating an 'active' CRTC
+without a mode set as actually disabled.
+
+This looks to have been first introduced with
+
+commit 24929352481f085c5f85d4d4cbc919ddf106d381
+Author: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Mon Jul 2 20:28:59 2012 +0200
+
+ drm/i915: read out the modeset hw state at load and resume time
+
+but then combined with
+
+commit b0a2658acb5bf9ca86b4aab011b7106de3af0add
+Author: Daniel Vetter <daniel.vetter at ffwll.ch>
+Date: Tue Dec 18 09:37:54 2012 +0100
+
+ drm/i915: don't disable disconnected outputs
+
+it finally started oopsing.
+
+Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
+Reported-and-tested-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
+Tested-by: Sedat Dilek <sedat.dilek at gmail.com>
+Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
+Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
+Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_pm.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -44,6 +44,14 @@
+ * i915.i915_enable_fbc parameter
+ */
+
++static bool intel_crtc_active(struct drm_crtc *crtc)
++{
++ /* Be paranoid as we can arrive here with only partial
++ * state retrieved from the hardware during setup.
++ */
++ return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
++}
++
+ static void i8xx_disable_fbc(struct drm_device *dev)
+ {
+ struct drm_i915_private *dev_priv = dev->dev_private;
+@@ -405,9 +413,8 @@ void intel_update_fbc(struct drm_device
+ * - going to an unsupported config (interlace, pixel multiply, etc.)
+ */
+ list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
+- if (tmp_crtc->enabled &&
+- !to_intel_crtc(tmp_crtc)->primary_disabled &&
+- tmp_crtc->fb) {
++ if (intel_crtc_active(tmp_crtc) &&
++ !to_intel_crtc(tmp_crtc)->primary_disabled) {
+ if (crtc) {
+ DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
+ dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
+@@ -992,7 +999,7 @@ static struct drm_crtc *single_enabled_c
+ struct drm_crtc *crtc, *enabled = NULL;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+- if (crtc->enabled && crtc->fb) {
++ if (intel_crtc_active(crtc)) {
+ if (enabled)
+ return NULL;
+ enabled = crtc;
+@@ -1086,7 +1093,7 @@ static bool g4x_compute_wm0(struct drm_d
+ int entries, tlb_miss;
+
+ crtc = intel_get_crtc_for_plane(dev, plane);
+- if (crtc->fb == NULL || !crtc->enabled) {
++ if (!intel_crtc_active(crtc)) {
+ *cursor_wm = cursor->guard_size;
+ *plane_wm = display->guard_size;
+ return false;
+@@ -1215,7 +1222,7 @@ static bool vlv_compute_drain_latency(st
+ int entries;
+
+ crtc = intel_get_crtc_for_plane(dev, plane);
+- if (crtc->fb == NULL || !crtc->enabled)
++ if (!intel_crtc_active(crtc))
+ return false;
+
+ clock = crtc->mode.clock; /* VESA DOT Clock */
+@@ -1478,7 +1485,7 @@ static void i9xx_update_wm(struct drm_de
+
+ fifo_size = dev_priv->display.get_fifo_size(dev, 1);
+ crtc = intel_get_crtc_for_plane(dev, 1);
+- if (crtc->enabled && crtc->fb) {
++ if (intel_crtc_active(crtc)) {
+ planeb_wm = intel_calculate_wm(crtc->mode.clock,
+ wm_info, fifo_size,
+ crtc->fb->bits_per_pixel / 8,
+@@ -1923,7 +1930,7 @@ sandybridge_compute_sprite_wm(struct drm
+ int entries, tlb_miss;
+
+ crtc = intel_get_crtc_for_plane(dev, plane);
+- if (crtc->fb == NULL || !crtc->enabled) {
++ if (!intel_crtc_active(crtc)) {
+ *sprite_wm = display->guard_size;
+ return false;
+ }
diff --git a/config-x86-generic b/config-x86-generic
index b3d19ea..2bcd498 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -45,7 +45,7 @@ CONFIG_FB_EFI=y
CONFIG_INTEL_IOMMU=y
CONFIG_DMAR_BROKEN_GFX_WA=y
CONFIG_INTEL_IOMMU_FLOPPY_WA=y
-CONFIG_INTEL_IOMMU_DEFAULT_ON=y
+# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
CONFIG_SCSI_ADVANSYS=m
CONFIG_SECCOMP=y
diff --git a/kernel.spec b/kernel.spec
index 71033f5..e58f8cb 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 202
+%global baserelease 203
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -780,17 +780,8 @@ Patch21231: 8139cp-revert-set-ring-address-before-enabling-receiver.patch
Patch21232: 8139cp-set-ring-address-after-enabling-C-mode.patch
Patch21233: 8139cp-re-enable-interrupts-after-tx-timeout.patch
-#rhbz 883414
-Patch21234: mac80211-fix-ibss-scanning.patch
-
-#rhbz 873107
-Patch21237: 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch
-
-#rhbz 853064
-Patch21239: aoe-remove-vestigial-request-queue-allocation.patch
-
-#rhbz 890547
-Patch21240: ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch
+#3.7.3 stable queue
+Patch2150: 3.7.3-stable-queue.patch
# END OF PATCH DEFINITIONS
@@ -1511,18 +1502,8 @@ ApplyPatch 8139cp-revert-set-ring-address-before-enabling-receiver.patch -R
ApplyPatch 8139cp-set-ring-address-after-enabling-C-mode.patch
ApplyPatch 8139cp-re-enable-interrupts-after-tx-timeout.patch
-#rhbz 883414
-ApplyPatch mac80211-fix-ibss-scanning.patch
-
-#rhbz 873107
-ApplyPatch 0001-ACPI-sony-laptop-do-proper-memcpy-for-ACPI_TYPE_INTE.patch
-
-#rhbz 853064
-ApplyPatch aoe-remove-vestigial-request-queue-allocation.patch
-
-#rhbz 890547
-ApplyPatch ACPI-do-not-use-Lid-and-Sleep-button-for-S5-wakeup.patch
-
+#3.7.3 stable qeueu
+ApplyPatch 3.7.3-stable-queue.patch
# END OF PATCH APPLICATIONS
@@ -2396,6 +2377,10 @@ fi
# ||----w |
# || ||
%changelog
+* Tue Jan 15 2013 Justin M. Forbes <jforbes at redhat.com> 3.7.2-203
+- Turn off Intel IOMMU by default
+- Stable queue from 3.7.3 with many relevant fixes
+
* Tue Jan 15 2013 Josh Boyer <jwboyer at redhat.com>
- Enable CONFIG_DVB_USB_V2 (rhbz 895460)
More information about the scm-commits
mailing list