Message ID | 20210519235426.99728-3-ameynarkhede03@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | Expose and manage PCI device reset | expand |
Hi Amey, [...] > +int pcie_reset_flr(struct pci_dev *dev, int probe) > +{ > + u32 cap; > + > + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) > + return -ENOTTY; > + > + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); > + if (!(cap & PCI_EXP_DEVCAP_FLR)) > + return -ENOTTY; > + > + if (probe) > + return 0; > + > + return pcie_flr(dev); > +} Similarly to my suggestion in the first patch in the series, perhaps using a boolean here would be an option. Having said that, the following existing functions aren't doing it, so for the sake of keeping things consistent it might not be the best option, as per: static int pci_af_flr(struct pci_dev *dev, int probe) int nvme_disable_and_flr(struct pci_dev *dev, int probe) Krzysztof
On 21/05/20 05:05PM, Krzysztof Wilczyński wrote: > Hi Amey, > > [...] > > +int pcie_reset_flr(struct pci_dev *dev, int probe) > > +{ > > + u32 cap; > > + > > + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) > > + return -ENOTTY; > > + > > + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); > > + if (!(cap & PCI_EXP_DEVCAP_FLR)) > > + return -ENOTTY; > > + > > + if (probe) > > + return 0; > > + > > + return pcie_flr(dev); > > +} > > Similarly to my suggestion in the first patch in the series, perhaps > using a boolean here would be an option. > > Having said that, the following existing functions aren't doing it, so > for the sake of keeping things consistent it might not be the best > option, as per: > > static int pci_af_flr(struct pci_dev *dev, int probe) > int nvme_disable_and_flr(struct pci_dev *dev, int probe) > > Krzysztof All the functions which implement different types of resets including quirks have ...reset(struct pci_dev *dev, int probe) signature. Should I modify all of them? Thanks, Amey
Hi Amey, Sorry for late reply! [...] > > Similarly to my suggestion in the first patch in the series, perhaps > > using a boolean here would be an option. > > > > Having said that, the following existing functions aren't doing it, so > > for the sake of keeping things consistent it might not be the best > > option, as per: > > > > static int pci_af_flr(struct pci_dev *dev, int probe) > > int nvme_disable_and_flr(struct pci_dev *dev, int probe) > > > > Krzysztof > > All the functions which implement different types of resets including > quirks have ...reset(struct pci_dev *dev, int probe) signature. > Should I modify all of them? Might not be worth it to change anything then, especially if the other functions there already use an integer argument to enable or disable the problem or something else. At least no in this series. Krzysztof
On 21/05/25 05:17PM, Krzysztof Wilczyński wrote: > Hi Amey, > > Sorry for late reply! > > [...] > > > Similarly to my suggestion in the first patch in the series, perhaps > > > using a boolean here would be an option. > > > > > > Having said that, the following existing functions aren't doing it, so > > > for the sake of keeping things consistent it might not be the best > > > option, as per: > > > > > > static int pci_af_flr(struct pci_dev *dev, int probe) > > > int nvme_disable_and_flr(struct pci_dev *dev, int probe) > > > > > > Krzysztof > > > > All the functions which implement different types of resets including > > quirks have ...reset(struct pci_dev *dev, int probe) signature. > > Should I modify all of them? > > Might not be worth it to change anything then, especially if the other > functions there already use an integer argument to enable or disable the > problem or something else. At least no in this series. > > Krzysztof Actually I made a new separate patch at the end to implement this change. I'll send v3 soon. Thanks, Amey
diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index facc8e6bc..15d6c8452 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -306,9 +306,7 @@ static int nitrox_device_flr(struct pci_dev *pdev) return -ENOMEM; } - /* check flr support */ - if (pcie_has_flr(pdev)) - pcie_flr(pdev); + pcie_reset_flr(pdev, 0); pci_restore_state(pdev); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a8f8dd588..b998d6ad3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4573,32 +4573,12 @@ int pci_wait_for_pending_transaction(struct pci_dev *dev) } EXPORT_SYMBOL(pci_wait_for_pending_transaction); -/** - * pcie_has_flr - check if a device supports function level resets - * @dev: device to check - * - * Returns true if the device advertises support for PCIe function level - * resets. - */ -bool pcie_has_flr(struct pci_dev *dev) -{ - u32 cap; - - if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) - return false; - - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); - return cap & PCI_EXP_DEVCAP_FLR; -} -EXPORT_SYMBOL_GPL(pcie_has_flr); - /** * pcie_flr - initiate a PCIe function level reset * @dev: device to reset * - * Initiate a function level reset on @dev. The caller should ensure the - * device supports FLR before calling this function, e.g. by using the - * pcie_has_flr() helper. + * Initiate a function level reset unconditionally on @dev without + * checking any flags and DEVCAP */ int pcie_flr(struct pci_dev *dev) { @@ -4621,6 +4601,31 @@ int pcie_flr(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(pcie_flr); +/** + * pcie_reset_flr - initiate a PCIe function level reset + * @dev: device to reset + * @probe: If set, only check if the device can be reset this way. + * + * Initiate a function level reset on @dev. + */ +int pcie_reset_flr(struct pci_dev *dev, int probe) +{ + u32 cap; + + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) + return -ENOTTY; + + pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); + if (!(cap & PCI_EXP_DEVCAP_FLR)) + return -ENOTTY; + + if (probe) + return 0; + + return pcie_flr(dev); +} +EXPORT_SYMBOL_GPL(pcie_reset_flr); + static int pci_af_flr(struct pci_dev *dev, int probe) { int pos; @@ -5100,11 +5105,9 @@ int __pci_reset_function_locked(struct pci_dev *dev) rc = pci_dev_specific_reset(dev, 0); if (rc != -ENOTTY) return rc; - if (pcie_has_flr(dev)) { - rc = pcie_flr(dev); - if (rc != -ENOTTY) - return rc; - } + rc = pcie_reset_flr(dev, 0); + if (rc != -ENOTTY) + return rc; rc = pci_af_flr(dev, 0); if (rc != -ENOTTY) return rc; @@ -5135,8 +5138,9 @@ int pci_probe_reset_function(struct pci_dev *dev) rc = pci_dev_specific_reset(dev, 1); if (rc != -ENOTTY) return rc; - if (pcie_has_flr(dev)) - return 0; + rc = pcie_reset_flr(dev, 1); + if (rc != -ENOTTY) + return rc; rc = pci_af_flr(dev, 1); if (rc != -ENOTTY) return rc; diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index ba2238834..f4e891bd5 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1405,13 +1405,11 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) } if (type == PCI_EXP_TYPE_RC_EC || type == PCI_EXP_TYPE_RC_END) { - if (pcie_has_flr(dev)) { - rc = pcie_flr(dev); - pci_info(dev, "has been reset (%d)\n", rc); - } else { - pci_info(dev, "not reset (no FLR support)\n"); - rc = -ENOTTY; - } + rc = pcie_reset_flr(dev, 0); + if (!rc) + pci_info(dev, "has been reset\n"); + else + pci_info(dev, "not reset (no FLR support: %d)\n", rc); } else { rc = pci_bus_error_reset(dev); pci_info(dev, "%s Port link has been reset (%d)\n", diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 653660e3b..5318833f3 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3831,7 +3831,7 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe) u32 cfg; if (dev->class != PCI_CLASS_STORAGE_EXPRESS || - !pcie_has_flr(dev) || !pci_resource_start(dev, 0)) + pcie_reset_flr(dev, 1) || !pci_resource_start(dev, 0)) return -ENOTTY; if (probe) @@ -3900,13 +3900,10 @@ static int nvme_disable_and_flr(struct pci_dev *dev, int probe) */ static int delay_250ms_after_flr(struct pci_dev *dev, int probe) { - if (!pcie_has_flr(dev)) - return -ENOTTY; + int ret = pcie_reset_flr(dev, probe); if (probe) - return 0; - - pcie_flr(dev); + return ret; msleep(250); diff --git a/include/linux/pci.h b/include/linux/pci.h index 979d54335..8d20e51ab 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1217,7 +1217,7 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev, enum pci_bus_speed *speed, enum pcie_link_width *width); void pcie_print_link_status(struct pci_dev *dev); -bool pcie_has_flr(struct pci_dev *dev); +int pcie_reset_flr(struct pci_dev *dev, int probe); int pcie_flr(struct pci_dev *dev); int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev);