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
next prev 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).