Re: [PATCH v4 07/10] PCI: PCI: Add pcie_is_link_active() to determine if the PCIe link is active

From: Lukas Wunner
Date: Tue Feb 25 2025 - 04:54:44 EST


On Tue, Feb 25, 2025 at 03:04:04PM +0530, Krishna Chaitanya Chundru wrote:
> Introduce a common API to check if the PCIe link is active, replacing
> duplicate code in multiple locations.
[...]
> --- a/drivers/pci/hotplug/pciehp_hpc.c
> +++ b/drivers/pci/hotplug/pciehp_hpc.c
> @@ -234,18 +234,7 @@ static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask)
> */
> int pciehp_check_link_active(struct controller *ctrl)
> {
> - struct pci_dev *pdev = ctrl_dev(ctrl);
> - u16 lnk_status;
> - int ret;
> -
> - ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
> - if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(lnk_status))
> - return -ENODEV;
> -
> - ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
> - ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
> -
> - return ret;
> + return pcie_is_link_active(ctrl_dev(ctrl));
> }

Please replace all call sites of pciehp_check_link_active() with a call
to the new function.


> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4923,8 +4922,7 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
> if (!dev->link_active_reporting)
> return -ENOTTY;
>
> - pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &status);
> - if (!(status & PCI_EXP_LNKSTA_DLLLA))
> + if (pcie_is_link_active(dev))
> return -ENOTTY;

Missing negation.


> +/**
> + * pcie_is_link_active() - Checks if the link is active or not
> + * @pdev: PCI device to query
> + *
> + * Check whether the link is active or not.
> + *
> + * If the config read returns error then return -ENODEV.
> + */
> +int pcie_is_link_active(struct pci_dev *pdev)

Why not return bool?

I don't quite like the function name because in English the correct word
order is subject - predicate - object, i.e. pcie_link_is_active() or
even shorter, pcie_link_active().


> @@ -2094,6 +2095,10 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
> {
> return -ENOSPC;
> }
> +
> +static inline int pcie_is_link_active(struct pci_dev *dev)
> +{ return -ENODEV; }
> +
> #endif /* CONFIG_PCI */

Is the empty inline really necessary? What breaks if you leave it out?

Thanks,

Lukas