[Very RFC 15/46] powernv/eeh: Use pnv_eeh_*_config() for internal config ops
Alexey Kardashevskiy
aik at ozlabs.ru
Fri Nov 22 17:15:19 AEDT 2019
On 20/11/2019 12:28, Oliver O'Halloran wrote:
> Use the pnv_eeh_{read|write}_config() functions that take an edev rather
> than a pci_dn. This allows us to remove most of the explict uses of pci_dn
> in the PowerNV EEH backend and localises them into a few functions which we
> can fix later.
-ESPELL :)
>
> Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
> ---
> arch/powerpc/platforms/powernv/eeh-powernv.c | 153 +++++++++----------
> 1 file changed, 70 insertions(+), 83 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
> index aa2935a08464..aaccb3768393 100644
> --- a/arch/powerpc/platforms/powernv/eeh-powernv.c
> +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
> @@ -278,27 +278,73 @@ int pnv_eeh_post_init(void)
> return ret;
> }
>
> -static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
> +static inline bool pnv_eeh_cfg_blocked(struct eeh_dev *edev)
> +{
> + if (!edev || !edev->pe)
> + return false;
> +
> + /*
> + * We will issue FLR or AF FLR to all VFs, which are contained
> + * in VF PE. It relies on the EEH PCI config accessors. So we
> + * can't block them during the window.
> + */
> + if (edev->physfn && (edev->pe->state & EEH_PE_RESET))
> + return false;
> +
> + if (edev->pe->state & EEH_PE_CFG_BLOCKED)
> + return true;
> +
> + return false;
> +}
> +
> +static int pnv_eeh_read_config(struct eeh_dev *edev,
> + int where, int size, u32 *val)
> +{
> + struct pci_dn *pdn = eeh_dev_to_pdn(edev);
> +
> + if (!pdn)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> +
> + if (pnv_eeh_cfg_blocked(edev)) {
> + *val = 0xFFFFFFFF;
> + return PCIBIOS_SET_FAILED;
> + }
> +
> + return pnv_pci_cfg_read(pdn, where, size, val);
> +}
> +
> +static int pnv_eeh_write_config(struct eeh_dev *edev,
> + int where, int size, u32 val)
> +{
> + struct pci_dn *pdn = eeh_dev_to_pdn(edev);
> +
> + if (!pdn)
> + return PCIBIOS_DEVICE_NOT_FOUND;
> +
> + if (pnv_eeh_cfg_blocked(edev))
> + return PCIBIOS_SET_FAILED;
> +
> + return pnv_pci_cfg_write(pdn, where, size, val);
> +}
> +
> +static int pnv_eeh_find_cap(struct eeh_dev *edev, int cap)
> {
> int pos = PCI_CAPABILITY_LIST;
> int cnt = 48; /* Maximal number of capabilities */
> u32 status, id;
>
> - if (!pdn)
> - return 0;
> -
> /* Check if the device supports capabilities */
> - pnv_pci_cfg_read(pdn, PCI_STATUS, 2, &status);
> + pnv_eeh_read_config(edev, PCI_STATUS, 2, &status);
> if (!(status & PCI_STATUS_CAP_LIST))
> return 0;
>
> while (cnt--) {
> - pnv_pci_cfg_read(pdn, pos, 1, &pos);
> + pnv_eeh_read_config(edev, pos, 1, &pos);
> if (pos < 0x40)
> break;
>
> pos &= ~3;
> - pnv_pci_cfg_read(pdn, pos + PCI_CAP_LIST_ID, 1, &id);
> + pnv_eeh_read_config(edev, pos + PCI_CAP_LIST_ID, 1, &id);
> if (id == 0xff)
> break;
>
> @@ -313,15 +359,14 @@ static int pnv_eeh_find_cap(struct pci_dn *pdn, int cap)
> return 0;
> }
>
> -static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap)
> +static int pnv_eeh_find_ecap(struct eeh_dev *edev, int cap)
> {
> - struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
> u32 header;
> int pos = 256, ttl = (4096 - 256) / 8;
>
> if (!edev || !edev->pcie_cap)
> return 0;
> - if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
> + if (pnv_eeh_read_config(edev, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
> return 0;
> else if (!header)
> return 0;
> @@ -334,7 +379,7 @@ static int pnv_eeh_find_ecap(struct pci_dn *pdn, int cap)
> if (pos < 256)
> break;
>
> - if (pnv_pci_cfg_read(pdn, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
> + if (pnv_eeh_read_config(edev, pos, 4, &header) != PCIBIOS_SUCCESSFUL)
> break;
> }
>
> @@ -382,15 +427,14 @@ static struct eeh_dev *pnv_eeh_probe_pdev(struct pci_dev *pdev)
>
> /* Initialize eeh device */
> edev->class_code = pdn->class_code;
> - edev->mode &= 0xFFFFFF00;
It seems that this should go to 22/46. Thanks,
> - edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
> - edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
> - edev->af_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF);
> - edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
> + edev->pcix_cap = pnv_eeh_find_cap(edev, PCI_CAP_ID_PCIX);
> + edev->pcie_cap = pnv_eeh_find_cap(edev, PCI_CAP_ID_EXP);
> + edev->af_cap = pnv_eeh_find_cap(edev, PCI_CAP_ID_AF);
> + edev->aer_cap = pnv_eeh_find_ecap(edev, PCI_EXT_CAP_ID_ERR);
> if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
> edev->mode |= EEH_DEV_BRIDGE;
> if (edev->pcie_cap) {
> - pnv_pci_cfg_read(pdn, edev->pcie_cap + PCI_EXP_FLAGS,
> + pnv_eeh_read_config(edev, edev->pcie_cap + PCI_EXP_FLAGS,
> 2, &pcie_flags);
> pcie_flags = (pcie_flags & PCI_EXP_FLAGS_TYPE) >> 4;
> if (pcie_flags == PCI_EXP_TYPE_ROOT_PORT)
> @@ -839,8 +883,7 @@ static int pnv_eeh_root_reset(struct pci_controller *hose, int option)
>
> static int __pnv_eeh_bridge_reset(struct pci_dev *dev, int option)
> {
> - struct pci_dn *pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
> - struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
> + struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
> int aer = edev ? edev->aer_cap : 0;
> u32 ctrl;
>
> @@ -944,10 +987,9 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
> }
> }
>
> -static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
> +static void pnv_eeh_wait_for_pending(struct eeh_dev *edev, const char *type,
> int pos, u16 mask)
> {
> - struct eeh_dev *edev = pdn->edev;
> int i, status = 0;
>
> /* Wait for Transaction Pending bit to be cleared */
> @@ -965,9 +1007,8 @@ static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type,
> PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn));
> }
>
> -static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
> +static int pnv_eeh_do_flr(struct eeh_dev *edev, int option)
> {
> - struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
> u32 reg = 0;
>
> if (WARN_ON(!edev->pcie_cap))
> @@ -980,7 +1021,7 @@ static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
> switch (option) {
> case EEH_RESET_HOT:
> case EEH_RESET_FUNDAMENTAL:
> - pnv_eeh_wait_for_pending(pdn, "",
> + pnv_eeh_wait_for_pending(edev, "",
> edev->pcie_cap + PCI_EXP_DEVSTA,
> PCI_EXP_DEVSTA_TRPND);
> eeh_ops->read_config(edev, edev->pcie_cap + PCI_EXP_DEVCTL,
> @@ -1003,9 +1044,8 @@ static int pnv_eeh_do_flr(struct pci_dn *pdn, int option)
> return 0;
> }
>
> -static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
> +static int pnv_eeh_do_af_flr(struct eeh_dev *edev, int option)
> {
> - struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
> u32 cap = 0;
>
> if (WARN_ON(!edev->af_cap))
> @@ -1023,7 +1063,7 @@ static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
> * test is used, so we use the conrol offset rather than status
> * and shift the test bit to match.
> */
> - pnv_eeh_wait_for_pending(pdn, "AF",
> + pnv_eeh_wait_for_pending(edev, "AF",
> edev->af_cap + PCI_AF_CTRL,
> PCI_AF_STATUS_TP << 8);
> eeh_ops->write_config(edev, edev->af_cap + PCI_AF_CTRL,
> @@ -1042,20 +1082,18 @@ static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option)
> static int pnv_eeh_reset_vf_pe(struct eeh_pe *pe, int option)
> {
> struct eeh_dev *edev;
> - struct pci_dn *pdn;
> int ret;
>
> /* The VF PE should have only one child device */
> edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry);
> - pdn = eeh_dev_to_pdn(edev);
> - if (!pdn)
> + if (!edev)
> return -ENXIO;
>
> - ret = pnv_eeh_do_flr(pdn, option);
> + ret = pnv_eeh_do_flr(edev, option);
> if (!ret)
> return ret;
>
> - return pnv_eeh_do_af_flr(pdn, option);
> + return pnv_eeh_do_af_flr(edev, option);
> }
>
> /**
> @@ -1244,57 +1282,6 @@ static int pnv_eeh_err_inject(struct eeh_pe *pe, int type, int func,
> return 0;
> }
>
> -static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn)
> -{
> - struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
> -
> - if (!edev || !edev->pe)
> - return false;
> -
> - /*
> - * We will issue FLR or AF FLR to all VFs, which are contained
> - * in VF PE. It relies on the EEH PCI config accessors. So we
> - * can't block them during the window.
> - */
> - if (edev->physfn && (edev->pe->state & EEH_PE_RESET))
> - return false;
> -
> - if (edev->pe->state & EEH_PE_CFG_BLOCKED)
> - return true;
> -
> - return false;
> -}
> -
> -static int pnv_eeh_read_config(struct eeh_dev *edev,
> - int where, int size, u32 *val)
> -{
> - struct pci_dn *pdn = eeh_dev_to_pdn(edev);
> -
> - if (!pdn)
> - return PCIBIOS_DEVICE_NOT_FOUND;
> -
> - if (pnv_eeh_cfg_blocked(pdn)) {
> - *val = 0xFFFFFFFF;
> - return PCIBIOS_SET_FAILED;
> - }
> -
> - return pnv_pci_cfg_read(pdn, where, size, val);
> -}
> -
> -static int pnv_eeh_write_config(struct eeh_dev *edev,
> - int where, int size, u32 val)
> -{
> - struct pci_dn *pdn = eeh_dev_to_pdn(edev);
> -
> - if (!pdn)
> - return PCIBIOS_DEVICE_NOT_FOUND;
> -
> - if (pnv_eeh_cfg_blocked(pdn))
> - return PCIBIOS_SET_FAILED;
> -
> - return pnv_pci_cfg_write(pdn, where, size, val);
> -}
> -
> static void pnv_eeh_dump_hub_diag_common(struct OpalIoP7IOCErrorData *data)
> {
> /* GEM */
>
--
Alexey
More information about the Linuxppc-dev
mailing list