linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Gavin Shan <shangw@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Gavin Shan <shangw@linux.vnet.ibm.com>
Subject: [PATCH 07/10] powerpc/powernv: Block PCI-CFG access if necessary
Date: Tue, 25 Jun 2013 13:55:14 +0800	[thread overview]
Message-ID: <1372139717-14885-8-git-send-email-shangw@linux.vnet.ibm.com> (raw)
In-Reply-To: <1372139717-14885-1-git-send-email-shangw@linux.vnet.ibm.com>

If the PCI-CFG access on the specific PHB, to return 0xFF's for
reading and drop writing. The patch implements that for PowerNV
platform. The patch also removes the check on "hose == NULL"
for PCI-CFG accessors since the kernel should stop while fetching
platform-dependent PHB (struct pnv_phb).

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-powernv.c |   10 ++---
 arch/powerpc/platforms/powernv/pci.c         |   59 ++++++++++++++++++++------
 arch/powerpc/platforms/powernv/pci.h         |    4 ++
 3 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
index 20a7865..249798e 100644
--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
+++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
@@ -328,9 +328,9 @@ static int powernv_eeh_read_config(struct device_node *dn, int where,
 {
 	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
 	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	struct pci_controller *hose = edev->phb;
 
-	return hose->ops->read(dev->bus, dev->devfn, where, size, val);
+	return pnv_pci_cfg_read(dev->bus, dev->devfn,
+				where, size, val, false);
 }
 
 /**
@@ -347,11 +347,9 @@ static int powernv_eeh_write_config(struct device_node *dn, int where,
 {
 	struct eeh_dev *edev = of_node_to_eeh_dev(dn);
 	struct pci_dev *dev = eeh_dev_to_pci_dev(edev);
-	struct pci_controller *hose = edev->phb;
 
-	hose = pci_bus_to_host(dev->bus);
-
-	return hose->ops->write(dev->bus, dev->devfn, where, size, val);
+	return pnv_pci_cfg_write(dev->bus, dev->devfn,
+				 where, size, val, false);
 }
 
 /**
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 1f31826..47fa921 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -255,21 +255,30 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, struct pci_bus *bus,
 		pnv_pci_handle_eeh_config(phb, pe_no);
 }
 
-static int pnv_pci_read_config(struct pci_bus *bus,
-			       unsigned int devfn,
-			       int where, int size, u32 *val)
+int pnv_pci_cfg_read(struct pci_bus *bus,
+		     unsigned int devfn,
+		     int where, int size,
+		     u32 *val, bool check)
 {
 	struct pci_controller *hose = pci_bus_to_host(bus);
 	struct pnv_phb *phb = hose->private_data;
+	u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
+	s64 rc;
 #ifdef CONFIG_EEH
 	struct device_node *busdn, *dn;
 	struct eeh_pe *phb_pe = NULL;
-#endif
-	u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
-	s64 rc;
 
-	if (hose == NULL)
+	/*
+	 * If PCI-CFG access has been blocked, we simply
+	 * return 0xFF's here.
+	 */
+	if (check &&
+	    (phb->eeh_state & PNV_EEH_STATE_ENABLED) &&
+	    (phb->eeh_state & PNV_EEH_STATE_CFG_BLOCKED)) {
+		*val = 0xFFFFFFFF;
 		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+#endif
 
 	switch (size) {
 	case 1: {
@@ -329,19 +338,26 @@ static int pnv_pci_read_config(struct pci_bus *bus,
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int pnv_pci_write_config(struct pci_bus *bus,
-				unsigned int devfn,
-				int where, int size, u32 val)
+int pnv_pci_cfg_write(struct pci_bus *bus,
+		      unsigned int devfn,
+		      int where, int size,
+		      u32 val, bool check)
 {
 	struct pci_controller *hose = pci_bus_to_host(bus);
 	struct pnv_phb *phb = hose->private_data;
 	u32 bdfn = (((uint64_t)bus->number) << 8) | devfn;
 
-	if (hose == NULL)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
 	cfg_dbg("pnv_pci_write_config bus: %x devfn: %x +%x/%x -> %08x\n",
 		bus->number, devfn, where, size, val);
+
+#ifdef CONFIG_EEH
+	/* If PCI-CFG access has been blocked, drop it */
+	if (check &&
+	    (phb->eeh_state & PNV_EEH_STATE_ENABLED) &&
+	    (phb->eeh_state & PNV_EEH_STATE_CFG_BLOCKED))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+#endif
+
 	switch (size) {
 	case 1:
 		opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
@@ -367,6 +383,23 @@ static int pnv_pci_write_config(struct pci_bus *bus,
 	return PCIBIOS_SUCCESSFUL;
 }
 
+static int pnv_pci_read_config(struct pci_bus *bus,
+			       unsigned int devfn,
+			       int where, int size, u32 *val)
+{
+	return pnv_pci_cfg_read(bus, devfn, where,
+				size, val, true);
+}
+
+static int pnv_pci_write_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where, int size,
+				u32 val)
+{
+	return pnv_pci_cfg_write(bus, devfn, where,
+				 size, val, true);
+}
+
 struct pci_ops pnv_pci_ops = {
 	.read = pnv_pci_read_config,
 	.write = pnv_pci_write_config,
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
index a281a1c..8624f8f 100644
--- a/arch/powerpc/platforms/powernv/pci.h
+++ b/arch/powerpc/platforms/powernv/pci.h
@@ -187,6 +187,10 @@ extern struct pci_ops pnv_pci_ops;
 extern struct pnv_eeh_ops ioda_eeh_ops;
 #endif
 
+extern int pnv_pci_cfg_read(struct pci_bus *bus, unsigned int devfn,
+			    int where, int size, u32 *val, bool check);
+extern int pnv_pci_cfg_write(struct pci_bus *bus, unsigned int devfn,
+			     int where, int size, u32 val, bool check);
 extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
 				      void *tce_mem, u64 tce_size,
 				      u64 dma_offset);
-- 
1.7.5.4

  parent reply	other threads:[~2013-06-25  5:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-25  5:55 [PATCH v1 00/10] powerpc/eeh: Remove eeh_mutex Gavin Shan
2013-06-25  5:55 ` [PATCH 01/10] " Gavin Shan
2013-06-25  5:55 ` [PATCH 02/10] powerpc/eeh: Don't collect PCI-CFG data on PHB Gavin Shan
2013-06-25  5:55 ` [PATCH 03/10] powerpc/eeh: Check PCIe link after reset Gavin Shan
2013-06-25  6:06   ` Benjamin Herrenschmidt
2013-06-25  7:47     ` Gavin Shan
2013-06-25  7:57       ` Benjamin Herrenschmidt
2013-06-25  8:04         ` Gavin Shan
2013-06-25  5:55 ` [PATCH 04/10] powerpc/eeh: Backends to get/set settings Gavin Shan
2013-06-25  6:07   ` Benjamin Herrenschmidt
2013-06-25  7:12     ` Gavin Shan
2013-06-25  5:55 ` [PATCH 05/10] powerpc/powernv: Support set/get EEH settings Gavin Shan
2013-06-25  5:55 ` [PATCH 06/10] powerpc/eeh: Support blocked IO access Gavin Shan
2013-06-25  5:55 ` Gavin Shan [this message]
2013-06-25  5:55 ` [PATCH 08/10] powerpc/powernv: Hold PCI-CFG and I/O access Gavin Shan
2013-06-25  5:55 ` [PATCH 09/10] powerpc/eeh: Fix address catch for PowerNV Gavin Shan
2013-06-25  5:55 ` [PATCH 10/10] net/tg3: Avoid delay during MMIO access Gavin Shan
2013-06-25  6:15   ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1372139717-14885-8-git-send-email-shangw@linux.vnet.ibm.com \
    --to=shangw@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).