On Fri, Feb 19, 2021 at 03:40:05PM +0100, Robert Richter wrote: > On 18.02.21 23:04:55, Dejin Zheng wrote: > > Introduce pcim_alloc_irq_vectors(), a device-managed version of > > pci_alloc_irq_vectors(). Introducing this function can simplify > > the error handling path in many drivers. > > > > And use pci_free_irq_vectors() to replace some code in pcim_release(), > > they are equivalent, and no functional change. It is more explicit > > that pcim_alloc_irq_vectors() is a device-managed function. > > > > Suggested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > > Signed-off-by: Dejin Zheng <zhengdejin5@xxxxxxxxx> > > --- > > v3 -> v4: > > - No change > > v2 -> v3: > > - Add some commit comments for replace some codes in > > pcim_release() by pci_free_irq_vectors(). > > v1 -> v2: > > - Use pci_free_irq_vectors() to replace some code in > > pcim_release(). > > - Modify some commit messages. > > > > drivers/pci/pci.c | 33 +++++++++++++++++++++++++++++---- > > include/linux/pci.h | 3 +++ > > 2 files changed, 32 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > > index b67c4327d307..db799d089c85 100644 > > --- a/drivers/pci/pci.c > > +++ b/drivers/pci/pci.c > > @@ -1969,10 +1969,7 @@ static void pcim_release(struct device *gendev, void *res) > > struct pci_devres *this = res; > > int i; > > > > - if (dev->msi_enabled) > > - pci_disable_msi(dev); > > - if (dev->msix_enabled) > > - pci_disable_msix(dev); > > + pci_free_irq_vectors(dev); > > > > for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) > > if (this->region_mask & (1 << i)) > > @@ -2054,6 +2051,34 @@ void pcim_pin_device(struct pci_dev *pdev) > > } > > EXPORT_SYMBOL(pcim_pin_device); > > > > +/** > > + * pcim_alloc_irq_vectors - a device-managed pci_alloc_irq_vectors() > > + * @dev: PCI device to operate on > > + * @min_vecs: minimum number of vectors required (must be >= 1) > > + * @max_vecs: maximum (desired) number of vectors > > + * @flags: flags or quirks for the allocation > > + * > > + * Return the number of vectors allocated, (which might be smaller than > > + * @max_vecs) if successful, or a negative error code on error. If less > > + * than @min_vecs interrupt vectors are available for @dev the function > > + * will fail with -ENOSPC. > > + * > > + * It depends on calling pcim_enable_device() to make IRQ resources > > + * manageable. > > + */ > > +int pcim_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, > > + unsigned int max_vecs, unsigned int flags) > > +{ > > + struct pci_devres *dr; > > + > > + dr = find_pci_dr(dev); > > + if (!dr || !dr->enabled) > > + return -EINVAL; > > + > > + return pci_alloc_irq_vectors(dev, min_vecs, max_vecs, flags); > > +} > > +EXPORT_SYMBOL(pcim_alloc_irq_vectors); > > If it is just about having a pcim-* counterpart why not just an inline > function like the one below. > Robert and Andy, First of all, thank you very much for your suggestions and help. I think this is not just a pcim-* counterpart, I may not explain this place clearly. In addition to calling pci_alloc_irq_vectors(), the pcim_alloc_irq_vectors() function also checks whether the pci device is enabled and whether the pci device resource has been managed. If any one is wrong, it will return failure. Therefore, I think it should be used as a function. For novices, maybe I understand it incorrectly, so I look forward to your suggestions. > > + dr = find_pci_dr(dev); static struct pci_devres *find_pci_dr(struct pci_dev *pdev) { if (pci_is_managed(pdev)) return devres_find(&pdev->dev, pcim_release, NULL, NULL); return NULL; } here checks whether the pci device resource has been managed. > > + if (!dr || !dr->enabled) here checks whether the pci device is enabled. int pcim_enable_device(struct pci_dev *pdev) { struct pci_devres *dr; int rc; dr = get_pci_dr(pdev); if (unlikely(!dr)) return -ENOMEM; if (dr->enabled) return 0; rc = pci_enable_device(pdev); if (!rc) { pdev->is_managed = 1; dr->enabled = 1; } return rc; } BR, Dejin > > + > > /* > > * pcibios_add_device - provide arch specific hooks when adding device dev > > * @dev: the PCI device being added > > diff --git a/include/linux/pci.h b/include/linux/pci.h > > index 86c799c97b77..d75ba85ddfc5 100644 > > --- a/include/linux/pci.h > > +++ b/include/linux/pci.h > > @@ -1818,6 +1818,9 @@ pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, > > NULL); > > } > > > > +int pcim_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs, > > + unsigned int max_vecs, unsigned int flags); > > + > > static inline int pcim_alloc_irq_vectors(struct pci_dev *dev, > unsigned int min_vecs, unsigned int max_vecs, unsigned int flags) > { > if (!pci_is_managed(dev, min_vecs, max_vecs, flags)) > return -EINVAL; > > return pci_alloc_irq_vectors(dev, min_vecs, max_vecs, flags); > } > > All those stub functions with EXPORT_SYMBOLS etc. could be dropped > then. > > With some macro magic added a list of functions could easily being > created that are already managed but just need a pcim* counterpart. > > -Robert > > > /* Include architecture-dependent settings and functions */ > > > > #include <asm/pci.h> > > -- > > 2.25.0 > >