diff --git a/3.7.3-stable-queue.patch b/3.7.3-stable-queue.patch deleted file mode 100644 index e9b57d5a5..000000000 --- a/3.7.3-stable-queue.patch +++ /dev/null @@ -1,15769 +0,0 @@ -From 13ae633cf729b0ecb677b75b04886ff8fada8fad Mon Sep 17 00:00:00 2001 -From: Mark Brown -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 - -commit 13ae633cf729b0ecb677b75b04886ff8fada8fad upstream. - -Reported-by: Guennadi Liakhovetski -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 10 Dec 2012 16:40:41 +0100 -Subject: ath5k: fix tx path skb leaks - -From: Felix Fietkau - -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 -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 28 Nov 2012 10:51:34 +0200 -Subject: iwlwifi: don't handle masked interrupt - -From: Emmanuel Grumbach - -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 -Reviewed-by: Gregory Greenman -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 2 Dec 2012 09:56:44 +0200 -Subject: iwlwifi: silently ignore fw flaws in Tx path - -From: Emmanuel Grumbach - -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 -Signed-off-by: Emmanuel Grumbach -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 10 Dec 2012 07:53:56 +0100 -Subject: bcma: mips: fix clearing device IRQ - -From: Rafał Miłecki - -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 -Cc: Hauke Mehrtens -Acked-by: Hauke Mehrtens -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Tested-by: Stefan Lippers-Hollmann -Signed-off-by: Helmut Schaa -Acked-by: Gertjan van Wingerde -Acked-by: Stanislaw Gruszka -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 2 Oct 2012 16:25:38 +0200 -Subject: s390/kvm: dont announce RRBM support - -From: Christian Borntraeger - -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 -CC: Alex Graf -Signed-off-by: Christian Borntraeger -Signed-off-by: Marcelo Tosatti -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 15 Nov 2012 09:35:16 +0100 -Subject: s390/kvm: Fix address space mixup - -From: Christian Borntraeger - -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 -Signed-off-by: Martin Schwidefsky -CC: Heiko Carstens -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 11 Nov 2012 19:01:05 +0000 -Subject: powerpc: Fix CONFIG_RELOCATABLE=y CONFIG_CRASH_DUMP=n build - -From: Anton Blanchard - -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 -Signed-off-by: Benjamin Herrenschmidt -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 8 Nov 2012 15:57:49 +0000 -Subject: powerpc/vdso: Remove redundant locking in update_vsyscall_tz() - -From: Shan Hai - -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 -Signed-off-by: Benjamin Herrenschmidt -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 03:44:28 +0000 -Subject: powerpc: Add missing NULL terminator to avoid boot panic on PPC40x - -From: Gabor Juhos - -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 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 -Cc: Grant Likely -Signed-off-by: Benjamin Herrenschmidt -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 22 Aug 2012 15:04:23 +0000 -Subject: KVM: PPC: e500: fix allocation size error on g2h_tlb1_map - -From: Scott Wood - -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 -Signed-off-by: Alexander Graf -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 29 Nov 2012 14:07:59 -0700 -Subject: KVM: Fix user memslot overlap check - -From: Alex Williamson - -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 -Signed-off-by: Marcelo Tosatti -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 30 Nov 2012 16:48:59 +0100 -Subject: s390/cio: fix pgid reserved check - -From: Sebastian Ott - -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 -Signed-off-by: Sebastian Ott -Signed-off-by: Martin Schwidefsky -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 13 Aug 2012 20:52:24 +0800 -Subject: MIPS: Fix poweroff failure when HOTPLUG_CPU configured. - -From: Huacai Chen - -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 -Signed-off-by: Hongliang Tao -Signed-off-by: Hua Yan -Cc: Yong Zhang -Cc: Fuxin Zhang -Cc: Zhangjin Wu -Patchwork: https://patchwork.linux-mips.org/patch/4211/ -Signed-off-by: Ralf Baechle -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 14:31:47 -0800 -Subject: mm: compaction: fix echo 1 > compact_memory return error issue - -From: Jason Liu - -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 -Suggested-by: David Rientjes -Acked-by: Mel Gorman -Cc: Rik van Riel -Cc: Minchan Kim -Cc: KAMEZAWA Hiroyuki -Acked-by: David Rientjes -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 14:31:51 -0800 -Subject: mm: use aligned zone start for pfn_to_bitidx calculation - -From: Laura Abbott - -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 -Acked-by: Mel Gorman -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 14:31:52 -0800 -Subject: mm: bootmem: fix free_all_bootmem_core() with odd bitmap alignment - -From: Max Filippov - -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 -Cc: Gavin Shan -Cc: Johannes Weiner -Cc: Tejun Heo -Cc: Yinghai Lu -Cc: Joonsoo Kim -Cc: Prasad Koya -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 25 Oct 2012 17:11:31 +0530 -Subject: ath9k_hw: Enable hw PLL power save for AR9462 - -From: Rajkumar Manoharan - -commit 1680260226a8fd2aab590319da83ad8e610da9bd upstream. - -This reduced the power consumption to half in full and network sleep. - -Signed-off-by: Rajkumar Manoharan -Cc: Paul Stewart -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 6 Dec 2012 18:40:11 +0100 -Subject: Revert "ath9k_hw: Update AR9003 high_power tx gain table" - -From: Felix Fietkau - -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 -Cc: rmanohar@qca.qualcomm.com -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 9 Dec 2012 23:57:09 +0100 -Subject: ath9k: ar9003: fix OTP register offsets for AR9340 - -From: Gabor Juhos - -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 -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 10 Dec 2012 14:03:17 +0100 -Subject: ath9k_hw: Fix signal strength / channel noise reporting - -From: Felix Fietkau - -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 -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 26 Dec 2012 12:27:39 +0530 -Subject: ath9k_hw: Fix RX gain initvals for AR9485 - -From: Sujith Manoharan - -commit a796a1dd5da9645ad77aa687d1a890ecd63ab5a6 upstream. - -Populate iniModesRxGain with the correct initvals -array for AR9485 v1.1 - -Signed-off-by: Sujith Manoharan -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 3 Dec 2012 12:56:33 +0100 -Subject: mac80211: introduce IEEE80211_HW_TEARDOWN_AGGR_ON_BAR_FAIL - -From: Stanislaw Gruszka - -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 -[replaced link with mid.gmane.org that has message-id] -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 22 Dec 2012 04:35:24 +0100 -Subject: carl9170: fix -EINVAL bailout during init with !CONFIG_MAC80211_MESH - -From: Christian Lamparter - -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 -Signed-off-by: Christian Lamparter -Tested-by: Sean Patrick Santos -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 28 Nov 2012 20:04:32 +0100 -Subject: firewire: net: Fix handling of fragmented multicast/broadcast packets. - -From: Stephan Gatzka - -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 -Signed-off-by: Stefan Richter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 20:51:31 +0100 -Subject: watchdog: Fix disable/enable regression - -From: Bjørn Mork - -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 -Cc: Norbert Warmuth -Cc: Joseph Salisbury -Cc: Thomas Gleixner -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 28 Nov 2012 13:46:56 +0000 -Subject: ASoC: wm8994: Use the same DCS codes for all WM1811 variants - -From: Mark Brown - -commit 72222be39afbd39c16eb180646b0ac44bb1ba460 upstream. - -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 7 Dec 2012 18:30:51 +0100 -Subject: ASoC: sigmadsp: Fix endianness conversion issue - -From: Lars-Peter Clausen - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 24 Nov 2012 11:13:28 +0900 -Subject: regulator: s2mps11: Fix ramp delay value shift operation - -From: Sangbeom Kim - -commit f7ebaaeb0b4b97b20c1816f11884e7bfe610a2fa upstream. - -This patch fix the abnormal ramp delay setting. -The shift operation was wrong. - -Signed-off-by: Sangbeom Kim -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 16 Nov 2012 14:40:03 -0500 -Subject: SCSI: mvsas: fix undefined bit shift - -From: Xi Wang - -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 -Acked-by: Xiangliang Yu -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 15 Nov 2012 15:51:46 -0500 -Subject: SCSI: prevent stack buffer overflow in host_reset - -From: Sasha Levin - -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] [] panic+0xcd/0x1f4 -[ 316.320051] [] ? store_host_reset+0xd7/0x100 -[ 316.320051] [] __stack_chk_fail+0x16/0x20 -[ 316.320051] [] store_host_reset+0xd7/0x100 -[ 316.320051] [] dev_attr_store+0x13/0x30 -[ 316.320051] [] sysfs_write_file+0x101/0x170 -[ 316.320051] [] vfs_write+0xb8/0x180 -[ 316.320051] [] sys_write+0x50/0xa0 -[ 316.320051] [] 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 -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Armen Baloyan -Signed-off-by: Saurav Kashyap -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 21 Nov 2012 02:39:54 -0500 -Subject: SCSI: qla2xxx: Test and clear FCPORT_UPDATE_NEEDED atomically. - -From: David Jeffery - -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 -Signed-off-by: Chad Dupuis -Signed-off-by: Saurav Kashyap -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -commit 220d36b4c2d96446e88d561714829ec5801b4fc7 upstream. - -Signed-off-by: Giridhar Malavali -Signed-off-by: Saurav Kashyap -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -commit 9bceab4e08c5e329e9def7fe1cab41c467236517 upstream. - -Signed-off-by: Steve Hodgson -Signed-off-by: Armen Baloyan -Signed-off-by: Saurav Kashyap -Signed-off-by: James Bottomley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Roland Dreier -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 5 Nov 2012 18:02:42 -0800 -Subject: iscsi-target: Always send a response before terminating iSCSI connection - -From: Roland Dreier - -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 -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 23 Nov 2012 12:07:39 +0800 -Subject: iscsit: use GFP_ATOMIC under spin lock - -From: Wei Yongjun - -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 -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 16 Nov 2012 08:06:17 -0800 -Subject: qla2xxx: Look up LUN for abort requests - -From: Steve Hodgson - -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 -Signed-off-by: Roland Dreier -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 16 Sep 2012 20:53:43 +0200 -Subject: sata_promise: fix hardreset lockdep error - -From: Mikael Pettersson - -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 -Tested-by: Adko Branil -Signed-off-by: Jeff Garzik -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 07:21:09 +0900 -Subject: sony-laptop: fix SNC buffer calls when SN06 returns Integers - -From: Mattia Dongili - -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 -Cc: -Signed-off-by: Mattia Dongili -Signed-off-by: Matthew Garrett -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 27 Nov 2012 16:24:29 +0000 -Subject: IB/mlx4: Fix spinlock order to avoid lockdep warnings - -From: Jack Morgenstein - -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 -Signed-off-by: Or Gerlitz -Signed-off-by: Roland Dreier -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 27 Nov 2012 16:24:30 +0000 -Subject: mlx4_core: Fix potential deadlock in mlx4_eq_int() - -From: Jack Morgenstein - -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 -Signed-off-by: Or Gerlitz -Signed-off-by: Roland Dreier -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 22 Oct 2012 11:19:28 +0200 -Subject: pstore/ram: Fix undefined usage of rounddown_pow_of_two(0) - -From: Maxime Bizon - -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 -Signed-off-by: Florian Fainelli -Acked-by: Kees Cook -Signed-off-by: Anton Vorontsov -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 3 Dec 2012 11:35:02 +0800 -Subject: libata: set dma_mode to 0xff in reset - -From: Aaron Lu - -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 -Signed-off-by: Aaron Lu -Tested-by: Szymon Janc -Tested-by: Dutra Julio -Acked-by: Alan Cox -Signed-off-by: Jeff Garzik -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 13 Dec 2012 16:12:18 +0800 -Subject: libata: fix Null pointer dereference on disk error - -From: Xiaotian Feng - -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 -Cc: James Bottomley -Signed-off-by: Jeff Garzik -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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: [] transport_deregister_session+0x41/0x148 [target_core_mod] -[ 1357.238450] {SOFTIRQ-ON-W} state was registered at: -[ 1357.238450] [] mark_held_locks+0x6d/0x95 -[ 1357.238450] [] trace_hardirqs_on_caller+0x12d/0x197 -[ 1357.238450] [] trace_hardirqs_on+0xd/0xf -[ 1357.238450] [] _raw_spin_unlock_irq+0x2d/0x45 -[ 1357.238450] [] __transport_register_session+0xb8/0x122 [target_core_mod] -[ 1357.238450] [] transport_register_session+0x44/0x5a [target_core_mod] -[ 1357.238450] [] ft_prli+0x1e3/0x275 [tcm_fc] -[ 1357.238450] [] fc_rport_recv_req+0x95e/0xdc5 [libfc] -[ 1357.238450] [] fc_lport_recv_els_req+0xc4/0xd5 [libfc] -[ 1357.238450] [] fc_lport_recv_req+0x12f/0x18f [libfc] -[ 1357.238450] [] fc_exch_recv+0x8ba/0x981 [libfc] -[ 1357.238450] [] fcoe_percpu_receive_thread+0x47a/0x4e2 [fcoe] -[ 1357.238450] [] kthread+0xb1/0xb9 -[ 1357.238450] [] ret_from_fork+0x7c/0xb0 -[ 1357.238450] irq event stamp: 275411 -[ 1357.238450] hardirqs last enabled at (275410): [] rcu_process_callbacks+0x229/0x42a -[ 1357.238450] hardirqs last disabled at (275411): [] _raw_spin_lock_irqsave+0x22/0x8e -[ 1357.238450] softirqs last enabled at (275394): [] __do_softirq+0x246/0x26f -[ 1357.238450] softirqs last disabled at (275399): [] 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] -[ 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] [] print_usage_bug+0x1f5/0x206 -[ 1357.238450] [] ? save_stack_trace+0x2c/0x49 -[ 1357.238450] [] ? print_irq_inversion_bug.part.14+0x1ae/0x1ae -[ 1357.238450] [] mark_lock+0x106/0x258 -[ 1357.238450] [] __lock_acquire+0x2e7/0xe53 -[ 1357.238450] [] ? pvclock_clocksource_read+0x48/0xb4 -[ 1357.238450] [] ? rcu_process_gp_end+0xc0/0xc9 -[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] -[ 1357.238450] [] lock_acquire+0x119/0x143 -[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] -[ 1357.238450] [] _raw_spin_lock_irqsave+0x54/0x8e -[ 1357.238450] [] ? transport_deregister_session+0x41/0x148 [target_core_mod] -[ 1357.238450] [] transport_deregister_session+0x41/0x148 [target_core_mod] -[ 1357.238450] [] ? rcu_process_callbacks+0x229/0x42a -[ 1357.238450] [] ft_sess_rcu_free+0x17/0x24 [tcm_fc] -[ 1357.238450] [] ? ft_sess_free+0x1b/0x1b [tcm_fc] -[ 1357.238450] [] rcu_process_callbacks+0x260/0x42a -[ 1357.238450] [] __do_softirq+0x13a/0x26f -[ 1357.238450] [] ? __schedule+0x65f/0x68e -[ 1357.238450] [] run_ksoftirqd+0x29/0x62 -[ 1357.238450] [] smpboot_thread_fn+0x1a5/0x1aa -[ 1357.238450] [] ? smpboot_unregister_percpu_thread+0x47/0x47 -[ 1357.238450] [] kthread+0xb1/0xb9 -[ 1357.238450] [] ? wait_for_common+0xbb/0x10a -[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 -[ 1357.238450] [] ret_from_fork+0x7c/0xb0 -[ 1357.238450] [] ? __init_kthread_worker+0x59/0x59 -[ 1417.440099] rport-2:0-0: blocked FC remote port time out: removing rport - -Signed-off-by: Yi Zou -Cc: Open-FCoE -Cc: Nicholas A. Bellinger -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 11 Dec 2012 21:58:48 +0000 -Subject: sbp-target: fix error path in sbp_make_tpg() - -From: Chris Boot - -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 -Signed-off-by: Chris Boot -Cc: Andy Grover -Cc: Nicholas A. Bellinger -Signed-off-by: Nicholas Bellinger -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 23 Nov 2012 12:05:33 +0900 -Subject: mfd: wm8994: Add support for WM1811 rev E - -From: Mark Brown - -commit fee546ce8cfd9dea1f53175f627e17ef5ff05df4 upstream. - -This is supported identically to the previous revisions. - -Signed-off-by: Mark Brown -Signed-off-by: Samuel Ortiz -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 9 Nov 2012 16:15:28 +0000 -Subject: mfd: Only unregister platform devices allocated by the mfd core - -From: Charles Keepax - -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 -Tested-by: Peter Tyser -Reviewed-by: Mark Brown -Signed-off-by: Samuel Ortiz -Signed-off-by: Greg Kroah-Hartman - ---- - 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 - #include - -+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 -Date: Mon, 15 Oct 2012 22:44:45 +0200 -Subject: mfd: Remove Unicode Byte Order Marks from da9055 - -From: Geert Uytterhoeven - -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 -Signed-off-by: Samuel Ortiz -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Eugene Shatokhin -Signed-off-by: "Theodore Ts'o" -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 29 Nov 2012 21:21:22 -0500 -Subject: ext4: fix possible use after free with metadata csum - -From: Theodore Ts'o - -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 -Signed-off-by: "Theodore Ts'o" -Acked-by: Darrick J. Wong -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 22 Nov 2012 10:42:52 +1100 -Subject: mtd cs553x_nand: Initialise ecc.strength before nand_scan() - -From: Nathan Williams - -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:[] 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: - [] ? nand_scan+0x1b/0x4d - [] ? init_module+0x25c/0x2de [cs553x_nand] - [] ? 0xd014afff - [] ? do_one_initcall+0x21/0x111 - [] ? sys_init_module+0xe4/0x1261 - [] ? task_work_run+0x36/0x43 - [] ? 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: [] 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 -Acked-by: Brian Norris -Acked-by: Mike Dunn -Signed-off-by: Artem Bityutskiy -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Acked-by: Huang Shijie -Signed-off-by: Artem Bityutskiy -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 29 Oct 2012 11:23:02 +0000 -Subject: kbuild: Do not remove vmlinux when cleaning external module - -From: Pawel Moll - -commit bd1ee804af8bdf2fd5131234330615f8aecbd9ed upstream. - -Since commit 1f2bfbd00e466ff3489b2ca5cc75b1cccd14c123 "kbuild: -link of vmlinux moved to a script" make clean with M= -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 -Signed-off-by: Michal Marek -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 22 Nov 2012 10:39:56 +0200 -Subject: OMAP: board-files: fix i2c_bus for tfp410 - -From: Tomi Valkeinen - -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 -Reported-by: Thomas Weber -Cc: Thomas Weber -Signed-off-by: Tony Lindgren -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 8 Nov 2012 10:01:26 -0500 -Subject: SUNRPC: Fix validity issues with rpc_pipefs sb->s_fs_info - -From: Trond Myklebust - -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 -Cc: Stanislav Kinsbursky -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Trond Myklebust -Signed-off-by: Greg Kroah-Hartman - ---- - 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" -Date: Wed, 14 Nov 2012 10:48:05 -0500 -Subject: svcrpc: Revert "sunrpc/cache.h: replace simple_strtoul" - -From: "J. Bruce Fields" - -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 -Signed-off-by: J. Bruce Fields -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Cc: Weston Andros Adamson -Cc: Tejun Heo -Cc: Bruce Fields -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Trond Myklebust -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 5 Nov 2012 22:40:14 +0400 -Subject: jffs2: hold erase_completion_lock on exit - -From: Alexey Khoroshilov - -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 -Signed-off-by: Artem Bityutskiy -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 14 Dec 2012 13:10:50 +0000 -Subject: i2400m: add Intel 6150 device IDs - -From: Dan Williams - -commit 999a7c5776a0ed2133645fa7e008bec05bda9254 upstream. - -Add device IDs for WiMAX function of Intel 6150 cards. - -Signed-off-by: Dan Williams -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman - ---- - 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" -Date: Wed, 19 Dec 2012 13:25:35 +0000 -Subject: intel-iommu: Free old page tables before creating superpage - -From: "Woodhouse, David" - -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 -Tested-by: Ravi Murty -Tested-by: Sudeep Dutt -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 18 Sep 2012 15:30:44 -0400 -Subject: drm/radeon: stop page faults from hanging the system (v2) - -From: Christian König - -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 -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 13 Nov 2012 18:03:41 -0500 -Subject: drm/radeon/dce32+: use fractional fb dividers for high clocks - -From: Alex Deucher - -commit a02dc74b317d78298cb0587b9b1f6f741fd5c139 upstream. - -Fixes flickering with some high res montiors. - -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 4 Dec 2012 16:50:28 -0500 -Subject: drm/radeon: fix eDP clk and lane setup for scaled modes - -From: Alex Deucher - -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 -Reviewed-by: Jerome Glisse -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 11 Dec 2012 11:56:52 -0500 -Subject: drm/radeon: fix amd afusion gpu setup aka sumo v2 - -From: Jerome Glisse - -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 -Reviewed-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 14 Dec 2012 16:20:46 -0500 -Subject: drm/radeon: restore modeset late in GPU reset path - -From: Jerome Glisse - -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 -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Reviewed-by: Christian König -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 17 Dec 2012 11:04:32 -0500 -Subject: drm/radeon: avoid deadlock in pm path when waiting for fence - -From: Jerome Glisse - -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 -Reviewed-by: Christian König -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 21:19:32 -0500 -Subject: drm/radeon: add WAIT_UNTIL to evergreen VM safe reg list - -From: Alex Deucher - -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 -Reviewed-by: Jerome Glisse -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 16:35:47 -0500 -Subject: drm/radeon: add connector table for Mac G4 Silver - -From: Alex Deucher - -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ß -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 3 Jan 2013 19:09:28 +0100 -Subject: drm/radeon: Properly handle DDC probe for DP bridges - -From: Niels Ole Salscheider - -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 -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 31 Dec 2012 03:34:59 +0200 -Subject: drm/nouveau: fix init with agpgart-uninorth - -From: Aaro Koskinen - -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 -Signed-off-by: Aaro Koskinen -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Reviewed-by: Damien Lespiau -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 14:32:16 -0800 -Subject: mm: compaction: partially revert capture of suitable high-order page - -From: Mel Gorman - -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 -Tested-by: Eric Dumazet -Signed-off-by: Mel Gorman -Cc: David Miller -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -[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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 1 Nov 2012 09:26:26 +0000 -Subject: drm/i915: Flush outstanding unpin tasks before pageflipping - -From: Chris Wilson - -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 -Signed-off-by: Chris Wilson -[danvet: Added note about workqueu deadlock.] -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56337 -Signed-off-by: Daniel Vetter -Tested-by: Daniel Gnoutcheff -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 18 Dec 2012 09:37:54 +0100 -Subject: drm/i915: don't disable disconnected outputs - -From: Daniel Vetter - -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 -Reviewed-by: Rodrigo Vivi -Reviewed-by: Jesse Barnes -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 10:51:09 +1000 -Subject: drm/i915: fix flags in dma buf exporting - -From: Dave Airlie - -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 -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Kyungmin.park -Cc: Inki Dae -Cc: Daniel Vetter -Cc: Rob Clark -Cc: Alex Deucher -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 16:51:06 +0000 -Subject: drm: Only evict the blocks required to create the requested hole - -From: Chris Wilson - -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 -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 -Cc: Daniel Vetter -[danvet: Added note plus bugzilla link and tested-by.] -Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55984 -Tested-by: Norbert Preining -Acked-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 10 Jan 2013 18:03:00 +0100 -Subject: drm/i915: Revert shrinker changes from "Track unbound pages" - -From: Daniel Vetter - -commit 93927ca52a55c23e0a6a305e7e9082e8411ac9fa upstream. - -This partially reverts - -commit 6c085a728cf000ac1865d66f8c9b52935558b328 -Author: Chris Wilson -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 -Tested-by: Dave Kleikamp -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 -Acked-by: Chris Wilson -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -commit 7d9c199a55200c9b9fcad08e150470d02fb385be upstream. - -Signed-off-by: Tatyana Nikolova -Signed-off-by: Roland Dreier -Signed-off-by: CAI Qian -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 6 Dec 2012 19:58:27 +0000 -Subject: RDMA/nes: Fix for terminate timer crash - -From: Tatyana Nikolova - -commit 7bfcfa51c35cdd2d37e0d70fc11790642dd11fb3 upstream. - -The terminate timer needs to be initialized just once. - -Signed-off-by: Tatyana Nikolova -Signed-off-by: Roland Dreier -Signed-off-by: CAI Qian -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 20:23:30 +0000 -Subject: dm: disable WRITE SAME - -From: Mike Snitzer - -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 -Cc: Milan Broz -Signed-off-by: Alasdair G Kergon -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 20:23:30 +0000 -Subject: dm persistent data: rename node to btree_node - -From: Mikulas Patocka - -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 -Signed-off-by: Alasdair G Kergon -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 20:23:30 +0000 -Subject: dm ioctl: prevent unsafe change to dm_ioctl data_size - -From: Alasdair G Kergon - -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 -Signed-off-by: Alasdair G Kergon -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 20:23:31 +0000 -Subject: dm thin: replace dm_cell_release_singleton with cell_defer_except - -From: Joe Thornber - -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 -Signed-off-by: Mike Snitzer -Signed-off-by: Alasdair G Kergon -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 7 Oct 2012 08:27:00 +0100 -Subject: staging: vt6656: [BUG] out of bound array reference in RFbSetPower. - -From: Malcolm Priestley - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 11 Nov 2012 15:32:05 +0000 -Subject: staging: vt6656: 64 bit fixes: use u32 for QWORD definition. - -From: Malcolm Priestley - -commit a552397d5e4ef0cc0bd3e9595d6acc9a3b381171 upstream. - -Size of long issues replace with u32. - -Signed-off-by: Malcolm Priestley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -+ - /******* 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 -Date: Sun, 11 Nov 2012 15:41:25 +0000 -Subject: staging: vt6656: 64 bit fixes : correct all type sizes - -From: Malcolm Priestley - -commit 7730492855a2f9c828599bcd8d62760f96d319e4 upstream. - -After this patch all BYTE/WORD/DWORD types can be replaced with the appropriate u sizes. - -Signed-off-by: Malcolm Priestley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 11 Nov 2012 15:45:52 +0000 -Subject: staging: vt6656: 64 bit fixes: fix long warning messages. - -From: Malcolm Priestley - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -commit c0d05b305b00c698b0a8c1b3d46c9380bce9db45 upstream. - -Fixes long issues. - -Signed-off-by: Malcolm Priestley -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 11 Nov 2012 16:07:57 +0000 -Subject: staging: vt6656: 64bit fixes: vCommandTimerWait change calculation of timer. - -From: Malcolm Priestley - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 01:58:34 -0800 -Subject: hwmon: (lm73} Detect and report i2c bus errors - -From: Chris Verges - -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 -Signed-off-by: Guenter Roeck -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 14:32:05 -0800 -Subject: audit: create explicit AUDIT_SECCOMP event type - -From: Kees Cook - -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 -Cc: Al Viro -Cc: Eric Paris -Cc: Jeff Layton -Cc: "Eric W. Biederman" -Cc: Julien Tinnes -Acked-by: Will Drewry -Acked-by: Steve Grubb -Cc: Andrea Arcangeli -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 7 Jan 2013 05:32:06 +0000 -Subject: xen/netfront: improve truesize tracking - -From: Ian Campbell - -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 -Cc: Sander Eikelenboom -Cc: Konrad Rzeszutek Wilk -Cc: annie li -Cc: xen-devel@lists.xen.org -Cc: netdev@vger.kernel.org -Acked-by: Eric Dumazet -Signed-off-by: David S. Miller -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 18 Dec 2012 13:52:54 +0100 -Subject: cpuidle / coupled: fix ready counter decrement - -From: Sivaram Nair - -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 -Acked-by: Santosh Shilimkar -Acked-by: Colin Cross -Signed-off-by: Rafael J. Wysocki -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 2 Jan 2013 15:12:39 +0100 -Subject: brcmfmac: fix parsing rsn ie for ap mode. - -From: Hante Meuleman - -commit 619c5a9ad54e6bbdafd16d1cdc6c049403710540 upstream. - -RSN IEs got incorrectly parsed and therefore ap mode using WPA2 -security was not working. - -Reviewed-by: Arend Van Spriel -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Acked-by: Juergen Beisert -Tested-by: Lauri Hintsala -Signed-off-by: Shawn Guo -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 5 Dec 2012 16:08:33 -0600 -Subject: samsung-laptop: Add quirk for broken acpi_video backlight on N250P - -From: Seth Forshee - -commit e04c200f1f2de8eaa2f5af6d97e7e213a1abb424 upstream. - -BugLink: http://bugs.launchpad.net/bugs/1086921 -Signed-off-by: Seth Forshee -Signed-off-by: Matthew Garrett -Signed-off-by: Greg Kroah-Hartman - ---- - 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" -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" - -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 -Signed-off-by: Rafael J. Wysocki -Reviewed-by: Ulf Hansson -Reviewed-by: Kevin Hilman -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 17 Dec 2012 09:55:39 -0500 -Subject: ext4: fix extent tree corruption caused by hole punch - -From: Forrest Liu - -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 -Signed-off-by: "Theodore Ts'o" -Reviewed-by: Ashish Sangwan -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 00:07:18 -0500 -Subject: ext4: check dioread_nolock on remount - -From: Jan Kara - -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 -Signed-off-by: "Theodore Ts'o" -Reviewed-by: Eric Sandeen -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 00:15:51 -0500 -Subject: jbd2: fix assertion failure in jbd2_journal_flush() - -From: Jan Kara - -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@empal.com -Signed-off-by: Jan Kara -Signed-off-by: "Theodore Ts'o" -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: "Theodore Ts'o" -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 27 Dec 2012 01:42:48 -0500 -Subject: ext4: lock i_mutex when truncating orphan inodes - -From: Theodore Ts'o - -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 -Signed-off-by: "Theodore Ts'o" -Reviewed-by: Zheng Liu -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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" -Reviewed-by: Zheng Liu -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 6 Jan 2013 23:38:47 -0500 -Subject: ext4: release buffer in failed path in dx_probe() - -From: Guo Chao - -commit 0ecaef0644973e9006fdbc6974301047aaff9bc6 upstream. - -If checksum fails, we should also release the buffer -read from previous iteration. - -Signed-off-by: Guo Chao -Signed-off-by: "Theodore Ts'o" -Reviewed-by: Darrick J. Wong - -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 17 Dec 2012 16:03:58 -0800 -Subject: aoe: remove vestigial request queue allocation - -From: Ed Cashin - -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 -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 10 Oct 2012 00:08:56 +0900 -Subject: udf: fix memory leak while allocating blocks during write - -From: Namjae Jeon - -commit 2fb7d99d0de3fd8ae869f35ab682581d8455887a upstream. - -Need to brelse the buffer_head stored in cur_epos and next_epos. - -Signed-off-by: Namjae Jeon -Signed-off-by: Ashish Sangwan -Signed-off-by: Jan Kara -Signed-off-by: Shuah Khan -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 10 Oct 2012 00:09:12 +0900 -Subject: udf: don't increment lenExtents while writing to a hole - -From: Namjae Jeon - -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 -Signed-off-by: Ashish Sangwan -Signed-off-by: Jan Kara -Signed-off-by: Shuah Khan -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 4 Dec 2012 23:23:16 +0100 -Subject: ACPI : do not use Lid and Sleep button for S5 wakeup - -From: Zhang Rui - -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 -Signed-off-by: Rafael J. Wysocki -Cc: Joseph Salisbury -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 11 Dec 2012 01:14:11 +0900 -Subject: regmap: debugfs: Avoid overflows for very small reads - -From: Mark Brown - -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 -Cc: stable@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 -Date: Tue, 1 Jan 2013 21:20:27 +0000 -Subject: epoll: prevent missed events on EPOLL_CTL_MOD - -From: Eric Wong - -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 -Cc: Hans Verkuil -Cc: Jiri Olsa -Cc: Jonathan Corbet -Cc: Al Viro -Cc: Davide Libenzi -Cc: Hans de Goede -Cc: Mauro Carvalho Chehab -Cc: David Miller -Cc: Eric Dumazet -Cc: Andrew Morton -Cc: Andreas Voellmy -Tested-by: "Junchang(Jason) Wang" -Cc: netdev@vger.kernel.org -Cc: linux-fsdevel@vger.kernel.org -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 24 Nov 2012 06:15:57 +0100 -Subject: HID: add quirk for Freescale i.MX23 ROM recovery - -From: Marek Vasut - -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 -Signed-off-by: Jiri Kosina -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 18 Dec 2012 14:05:01 +0000 -Subject: ASoC: arizona: Correct FLL source definitions - -From: Mark Brown - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 23:29:42 +0800 -Subject: ASoC: arizona: Do proper shift for setting AIF rate - -From: Axel Lin - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 4 Jan 2013 10:48:02 +0000 -Subject: ASoC: arizona: Remove DSP B and left justified AIF modes - -From: Mark Brown - -commit d71753e22b24548911b377db28f80870cf50d07b upstream. - -These are not supported. - -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 4 Jan 2013 21:18:12 +0000 -Subject: ASoC: wm2000: Fix sense of speech clarity enable - -From: Mark Brown - -commit 267f8fa2e1eef0612b2007e1f1846bcbc35cc1fa upstream. - -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 21 Dec 2012 16:28:37 +0800 -Subject: ASoC: wm2200: Fix setting dai format in wm2200_set_fmt - -From: Axel Lin - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 4 Jan 2013 10:48:10 +0000 -Subject: ASoC: wm2200: Remove DSP B and left justified AIF modes - -From: Mark Brown - -commit 0cc411b934c4317b363d1af993549f391852b980 upstream. - -These are not supported. - -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 16:17:25 +0800 -Subject: ASoC: sta529: Fix update register bits in sta529_set_dai_fmt - -From: Axel Lin - -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 -Acked-by: Rajeev Kumar -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 19:36:02 -0800 -Subject: ASoC: pcm: allow backend hardware to be freed in pause state - -From: Patrick Lai - -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 -Acked-by: Liam Girdwood -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 4 Jan 2013 21:06:08 +0000 -Subject: ASoC: wm5100: Remove DSP B and left justified formats - -From: Mark Brown - -commit 5f960294e2031d12f10c8488c3446fecbf59628d upstream. - -These are not supported - -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 11 Jan 2013 12:08:58 +0100 -Subject: udldrmfb: udl_get_edid: drop unneeded i-- - -From: Hans de Goede - -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 -Signed-off-by: Dave Airlie -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 14 Jan 2013 13:17:50 -0800 -Subject: vfs: add missing virtual cache flush after editing partial pages - -From: Linus Torvalds - -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 -Signed-off-by: Linus Torvalds -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Takashi Iwai -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 8 Jan 2013 13:51:30 +0100 -Subject: ALSA: hda - Disable runtime D3 for Intel CPT & co - -From: Takashi Iwai - -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 -Reported-and-tested-by: Maurizio Avogadro -Signed-off-by: Takashi Iwai -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 7 Jan 2013 13:55:12 -0800 -Subject: ALSA: pxa27x: fix ac97 cold reset - -From: Mike Dunn - -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 -Acked-by: Igor Grinberg -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 7 Jan 2013 13:55:13 -0800 -Subject: ALSA: pxa27x: fix ac97 warm reset - -From: Mike Dunn - -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 -Signed-off-by: Igor Grinberg -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 - #include - #include -+#include - - #include - #include -@@ -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 -Date: Tue, 4 Dec 2012 15:59:55 +0000 -Subject: staging: comedi: prevent auto-unconfig of manually configured devices - -From: Ian Abbott - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Acked-By: Ian Abbott -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 3 Jan 2013 12:15:26 +0000 -Subject: staging: comedi: Kconfig: COMEDI_NI_AT_A2150 should select COMEDI_FC - -From: Ian Abbott - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 4 Jan 2013 11:33:21 +0000 -Subject: staging: comedi: comedi_test: fix race when cancelling command - -From: Ian Abbott - -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 -Reported-by: Éric Piel -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 29 Dec 2012 11:36:53 -0600 -Subject: staging: r8712u: Add new device ID - -From: Larry Finger - -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 -Signed-off-by: Larry Finger -Cc: Thomas Hartmann -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 5 Jan 2013 14:17:45 -0500 -Subject: staging: speakup: avoid out-of-range access in synth_init() - -From: Nickolai Zeldovich - -commit ae428655b826f2755a8101b27beda42a275ef8ad upstream. - -Check that array index is in-bounds before accessing the synths[] array. - -Signed-off-by: Nickolai Zeldovich -Cc: Samuel Thibault -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 7 Jan 2013 22:03:51 +0100 -Subject: staging: speakup: avoid out-of-range access in synth_add() - -From: Samuel Thibault - -commit 6102c48bd421074a33e102f2ebda3724e8d275f9 upstream. - -Check that array index is in-bounds before accessing the synths[] array. - -Signed-off-by: Samuel Thibault -Cc: Nickolai Zeldovich -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 30 Oct 2012 22:40:23 +0300 -Subject: staging: zram: factor-out zram_decompress_page() function - -From: Sergey Senozhatsky - -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 -Reviewed-by: Nitin Gupta -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 2 Jan 2013 08:53:41 -0800 -Subject: staging: zram: fix invalid memory references during disk write - -From: Nitin Gupta - -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 -Reported-by: Mihail Kasadjikov -Reported-by: Tomas M -Reviewed-by: Minchan Kim -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Alex Deucher -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 27 Dec 2012 21:37:04 +0100 -Subject: iwlwifi: fix PCIe interrupt handle return value - -From: Johannes Berg - -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 -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 31 Dec 2012 09:26:10 +0200 -Subject: iwlwifi: fix the reclaimed packet tracking upon flush queue - -From: Emmanuel Grumbach - -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 -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 11 Dec 2012 10:48:23 +0100 -Subject: mac80211: fix ibss scanning - -From: Stanislaw Gruszka - -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 -Reported-by: Mikko Rapeli -Signed-off-by: Stanislaw Gruszka -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 13 Dec 2012 22:54:58 +0100 -Subject: mac80211: fix station destruction in AP/mesh modes - -From: Johannes Berg - -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 -Tested-by: Ben Greear -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 13 Dec 2012 23:08:52 +0100 -Subject: mac80211: use del_timer_sync for final sta cleanup timer deletion - -From: Johannes Berg - -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 -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 2 Jan 2013 16:07:35 -0800 -Subject: mwifiex: check wait_event_interruptible return value - -From: Bing Zhao - -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 -Signed-off-by: Amitkumar Karwar -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 15:55:01 -0600 -Subject: b43: Fix firmware loading when driver is built into the kernel - -From: Larry Finger - -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 -Signed-off-by: Larry Finger -Signed-off-by: John W. Linville -Signed-off-by: Greg Kroah-Hartman - ---- - 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 - #include - #include -+#include - #include - - #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 -Date: Mon, 3 Dec 2012 16:06:26 +0300 -Subject: USB: option: add Nexpring NP10T terminal id - -From: Dzianis Kahanovich - -commit ad86e58661b38b279b7519d4e49c7a19dc1654bb upstream. - -Hyundai Petatel Inc. Nexpring NP10T terminal (EV-DO rev.A USB modem) ID - -Signed-off-by: Denis Kaganovich -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 15:15:17 +0100 -Subject: USB: option: blacklist network interface on ZTE MF880 - -From: Bjørn Mork - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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" -Date: Wed, 26 Dec 2012 16:58:22 +0800 -Subject: USB: option: Add new MEDIATEK PID support - -From: "Quentin.Li" - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 28 Dec 2012 17:29:52 +0100 -Subject: USB: option: add Telekom Speedstick LTE II - -From: Bjørn Mork - -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 -Signed-off-by: Bjørn Mork -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 13 Jan 2013 23:32:53 +0100 -Subject: usb: ftdi_sio: Crucible Technologies COMET Caller ID - pid added - -From: Tomasz Mloduchowski - -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 -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 26 Dec 2012 18:29:44 +0500 -Subject: USB: cdc-acm: Add support for "PSC Scanning, Magellan 800i" - -From: Denis N Ladin - -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 -Acked-by: Oliver Neukum -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 20 Nov 2012 13:23:15 +0100 -Subject: usb: gadget: dummy: fix enumeration with g_multi - -From: Sebastian Andrzej Siewior - -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 -Acked-by: Alan Stern -Signed-off-by: Felipe Balbi -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 18:49:50 +0300 -Subject: usb: musb: core: print new line in the driver banner again - -From: Sergei Shtylyov - -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 -Signed-off-by: Felipe Balbi -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 25 Dec 2012 18:13:22 +0100 -Subject: drm/nv17-50: restore fence buffer on resume - -From: Marcin Slusarz - -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 -Signed-off-by: Ben Skeggs -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 18 Dec 2012 20:30:47 +0100 -Subject: drm/nouveau: fix blank LVDS screen regression on pre-nv50 cards - -From: Marcin Slusarz - -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 -Signed-off-by: Marcin Slusarz -Signed-off-by: Ben Skeggs -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sun, 2 Dec 2012 12:56:22 +0100 -Subject: drm/nouveau: add locking around instobj list operations - -From: Marcin Slusarz - -commit 4c4101d29fb6c63f78791d02c437702b11e1d4f0 upstream. - -Fixes memory corruptions, oopses, etc. when multiple gpuobjs are -simultaneously created or destroyed. - -Signed-off-by: Marcin Slusarz -Signed-off-by: Ben Skeggs -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Tested-by: Aleksi Torhamo -Tested-by: Sean Santos -Signed-off-by: Ben Skeggs -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Reported-by: Roy Spliet -Tested-by: Roy Spliet -Signed-off-by: Ben Skeggs -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 15:58:52 -0800 -Subject: USB: Handle auto-transition from hot to warm reset. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 5 Dec 2012 16:17:49 +0100 -Subject: USB: Add device quirk for Microsoft VX700 webcam - -From: Andreas Fleig - -commit bc009eca8d539162f7271c2daf0ab5e9e3bb90a0 upstream. - -Add device quirk for Microsoft Lifecam VX700 v2.0 webcams. -Fixes squeaking noise of the microphone. - -Signed-off-by: Andreas Fleig -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 16:10:49 -0800 -Subject: USB: Ignore xHCI Reset Device status. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 16:42:32 -0800 -Subject: USB: Allow USB 3.0 ports to be disabled. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Reported-by: John Covici -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 17:16:52 -0800 -Subject: USB: Increase reset timeout. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Reported-by: John Covici -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 15 Nov 2012 14:58:04 -0800 -Subject: USB: Ignore port state until reset completes. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 14 Nov 2012 17:58:04 -0800 -Subject: USB: Handle warm reset failure on empty port. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Reported-by: John Covici -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Tue, 27 Nov 2012 12:30:23 -0800 -Subject: xhci: Avoid "dead ports", add roothub port polling. - -From: Sarah Sharp - -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 -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 29 Nov 2012 15:05:57 +0100 -Subject: USB: hub: handle claim of enabled remote wakeup after reset - -From: Oliver Neukum - -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 -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 17 Dec 2012 14:12:35 -0800 -Subject: xhci: Handle HS bulk/ctrl endpoints that don't NAK. - -From: Sarah Sharp - -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 -Suggested-by: Alan Stern -Signed-off-by: Sarah Sharp -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 16:15:56 +0000 -Subject: USB: ehci: make debug port in-use detection functional again - -From: Jan Beulich - -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 -Cc: Konrad Rzeszutek Wilk -Acked-by: Alan Stern -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 28 Dec 2012 17:09:03 +0800 -Subject: regulator: max8997: Use uV in voltage_map_desc - -From: Axel Lin - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 28 Dec 2012 17:10:20 +0800 -Subject: regulator: max8998: Use uV in voltage_map_desc - -From: Axel Lin - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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 -Signed-off-by: Mark Brown -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Thu, 20 Dec 2012 12:47:51 +0100 -Subject: Revert "MIPS: Optimise TLB handlers for MIPS32/64 R2 cores." - -From: Ralf Baechle - -commit 9120963578320532dfb3a9a7947e8d05b39900b5 upstream. - -This reverts commit ff401e52100dcdc85e572d1ad376d3307b3fe28e. - -This breaks on MIPS64 R2 cores such as Broadcom's. - -Signed-off-by: Jayachandran C -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -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: - [] schedule+0x29/0x70 - [] schedule_timeout+0x195/0x220 - [] ? _dm_request+0x111/0x160 [dm_mod] - [] wait_for_common+0x11e/0x190 - [] ? try_to_wake_up+0x2b0/0x2b0 - [] wait_for_completion+0x1d/0x20 - [] blkdev_issue_discard+0x219/0x260 - [] blkdev_ioctl+0x6e9/0x7b0 - [] block_ioctl+0x3c/0x40 - [] do_vfs_ioctl+0x8c/0x340 - [] ? block_llseek+0x67/0xb0 - [] sys_ioctl+0xa1/0xb0 - [] ? sys_rt_sigprocmask+0x86/0xd0 - [] 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 -Signed-off-by: Mike Snitzer -Signed-off-by: Alasdair G Kergon -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -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 - -commit ab9d6e4ffe192427ce9e93d4f927b0faaa8a941e upstream. - -This revert: - -commit be03d4a45c09ee5100d3aaaedd087f19bc20d01f -Author: Andreas Hartmann -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 -Signed-off-by: Stanislaw Gruszka -Signed-off-by: Johannes Berg -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 14 Dec 2012 15:03:10 +0400 -Subject: EDAC: Fix kernel panic on module unloading - -From: Konstantin Khlebnikov - -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 -Cc: Denis Kirjanov -Cc: Mauro Carvalho Chehab -Link: http://lkml.kernel.org/r/20121214110310.11019.21098.stgit@zurg -Signed-off-by: Borislav Petkov -[ a partial 3.7.y backport ] -Signed-off-by: Borislav Petkov -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 8 Dec 2012 12:58:33 +0100 -Subject: drm/i915: disable cpt phase pointer fdi rx workaround - -From: Daniel Vetter - -commit 539526b4137bc0e7a8806c38c8522f226814a0e6 upstream. - -We've originally added this in - -commit 291427f5fdadec6e4be2924172e83588880e1539 -Author: Jesse Barnes -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 -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 -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" -Cc: stable@vger.kernel.org -Reviewed-by: Jesse Barnes -Signed-off-by: Daniel Vetter -Signed-off-by: CAI Qian -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Sat, 6 Oct 2012 03:56:35 +0200 -Subject: KVM: PPC: 44x: fix DCR read/write - -From: Alexander Graf - -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 -Signed-off-by: CAI Qian -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Fri, 7 Dec 2012 19:50:07 -0600 -Subject: libceph: socket can close in any connection state - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Fri, 14 Dec 2012 16:47:41 -0600 -Subject: libceph: report connection fault with warning - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Thu, 6 Dec 2012 07:22:04 -0600 -Subject: libceph: init osd->o_node in create_osd() - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Mon, 17 Dec 2012 12:23:48 -0600 -Subject: libceph: init event->node in ceph_osdc_create_event() - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -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 - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Thu, 6 Dec 2012 07:22:04 -0600 -Subject: libceph: register request before unregister linger - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 19 Dec 2012 15:52:36 -0600 -Subject: libceph: move linger requests sooner in kick_requests() - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 26 Dec 2012 14:31:40 -0600 -Subject: libceph: always reset osds when kicking - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 26 Dec 2012 10:43:57 -0600 -Subject: libceph: WARN, don't BUG on unexpected connection states - -From: Alex Elder - -(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 -Tested-by: Ugis -Signed-off-by: Alex Elder -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -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 - -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 -References: http://permalink.gmane.org/gmane.comp.freedesktop.xorg.drivers.intel/17237 -Signed-off-by: Daniel Vetter -Cc: Luis Henriques -Signed-off-by: Greg Kroah-Hartman - - ---- - 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 -Date: Thu, 27 Dec 2012 20:27:04 -0600 -Subject: libceph: fix protocol feature mismatch failure path - - -From: Sage Weil - -(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 -Reviewed-by: Alex Elder -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Mon, 29 Oct 2012 11:01:42 -0700 -Subject: libceph: fix osdmap decode error paths - - -From: Sage Weil - -(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 -Reviewed-by: Alex Elder -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Fri, 7 Dec 2012 09:57:58 -0600 -Subject: libceph: avoid using freed osd in __kick_osd_requests() - - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 28 Nov 2012 12:28:24 -0800 -Subject: libceph: remove 'osdtimeout' option - - -From: Sage Weil - -(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 -Reviewed-by: Alex Elder -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Thu, 29 Nov 2012 08:37:03 -0600 -Subject: ceph: don't reference req after put - - -From: Alex Elder - -(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 -Reviewed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 10 Oct 2012 21:19:13 -0700 -Subject: rbd: fix bug in rbd_dev_id_put() - - -From: Alex Elder - -(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 -Reviewed-by: Josh Durgin -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Wed, 10 Oct 2012 21:19:13 -0700 -Subject: rbd: zero return code in rbd_dev_image_id() - - -From: Alex Elder - -(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 -Reviewed-by: Josh Durgin -Reviewed-by: Dan Mick -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Mon, 22 Oct 2012 11:31:26 -0500 -Subject: rbd: fix read-only option name - - -From: Alex Elder - -(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 -Reviewed-by: Dan Mick -Reviewed-by: Josh Durgin -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Tue, 3 Jul 2012 16:01:19 -0500 -Subject: rbd: increase maximum snapshot name length - - -From: Alex Elder - -(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 -Reviewed-by: Dan Mick -Reviewed-by: Josh Durgin -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Thu, 25 Oct 2012 23:34:40 -0500 -Subject: rbd: remove snapshots on error in rbd_add() - - -From: Alex Elder - -(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 -Reviewed-by: Josh Durgin -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Fri, 16 Nov 2012 09:29:16 -0600 -Subject: rbd: do not allow remove of mounted-on image - - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Fri, 9 Nov 2012 15:05:54 -0600 -Subject: rbd: get rid of RBD_MAX_SEG_NAME_LEN - - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Thu, 6 Dec 2012 09:37:23 -0600 -Subject: rbd: remove linger unconditionally - - -From: Alex Elder - -(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 -Reviewed-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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" -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" - -(cherry picked from commit 5e62ad30157d0da04cf40c6d1a2f4bc840948b9c) - -The cap from non-auth mds doesn't have a meaningful max_size value. - -Signed-off-by: Yan, Zheng -Signed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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" -Date: Mon, 19 Nov 2012 10:49:06 +0800 -Subject: ceph: Fix infinite loop in __wake_requests - - -From: "Yan, Zheng" - -(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 -Signed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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" -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" - -(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 -Signed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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" -Date: Mon, 19 Nov 2012 10:49:08 +0800 -Subject: ceph: Fix __ceph_do_pending_vmtruncate - - -From: "Yan, Zheng" - -(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 -Signed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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" -Date: Mon, 19 Nov 2012 10:49:09 +0800 -Subject: ceph: call handle_cap_grant() for cap import message - - -From: "Yan, Zheng" - -(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 -Signed-off-by: Sage Weil -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Mon, 3 Dec 2012 19:14:05 -0800 -Subject: libceph: Unlock unprocessed pages in start_read() error path - - -From: David Zafman - -(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 -Reviewed-by: Alex Elder -Signed-off-by: Greg Kroah-Hartman ---- - 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 -Date: Fri, 23 Nov 2012 18:16:34 +0100 -Subject: drm/i915: force restore on lid open - -From: Daniel Vetter - -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 -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 -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 -Reviewed-by: Jesse Barnes -Signed-off-by: Daniel Vetter -Signed-off-by: CAI Qian -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Wed, 19 Dec 2012 11:03:41 +0100 -Subject: i915: ensure that VGA plane is disabled - -From: Krzysztof Mazur - -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 -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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 -Date: Mon, 7 Jan 2013 10:11:40 +0000 -Subject: drm/i915: Treat crtc->mode.clock == 0 as disabled - -From: Chris Wilson - -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 -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 -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 -Reported-and-tested-by: Alexey Zaytsev -Tested-by: Sedat Dilek -Cc: Daniel Vetter -Cc: Jesse Barnes -Signed-off-by: Daniel Vetter -Signed-off-by: Greg Kroah-Hartman - ---- - 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; - }