PCI/MSI: Remove pci_enable_msi_block_auto()
The new pci_msi_vec_count() interface makes pci_enable_msi_block_auto() superfluous. Drivers can use pci_msi_vec_count() to learn the maximum number of MSIs supported by the device, and then call pci_enable_msi_block(). pci_enable_msi_block_auto() was introduced recently, and its only user is the AHCI driver, which is also updated by this change. Signed-off-by: Alexander Gordeev <agordeev@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
Родитель
d1ac1d2622
Коммит
7b92b4f61e
|
@ -127,49 +127,22 @@ on the number of vectors that can be allocated; pci_enable_msi_block()
|
|||
returns as soon as it finds any constraint that doesn't allow the
|
||||
call to succeed.
|
||||
|
||||
4.2.3 pci_enable_msi_block_auto
|
||||
|
||||
int pci_enable_msi_block_auto(struct pci_dev *dev, int *count)
|
||||
|
||||
This variation on pci_enable_msi() call allows a device driver to request
|
||||
the maximum possible number of MSIs. The MSI specification only allows
|
||||
interrupts to be allocated in powers of two, up to a maximum of 2^5 (32).
|
||||
|
||||
If this function returns a positive number, it indicates that it has
|
||||
succeeded and the returned value is the number of allocated interrupts. In
|
||||
this case, the function enables MSI on this device and updates dev->irq to
|
||||
be the lowest of the new interrupts assigned to it. The other interrupts
|
||||
assigned to the device are in the range dev->irq to dev->irq + returned
|
||||
value - 1.
|
||||
|
||||
If this function returns a negative number, it indicates an error and
|
||||
the driver should not attempt to request any more MSI interrupts for
|
||||
this device.
|
||||
|
||||
If the device driver needs to know the number of interrupts the device
|
||||
supports it can pass the pointer count where that number is stored. The
|
||||
device driver must decide what action to take if pci_enable_msi_block_auto()
|
||||
succeeds, but returns a value less than the number of interrupts supported.
|
||||
If the device driver does not need to know the number of interrupts
|
||||
supported, it can set the pointer count to NULL.
|
||||
|
||||
4.2.4 pci_disable_msi
|
||||
4.2.3 pci_disable_msi
|
||||
|
||||
void pci_disable_msi(struct pci_dev *dev)
|
||||
|
||||
This function should be used to undo the effect of pci_enable_msi() or
|
||||
pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores
|
||||
dev->irq to the pin-based interrupt number and frees the previously
|
||||
allocated message signaled interrupt(s). The interrupt may subsequently be
|
||||
assigned to another device, so drivers should not cache the value of
|
||||
dev->irq.
|
||||
pci_enable_msi_block(). Calling it restores dev->irq to the pin-based
|
||||
interrupt number and frees the previously allocated message signaled
|
||||
interrupt(s). The interrupt may subsequently be assigned to another
|
||||
device, so drivers should not cache the value of dev->irq.
|
||||
|
||||
Before calling this function, a device driver must always call free_irq()
|
||||
on any interrupt for which it previously called request_irq().
|
||||
Failure to do so results in a BUG_ON(), leaving the device with
|
||||
MSI enabled and thus leaking its vector.
|
||||
|
||||
4.2.5 pci_msi_vec_count
|
||||
4.2.4 pci_msi_vec_count
|
||||
|
||||
int pci_msi_vec_count(struct pci_dev *dev)
|
||||
|
||||
|
|
|
@ -1095,26 +1095,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
|
|||
{}
|
||||
#endif
|
||||
|
||||
int ahci_init_interrupts(struct pci_dev *pdev, struct ahci_host_priv *hpriv)
|
||||
int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
|
||||
struct ahci_host_priv *hpriv)
|
||||
{
|
||||
int rc;
|
||||
unsigned int maxvec;
|
||||
int rc, nvec;
|
||||
|
||||
if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) {
|
||||
rc = pci_enable_msi_block_auto(pdev, &maxvec);
|
||||
if (rc > 0) {
|
||||
if ((rc == maxvec) || (rc == 1))
|
||||
return rc;
|
||||
/*
|
||||
* Assume that advantage of multipe MSIs is negated,
|
||||
* so fallback to single MSI mode to save resources
|
||||
*/
|
||||
pci_disable_msi(pdev);
|
||||
if (!pci_enable_msi(pdev))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (hpriv->flags & AHCI_HFLAG_NO_MSI)
|
||||
goto intx;
|
||||
|
||||
rc = pci_msi_vec_count(pdev);
|
||||
if (rc < 0)
|
||||
goto intx;
|
||||
|
||||
/*
|
||||
* If number of MSIs is less than number of ports then Sharing Last
|
||||
* Message mode could be enforced. In this case assume that advantage
|
||||
* of multipe MSIs is negated and use single MSI mode instead.
|
||||
*/
|
||||
if (rc < n_ports)
|
||||
goto single_msi;
|
||||
|
||||
nvec = rc;
|
||||
rc = pci_enable_msi_block(pdev, nvec);
|
||||
if (rc)
|
||||
goto intx;
|
||||
|
||||
return nvec;
|
||||
|
||||
single_msi:
|
||||
rc = pci_enable_msi(pdev);
|
||||
if (rc)
|
||||
goto intx;
|
||||
return 1;
|
||||
|
||||
intx:
|
||||
pci_intx(pdev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1281,10 +1295,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
|
||||
|
||||
n_msis = ahci_init_interrupts(pdev, hpriv);
|
||||
if (n_msis > 1)
|
||||
hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
|
||||
|
||||
/* save initial config */
|
||||
ahci_pci_save_initial_config(pdev, hpriv);
|
||||
|
||||
|
@ -1339,6 +1349,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
*/
|
||||
n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
|
||||
|
||||
n_msis = ahci_init_interrupts(pdev, n_ports, hpriv);
|
||||
if (n_msis > 1)
|
||||
hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
|
||||
|
||||
host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
|
||||
if (!host)
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -911,31 +911,6 @@ int pci_enable_msi_block(struct pci_dev *dev, int nvec)
|
|||
}
|
||||
EXPORT_SYMBOL(pci_enable_msi_block);
|
||||
|
||||
int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec)
|
||||
{
|
||||
int ret, nvec;
|
||||
|
||||
if (dev->current_state != PCI_D0)
|
||||
return -EINVAL;
|
||||
|
||||
ret = pci_msi_vec_count(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (maxvec)
|
||||
*maxvec = ret;
|
||||
|
||||
do {
|
||||
nvec = ret;
|
||||
ret = pci_enable_msi_block(dev, nvec);
|
||||
} while (ret > 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return nvec;
|
||||
}
|
||||
EXPORT_SYMBOL(pci_enable_msi_block_auto);
|
||||
|
||||
void pci_msi_shutdown(struct pci_dev *dev)
|
||||
{
|
||||
struct msi_desc *desc;
|
||||
|
|
|
@ -1164,12 +1164,6 @@ static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec)
|
|||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline void pci_msi_shutdown(struct pci_dev *dev)
|
||||
{ }
|
||||
static inline void pci_disable_msi(struct pci_dev *dev)
|
||||
|
@ -1202,7 +1196,6 @@ static inline int pci_msi_enabled(void)
|
|||
#else
|
||||
int pci_msi_vec_count(struct pci_dev *dev);
|
||||
int pci_enable_msi_block(struct pci_dev *dev, int nvec);
|
||||
int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec);
|
||||
void pci_msi_shutdown(struct pci_dev *dev);
|
||||
void pci_disable_msi(struct pci_dev *dev);
|
||||
int pci_msix_table_size(struct pci_dev *dev);
|
||||
|
|
Загрузка…
Ссылка в новой задаче