From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161824AbWKVC2n (ORCPT ); Tue, 21 Nov 2006 21:28:43 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1161811AbWKVC2n (ORCPT ); Tue, 21 Nov 2006 21:28:43 -0500 Received: from iabervon.org ([66.92.72.58]:59404 "EHLO iabervon.org") by vger.kernel.org with ESMTP id S1161825AbWKVC2m (ORCPT ); Tue, 21 Nov 2006 21:28:42 -0500 Date: Tue, 21 Nov 2006 21:28:41 -0500 (EST) From: Daniel Barkalow To: linux-kernel@vger.kernel.org cc: Jeff Garzik , David Miller , Roland Dreier , Linus Torvalds , Ayaz Abdulla Subject: [PATCH] Disable INTx when enabling MSI in forcedeth Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org My nVidia ethernet card doesn't disable its own INTx when MSI is enabled. This causes a steady stream of spurious interrupts that eventually kills my SATA IRQ if MSI is used with forcedeth, which is true by default. Simply disabling the INTx interrupt takes care of it. This is against -stable, and would be suitable once someone who knows the code verifies that it's correct. Works for me, but I've obviously only tested the codepath where using MSI succeeds. Signed-off-by: Daniel Barkalow --- (cc:s to people who were talking about the existance of devices that misbehave like this) The device in question is: 00:07.0 Bridge: nVidia Corporation MCP61 Ethernet (rev a2) Subsystem: ASUSTeK Computer Inc. Unknown device 8234 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- SERR- msi_flags & NV_MSI_CAPABLE) { + pci_intx(np->pci_dev, 0); if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); + pci_intx(np->pci_dev, 1); np->msi_flags &= ~NV_MSI_ENABLED; goto out_err; } @@ -2706,6 +2708,8 @@ static int nv_request_irq(struct net_dev writel(0, base + NvRegMSIMap1); /* enable msi vector 0 */ writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); + } else { + pci_intx(np->pci_dev, 1); } } if (ret != 0) { -- 1.4.2.4