summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-27 10:07:13 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-27 10:07:13 -0700
commit4a3c390c384f31c60aaf0502dcd3d790a9ebebca (patch)
treeda185b856fd46aa4ea4292606e632963e1f0c972 /drivers
parent9c953d639c2fb97e4e96f7398acbf4b675713b76 (diff)
parent0ce57f8af1782fd12d3a81872a4ab97244989802 (diff)
downloadlinux-4a3c390c384f31c60aaf0502dcd3d790a9ebebca.tar.bz2
Merge branch 'for-4.9-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata
Pull libata fixes from Tejun Heo: "The AHCI MSI handling change in rc1 was a bit broken and caused disk probing failures on some machines. These three patches should fix the issues" David Howells comments: "My test machine fell foul of this using a PCIe M.2-attached SSD card. The patches fix it for me" * 'for-4.9-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata: ahci: fix the single MSI-X case in ahci_init_one ahci: fix nvec check ahci: only try to use multi-MSI mode if there is more than 1 port
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ba5f11cebee2..9669fc7c19df 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1418,31 +1418,34 @@ static int ahci_init_msi(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.
*/
- nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
- PCI_IRQ_MSIX | PCI_IRQ_MSI);
- if (nvec > 0) {
- if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
- hpriv->get_irq_vector = ahci_get_irq_vector;
- hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
- return nvec;
+ if (n_ports > 1) {
+ nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
+ PCI_IRQ_MSIX | PCI_IRQ_MSI);
+ if (nvec > 0) {
+ if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
+ hpriv->get_irq_vector = ahci_get_irq_vector;
+ hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
+ return nvec;
+ }
+
+ /*
+ * Fallback to single MSI mode if the controller
+ * enforced MRSM mode.
+ */
+ printk(KERN_INFO
+ "ahci: MRSM is on, fallback to single MSI\n");
+ pci_free_irq_vectors(pdev);
}
/*
- * Fallback to single MSI mode if the controller enforced MRSM
- * mode.
+ * -ENOSPC indicated we don't have enough vectors. Don't bother
+ * trying a single vectors for any other error:
*/
- printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
- pci_free_irq_vectors(pdev);
+ if (nvec < 0 && nvec != -ENOSPC)
+ return nvec;
}
/*
- * -ENOSPC indicated we don't have enough vectors. Don't bother trying
- * a single vectors for any other error:
- */
- if (nvec < 0 && nvec != -ENOSPC)
- return nvec;
-
- /*
* If the host is not capable of supporting per-port vectors, fall
* back to single MSI before finally attempting single MSI-X.
*/
@@ -1617,7 +1620,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* legacy intx interrupts */
pci_intx(pdev, 1);
}
- hpriv->irq = pdev->irq;
+ hpriv->irq = pci_irq_vector(pdev, 0);
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN;