diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-14 14:38:00 -0700 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-14 14:38:00 -0700 |
commit | c128856b48b1a7132166c6b37a53b086d549fbde (patch) | |
tree | c4c1bb2baa1e25a436f09efb17a8304364bf7901 /drivers | |
parent | c80ef97ae4848c4592f0fac9c06d7f436862a28d (diff) | |
parent | 94cccde648d32abe61e2d0d1b18178f3027f1a78 (diff) |
Merge branch 'pci/msi' into next
* pci/msi:
vfio: Use pci_enable_msi_range() and pci_enable_msix_range()
ahci: Use pci_enable_msi_range() instead of pci_enable_msi_block()
ahci: Fix broken fallback to single MSI mode
PCI/MSI: Add pci_enable_msi_exact() and pci_enable_msix_exact()
PCI/MSI: Fix cut-and-paste errors in documentation
PCI/MSI: Add pci_enable_msi() documentation back
PCI/MSI: Fix pci_msix_vec_count() htmldocs failure
PCI/MSI: Fix leak of msi_attrs
PCI/MSI: Check kmalloc() return value, fix leak of name
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ahci.c | 18 | ||||
-rw-r--r-- | drivers/pci/msi.c | 10 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_intrs.c | 12 |
3 files changed, 25 insertions, 15 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dc2756fb6f33..023710905289 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1151,13 +1151,13 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, struct ahci_host_priv *hpriv) { - int rc, nvec; + int nvec; if (hpriv->flags & AHCI_HFLAG_NO_MSI) goto intx; - rc = pci_msi_vec_count(pdev); - if (rc < 0) + nvec = pci_msi_vec_count(pdev); + if (nvec < 0) goto intx; /* @@ -1165,19 +1165,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, * 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) + if (nvec < n_ports) goto single_msi; - nvec = rc; - rc = pci_enable_msi_block(pdev, nvec); - if (rc) + nvec = pci_enable_msi_range(pdev, nvec, nvec); + if (nvec == -ENOSPC) + goto single_msi; + else if (nvec < 0) goto intx; return nvec; single_msi: - rc = pci_enable_msi(pdev); - if (rc) + if (pci_enable_msi(pdev)) goto intx; return 1; diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a0fec6ce571..955ab7990c5b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -545,9 +545,15 @@ static int populate_msi_sysfs(struct pci_dev *pdev) return -ENOMEM; list_for_each_entry(entry, &pdev->msi_list, list) { char *name = kmalloc(20, GFP_KERNEL); + if (!name) + goto error_attrs; + msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); - if (!msi_dev_attr) + if (!msi_dev_attr) { + kfree(name); goto error_attrs; + } + sprintf(name, "%d", entry->irq); sysfs_attr_init(&msi_dev_attr->attr); msi_dev_attr->attr.name = name; @@ -589,6 +595,7 @@ error_attrs: ++count; msi_attr = msi_attrs[count]; } + kfree(msi_attrs); return ret; } @@ -959,7 +966,6 @@ EXPORT_SYMBOL(pci_disable_msi); /** * pci_msix_vec_count - return the number of device's MSI-X table entries * @dev: pointer to the pci_dev data structure of MSI-X device function - * This function returns the number of device's MSI-X table entries and * therefore the number of MSI-X vectors device is capable of sending. * It returns a negative errno if the device is not capable of sending MSI-X diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 210357691dc0..9dd49c9839ac 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -482,15 +482,19 @@ static int vfio_msi_enable(struct vfio_pci_device *vdev, int nvec, bool msix) for (i = 0; i < nvec; i++) vdev->msix[i].entry = i; - ret = pci_enable_msix(pdev, vdev->msix, nvec); - if (ret) { + ret = pci_enable_msix_range(pdev, vdev->msix, 1, nvec); + if (ret < nvec) { + if (ret > 0) + pci_disable_msix(pdev); kfree(vdev->msix); kfree(vdev->ctx); return ret; } } else { - ret = pci_enable_msi_block(pdev, nvec); - if (ret) { + ret = pci_enable_msi_range(pdev, 1, nvec); + if (ret < nvec) { + if (ret > 0) + pci_disable_msi(pdev); kfree(vdev->ctx); return ret; } |