Commit 4a3c390c authored by Linus Torvalds's avatar Linus Torvalds

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
parents 9c953d63 0ce57f8a
...@@ -1418,30 +1418,33 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports, ...@@ -1418,30 +1418,33 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
* Message mode could be enforced. In this case assume that advantage * Message mode could be enforced. In this case assume that advantage
* of multipe MSIs is negated and use single MSI mode instead. * of multipe MSIs is negated and use single MSI mode instead.
*/ */
nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX, if (n_ports > 1) {
PCI_IRQ_MSIX | PCI_IRQ_MSI); nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
if (nvec > 0) { PCI_IRQ_MSIX | PCI_IRQ_MSI);
if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) { if (nvec > 0) {
hpriv->get_irq_vector = ahci_get_irq_vector; if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
hpriv->flags |= AHCI_HFLAG_MULTI_MSI; hpriv->get_irq_vector = ahci_get_irq_vector;
return nvec; 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 * -ENOSPC indicated we don't have enough vectors. Don't bother
* mode. * trying a single vectors for any other error:
*/ */
printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); if (nvec < 0 && nvec != -ENOSPC)
pci_free_irq_vectors(pdev); 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 * If the host is not capable of supporting per-port vectors, fall
* back to single MSI before finally attempting single MSI-X. * 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) ...@@ -1617,7 +1620,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* legacy intx interrupts */ /* legacy intx interrupts */
pci_intx(pdev, 1); pci_intx(pdev, 1);
} }
hpriv->irq = pdev->irq; hpriv->irq = pci_irq_vector(pdev, 0);
if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
host->flags |= ATA_HOST_PARALLEL_SCAN; host->flags |= ATA_HOST_PARALLEL_SCAN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment