From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:56112) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXSiu-0002Cs-DO for qemu-devel@nongnu.org; Thu, 24 May 2012 03:44:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SXSin-0001p0-3F for qemu-devel@nongnu.org; Thu, 24 May 2012 03:44:39 -0400 Received: from mail-gg0-f173.google.com ([209.85.161.173]:47383) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SXSim-0001og-WB for qemu-devel@nongnu.org; Thu, 24 May 2012 03:44:33 -0400 Received: by ggnp1 with SMTP id p1so9082866ggn.4 for ; Thu, 24 May 2012 00:44:31 -0700 (PDT) Message-ID: <4FBDE6D6.80700@ozlabs.ru> Date: Thu, 24 May 2012 17:44:22 +1000 From: Alexey Kardashevskiy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [RFC PATCH] PCI: Introduce INTx check & mask API List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex Williamson , Benjamin Herrenschmidt Alex Williamson , David Gibson , Alex Graf , kvm@vger.kernel.org, qemu-devel@nongnu.org [Found while debugging VFIO on POWER but it is platform independent] There is a feature in PCI (>=2.3?) to mask/unmask INTx via PCI_COMMAND and PCI_STATUS registers. And there is some API to support that (commit a2e27787f893621c5a6b865acf6b7766f8671328). I have a network adapter: 0001:00:01.0 Ethernet controller: Chelsio Communications Inc T310 10GbE Single Port Adapter Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- --- drivers/pci/pci.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ab6c2a6..ee4c804 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2978,60 +2978,60 @@ EXPORT_SYMBOL_GPL(pci_intx_mask_supported); static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask) { struct pci_bus *bus = dev->bus; bool mask_updated = true; u32 cmd_status_dword; u16 origcmd, newcmd; unsigned long flags; bool irq_pending; /* * We do a single dword read to retrieve both command and status. * Document assumptions that make this possible. */ BUILD_BUG_ON(PCI_COMMAND % 4); BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS); raw_spin_lock_irqsave(&pci_lock, flags); bus->ops->read(bus, dev->devfn, PCI_COMMAND, 4, &cmd_status_dword); irq_pending = (cmd_status_dword >> 16) & PCI_STATUS_INTERRUPT; /* * Check interrupt status register to see whether our device * triggered the interrupt (when masking) or the next IRQ is * already pending (when unmasking). */ - if (mask != irq_pending) { +/* if (mask != irq_pending) { mask_updated = false; goto done; - } + }*/ origcmd = cmd_status_dword; newcmd = origcmd & ~PCI_COMMAND_INTX_DISABLE; if (mask) newcmd |= PCI_COMMAND_INTX_DISABLE; if (newcmd != origcmd) bus->ops->write(bus, dev->devfn, PCI_COMMAND, 2, newcmd); done: raw_spin_unlock_irqrestore(&pci_lock, flags); return mask_updated; } /** * pci_check_and_mask_intx - mask INTx on pending interrupt * @dev: the PCI device to operate on * * Check if the device dev has its INTx line asserted, mask it and * return true in that case. False is returned if not interrupt was * pending. */ bool pci_check_and_mask_intx(struct pci_dev *dev) { return pci_check_and_set_intx_mask(dev, true); } EXPORT_SYMBOL_GPL(pci_check_and_mask_intx); -- 1.7.7.3