[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