From: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
To: <linux-pci@vger.kernel.org>, <linuxppc-dev@lists.ozlabs.org>
Cc: Bjorn Helgaas <helgaas@kernel.org>, <linux@yadro.com>,
Sergey Miroshnichenko <s.miroshnichenko@yadro.com>,
Oliver O'Halloran <oohall@gmail.com>
Subject: [PATCH v6 21/30] powerpc/pci: Access PCI config space directly w/o pci_dn
Date: Thu, 24 Oct 2019 20:12:19 +0300 [thread overview]
Message-ID: <20191024171228.877974-22-s.miroshnichenko@yadro.com> (raw)
In-Reply-To: <20191024171228.877974-1-s.miroshnichenko@yadro.com>
To fetch an updated DT for the newly hotplugged device, OS must explicitly
request it from the firmware via the pnv_php driver.
If pnv_php wasn't triggered/loaded, it is still possible to discover new
devices if PCIe I/O will not stop in absence of the pci_dn structure.
Reviewed-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Sergey Miroshnichenko <s.miroshnichenko@yadro.com>
---
arch/powerpc/kernel/rtas_pci.c | 97 +++++++++++++++++++---------
arch/powerpc/platforms/powernv/pci.c | 64 ++++++++++++------
2 files changed, 109 insertions(+), 52 deletions(-)
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index ae5e43eaca48..912da28b3737 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -42,10 +42,26 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
return 0;
}
-int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+static int rtas_read_raw_config(unsigned long buid, int busno, unsigned int devfn,
+ int where, int size, u32 *val)
{
int returnval = -1;
- unsigned long buid, addr;
+ unsigned long addr = rtas_config_addr(busno, devfn, where);
+ int ret;
+
+ if (buid) {
+ ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
+ addr, BUID_HI(buid), BUID_LO(buid), size);
+ } else {
+ ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
+ }
+ *val = returnval;
+
+ return ret;
+}
+
+int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
+{
int ret;
if (!pdn)
@@ -58,16 +74,8 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
return PCIBIOS_SET_FAILED;
#endif
- addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
- buid = pdn->phb->buid;
- if (buid) {
- ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
- addr, BUID_HI(buid), BUID_LO(buid), size);
- } else {
- ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
- }
- *val = returnval;
-
+ ret = rtas_read_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
+ where, size, val);
if (ret)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -85,18 +93,44 @@ static int rtas_pci_read_config(struct pci_bus *bus,
pdn = pci_get_pdn_by_devfn(bus, devfn);
- /* Validity of pdn is checked in here */
- ret = rtas_read_config(pdn, where, size, val);
- if (*val == EEH_IO_ERROR_VALUE(size) &&
- eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
- return PCIBIOS_DEVICE_NOT_FOUND;
+ if (pdn) {
+ /* Validity of pdn is checked in here */
+ ret = rtas_read_config(pdn, where, size, val);
+
+ if (*val == EEH_IO_ERROR_VALUE(size) &&
+ eeh_dev_check_failure(pdn_to_eeh_dev(pdn)))
+ ret = PCIBIOS_DEVICE_NOT_FOUND;
+ } else {
+ struct pci_controller *phb = pci_bus_to_host(bus);
+
+ ret = rtas_read_raw_config(phb->buid, bus->number, devfn,
+ where, size, val);
+ }
return ret;
}
+static int rtas_write_raw_config(unsigned long buid, int busno, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ unsigned long addr = rtas_config_addr(busno, devfn, where);
+ int ret;
+
+ if (buid) {
+ ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
+ BUID_HI(buid), BUID_LO(buid), size, (ulong)val);
+ } else {
+ ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
+ }
+
+ if (ret)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
{
- unsigned long buid, addr;
int ret;
if (!pdn)
@@ -109,15 +143,8 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
return PCIBIOS_SET_FAILED;
#endif
- addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
- buid = pdn->phb->buid;
- if (buid) {
- ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
- BUID_HI(buid), BUID_LO(buid), size, (ulong) val);
- } else {
- ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
- }
-
+ ret = rtas_write_raw_config(pdn->phb->buid, pdn->busno, pdn->devfn,
+ where, size, val);
if (ret)
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -128,12 +155,20 @@ static int rtas_pci_write_config(struct pci_bus *bus,
unsigned int devfn,
int where, int size, u32 val)
{
- struct pci_dn *pdn;
+ struct pci_dn *pdn = pci_get_pdn_by_devfn(bus, devfn);
+ int ret;
- pdn = pci_get_pdn_by_devfn(bus, devfn);
+ if (pdn) {
+ /* Validity of pdn is checked in here. */
+ ret = rtas_write_config(pdn, where, size, val);
+ } else {
+ struct pci_controller *phb = pci_bus_to_host(bus);
- /* Validity of pdn is checked in here. */
- return rtas_write_config(pdn, where, size, val);
+ ret = rtas_write_raw_config(phb->buid, bus->number, devfn,
+ where, size, val);
+ }
+
+ return ret;
}
static struct pci_ops rtas_pci_ops = {
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 2825d004dece..ffd546cf9204 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -648,30 +648,29 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn)
}
}
-int pnv_pci_cfg_read(struct pci_dn *pdn,
- int where, int size, u32 *val)
+static int pnv_pci_cfg_read_raw(u64 phb_id, int busno, unsigned int devfn,
+ int where, int size, u32 *val)
{
- struct pnv_phb *phb = pdn->phb->private_data;
- u32 bdfn = (pdn->busno << 8) | pdn->devfn;
+ u32 bdfn = (busno << 8) | devfn;
s64 rc;
switch (size) {
case 1: {
u8 v8;
- rc = opal_pci_config_read_byte(phb->opal_id, bdfn, where, &v8);
+ rc = opal_pci_config_read_byte(phb_id, bdfn, where, &v8);
*val = (rc == OPAL_SUCCESS) ? v8 : 0xff;
break;
}
case 2: {
__be16 v16;
- rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where,
- &v16);
+ rc = opal_pci_config_read_half_word(phb_id, bdfn, where,
+ &v16);
*val = (rc == OPAL_SUCCESS) ? be16_to_cpu(v16) : 0xffff;
break;
}
case 4: {
__be32 v32;
- rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32);
+ rc = opal_pci_config_read_word(phb_id, bdfn, where, &v32);
*val = (rc == OPAL_SUCCESS) ? be32_to_cpu(v32) : 0xffffffff;
break;
}
@@ -680,27 +679,28 @@ int pnv_pci_cfg_read(struct pci_dn *pdn,
}
pr_devel("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
- __func__, pdn->busno, pdn->devfn, where, size, *val);
+ __func__, busno, devfn, where, size, *val);
+
return PCIBIOS_SUCCESSFUL;
}
-int pnv_pci_cfg_write(struct pci_dn *pdn,
- int where, int size, u32 val)
+static int pnv_pci_cfg_write_raw(u64 phb_id, int busno, unsigned int devfn,
+ int where, int size, u32 val)
{
- struct pnv_phb *phb = pdn->phb->private_data;
- u32 bdfn = (pdn->busno << 8) | pdn->devfn;
+ u32 bdfn = (busno << 8) | devfn;
pr_devel("%s: bus: %x devfn: %x +%x/%x -> %08x\n",
- __func__, pdn->busno, pdn->devfn, where, size, val);
+ __func__, busno, devfn, where, size, val);
+
switch (size) {
case 1:
- opal_pci_config_write_byte(phb->opal_id, bdfn, where, val);
+ opal_pci_config_write_byte(phb_id, bdfn, where, val);
break;
case 2:
- opal_pci_config_write_half_word(phb->opal_id, bdfn, where, val);
+ opal_pci_config_write_half_word(phb_id, bdfn, where, val);
break;
case 4:
- opal_pci_config_write_word(phb->opal_id, bdfn, where, val);
+ opal_pci_config_write_word(phb_id, bdfn, where, val);
break;
default:
return PCIBIOS_FUNC_NOT_SUPPORTED;
@@ -709,6 +709,24 @@ int pnv_pci_cfg_write(struct pci_dn *pdn,
return PCIBIOS_SUCCESSFUL;
}
+int pnv_pci_cfg_read(struct pci_dn *pdn,
+ int where, int size, u32 *val)
+{
+ struct pnv_phb *phb = pdn->phb->private_data;
+
+ return pnv_pci_cfg_read_raw(phb->opal_id, pdn->busno, pdn->devfn,
+ where, size, val);
+}
+
+int pnv_pci_cfg_write(struct pci_dn *pdn,
+ int where, int size, u32 val)
+{
+ struct pnv_phb *phb = pdn->phb->private_data;
+
+ return pnv_pci_cfg_write_raw(phb->opal_id, pdn->busno, pdn->devfn,
+ where, size, val);
+}
+
#if CONFIG_EEH
static bool pnv_pci_cfg_check(struct pci_dn *pdn)
{
@@ -744,13 +762,15 @@ static int pnv_pci_read_config(struct pci_bus *bus,
int where, int size, u32 *val)
{
struct pci_dn *pdn;
- struct pnv_phb *phb;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct pnv_phb *phb = hose->private_data;
int ret;
*val = 0xFFFFFFFF;
pdn = pci_get_pdn_by_devfn(bus, devfn);
if (!pdn)
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return pnv_pci_cfg_read_raw(phb->opal_id, bus->number, devfn,
+ where, size, val);
if (!pnv_pci_cfg_check(pdn))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -773,12 +793,14 @@ static int pnv_pci_write_config(struct pci_bus *bus,
int where, int size, u32 val)
{
struct pci_dn *pdn;
- struct pnv_phb *phb;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct pnv_phb *phb = hose->private_data;
int ret;
pdn = pci_get_pdn_by_devfn(bus, devfn);
if (!pdn)
- return PCIBIOS_DEVICE_NOT_FOUND;
+ return pnv_pci_cfg_write_raw(phb->opal_id, bus->number, devfn,
+ where, size, val);
if (!pnv_pci_cfg_check(pdn))
return PCIBIOS_DEVICE_NOT_FOUND;
--
2.23.0
next prev parent reply other threads:[~2019-10-24 17:12 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-24 17:11 [PATCH v6 00/30] PCI: Allow BAR movement during hotplug Sergey Miroshnichenko
2019-10-24 17:11 ` [PATCH v6 01/30] PCI: Fix race condition in pci_enable/disable_device() Sergey Miroshnichenko
2019-10-25 14:33 ` Oxford Semiconductor Ltd OX16PCI954 - weird dmesg Carlo Pisani
2019-10-25 16:37 ` Bjorn Helgaas
2019-10-24 17:12 ` [PATCH v6 02/30] PCI: Enable bridge's I/O and MEM access for hotplugged devices Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 03/30] PCI: hotplug: Add a flag for the movable BARs feature Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 04/30] PCI: Define PCI-specific version of the release_child_resources() Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 05/30] PCI: hotplug: movable BARs: Fix reassigning the released bridge windows Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 06/30] PCI: hotplug: movable BARs: Recalculate all bridge windows during rescan Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 07/30] PCI: hotplug: movable BARs: Don't disable the released bridge windows Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 08/30] PCI: hotplug: movable BARs: Don't allow added devices to steal resources Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 09/30] PCI: Include fixed and immovable BARs into the bus size calculating Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 10/30] PCI: Prohibit assigning BARs and bridge windows to non-direct parents Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 11/30] PCI: hotplug: movable BARs: Try to assign unassigned resources only once Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 12/30] PCI: hotplug: movable BARs: Calculate immovable parts of bridge windows Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 13/30] PCI: hotplug: movable BARs: Compute limits for relocated " Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 14/30] PCI: Make sure bridge windows include their fixed BARs Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 15/30] PCI: Fix assigning the fixed prefetchable resources Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 16/30] PCI: hotplug: movable BARs: Assign fixed and immovable BARs before others Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 17/30] PCI: hotplug: movable BARs: Don't reserve IO/mem bus space Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 18/30] PCI: hotplug: Configure MPS for hot-added bridges during bus rescan Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 19/30] PCI: hotplug: movable BARs: Ignore the MEM BAR offsets from bootloader Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 20/30] powerpc/pci: Fix crash with enabled movable BARs Sergey Miroshnichenko
2019-10-25 1:22 ` Alexey Kardashevskiy
2019-10-24 17:12 ` Sergey Miroshnichenko [this message]
2019-10-24 17:12 ` [PATCH v6 22/30] powerpc/pci: Create pci_dn on demand Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 23/30] powerpc/pci: hotplug: Add support for movable BARs Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 24/30] powerpc/powernv/pci: Suppress an EEH error when reading an empty slot Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 25/30] PNP: Don't reserve BARs for PCI when enabled movable BARs Sergey Miroshnichenko
2019-10-27 17:40 ` kbuild test robot
2019-10-24 17:12 ` [PATCH v6 26/30] PCI: hotplug: movable BARs: Enable the feature by default Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 27/30] nvme-pci: Handle movable BARs Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 28/30] PCI/portdrv: Declare support of " Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 29/30] PCI: pciehp: movable BARs: Trigger a domain rescan on hp events Sergey Miroshnichenko
2019-10-24 17:12 ` [PATCH v6 30/30] Revert "powerpc/powernv/pci: Work around races in PCI bridge enabling" Sergey Miroshnichenko
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=20191024171228.877974-22-s.miroshnichenko@yadro.com \
--to=s.miroshnichenko@yadro.com \
--cc=helgaas@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@yadro.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=oohall@gmail.com \
/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).