On Sun, Jul 10, 2016 at 08:57:46PM +0900, Christoph Hellwig wrote: > @@ -1028,19 +1038,8 @@ int pci_msi_enabled(void) > } > EXPORT_SYMBOL(pci_msi_enabled); > > -/** > - * pci_enable_msi_range - configure device's MSI capability structure > - * @dev: device to configure > - * @minvec: minimal number of interrupts to configure > - * @maxvec: maximum number of interrupts to configure > - * > - * This function tries to allocate a maximum possible number of interrupts in a > - * range between @minvec and @maxvec. It returns a negative errno if an error > - * occurs. If it succeeds, it returns the actual number of interrupts allocated > - * and updates the @dev's irq member to the lowest new interrupt number; > - * the other interrupt numbers allocated to this device are consecutive. > - **/ > -int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) > +static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, > + unsigned int flags) > { > int nvec; > int rc; > @@ -1068,21 +1067,78 @@ int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) > else if (nvec > maxvec) > nvec = maxvec; > > - do { > + for (;;) { > + if (!(flags & PCI_IRQ_NOAFFINITY)) { > + dev->irq_affinity = irq_create_affinity_mask(&nvec); > + if (nvec < minvec) > + return -ERANGE; return -ENOSPC; > + } > + > rc = msi_capability_init(dev, nvec); > - if (rc < 0) { > + if (rc == 0) > + return nvec; > + > + kfree(dev->irq_affinity); > + dev->irq_affinity = NULL; > + > + if (rc < 0) > return rc; > - } else if (rc > 0) { > - if (rc < minvec) > - return -ENOSPC; > - nvec = rc; > - } > - } while (rc); > + if (rc < minvec) else if (rc < minvec) > + return -ENOSPC; > + nvec = rc; > + } > +} > > - return nvec; > +/** > + * pci_enable_msi_range - configure device's MSI capability structure > + * @dev: device to configure > + * @minvec: minimal number of interrupts to configure > + * @maxvec: maximum number of interrupts to configure > + * > + * This function tries to allocate a maximum possible number of interrupts in a > + * range between @minvec and @maxvec. It returns a negative errno if an error > + * occurs. If it succeeds, it returns the actual number of interrupts allocated > + * and updates the @dev's irq member to the lowest new interrupt number; > + * the other interrupt numbers allocated to this device are consecutive. > + **/ > +int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) > +{ > + return __pci_enable_msi_range(dev, minvec, maxvec, PCI_IRQ_NOAFFINITY); > } > EXPORT_SYMBOL(pci_enable_msi_range); As a one-liner pci_enable_msi_range() appears rather as a static inline in linux/pci.h, but we do not want __pci_enable_msi*_range() to show up in a public header, right? > +static int __pci_enable_msix_range(struct pci_dev *dev, > + struct msix_entry *entries, int minvec, int maxvec, > + unsigned int flags) > +{ > + int nvec = maxvec; > + int rc; > + > + if (maxvec < minvec) > + return -ERANGE; > + > + for (;;) { > + if (!(flags & PCI_IRQ_NOAFFINITY)) { > + dev->irq_affinity = irq_create_affinity_mask(&nvec); > + if (nvec < minvec) > + return -ERANGE; return -ENOSPC; > + } > + > + rc = pci_enable_msix(dev, entries, nvec); > + if (rc == 0) > + return nvec; > + > + kfree(dev->irq_affinity); > + dev->irq_affinity = NULL; > + > + if (rc < 0) > + return rc; > + if (rc < minvec) else if (rc < minvec) > + return -ENOSPC; > + nvec = rc; > + } > +} > + > /** > * pci_enable_msix_range - configure device's MSI-X capability structure > * @dev: pointer to the pci_dev data structure of MSI-X device function -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html