Commit fdd324aa authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata

Pull libata fixes from Tejun Heo:
 "Dan updated tag allocation to accomodate devices which choke when tags
  jump back and forth.  Quite a few ahci MSI related fixes.  A couple
  config dependency fixes and other misc fixes"

* 'for-3.15-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata:
  libata/ahci: accommodate tag ordered controllers
  ahci: Do not receive interrupts sent by dummy ports
  ahci: Use pci_enable_msi_exact() instead of pci_enable_msi_range()
  ahci: Ensure "MSI Revert to Single Message" mode is not enforced
  ahci: do not request irq for dummy port
  pata_samsung_cf: fix ata_host_activate() failure handling
  pata_arasan_cf: fix ata_host_activate() failure handling
  ata: fix i.MX AHCI driver dependencies
  pata_at91: fix ata_host_activate() failure handling
  libata: Update queued trim blacklist for M5x0 drives
  libata: make AHCI_XGENE depend on PHY_XGENE
parents db725c88 8a4aeec8
...@@ -116,7 +116,7 @@ config AHCI_ST ...@@ -116,7 +116,7 @@ config AHCI_ST
config AHCI_IMX config AHCI_IMX
tristate "Freescale i.MX AHCI SATA support" tristate "Freescale i.MX AHCI SATA support"
depends on MFD_SYSCON depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST)
help help
This option enables support for the Freescale i.MX SoC's This option enables support for the Freescale i.MX SoC's
onboard AHCI SATA. onboard AHCI SATA.
...@@ -134,8 +134,7 @@ config AHCI_SUNXI ...@@ -134,8 +134,7 @@ config AHCI_SUNXI
config AHCI_XGENE config AHCI_XGENE
tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support"
depends on ARM64 || COMPILE_TEST depends on PHY_XGENE
select PHY_XGENE
help help
This option enables support for APM X-Gene SoC SATA host controller. This option enables support for APM X-Gene SoC SATA host controller.
......
...@@ -1166,7 +1166,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) ...@@ -1166,7 +1166,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
struct ahci_host_priv *hpriv) struct ahci_host_priv *hpriv)
{ {
int nvec; int rc, nvec;
if (hpriv->flags & AHCI_HFLAG_NO_MSI) if (hpriv->flags & AHCI_HFLAG_NO_MSI)
goto intx; goto intx;
...@@ -1183,12 +1183,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, ...@@ -1183,12 +1183,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
if (nvec < n_ports) if (nvec < n_ports)
goto single_msi; goto single_msi;
nvec = pci_enable_msi_range(pdev, nvec, nvec); rc = pci_enable_msi_exact(pdev, nvec);
if (nvec == -ENOSPC) if (rc == -ENOSPC)
goto single_msi; goto single_msi;
else if (nvec < 0) else if (rc < 0)
goto intx; goto intx;
/* fallback to single MSI mode if the controller enforced MRSM mode */
if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) {
pci_disable_msi(pdev);
printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
goto single_msi;
}
return nvec; return nvec;
single_msi: single_msi:
...@@ -1232,18 +1239,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) ...@@ -1232,18 +1239,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis)
return rc; return rc;
for (i = 0; i < host->n_ports; i++) { for (i = 0; i < host->n_ports; i++) {
const char* desc;
struct ahci_port_priv *pp = host->ports[i]->private_data; struct ahci_port_priv *pp = host->ports[i]->private_data;
/* pp is NULL for dummy ports */ /* Do not receive interrupts sent by dummy ports */
if (pp) if (!pp) {
desc = pp->irq_desc; disable_irq(irq + i);
else continue;
desc = dev_driver_string(host->dev); }
rc = devm_request_threaded_irq(host->dev, rc = devm_request_threaded_irq(host->dev, irq + i,
irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED, ahci_hw_interrupt,
desc, host->ports[i]); ahci_thread_fn, IRQF_SHARED,
pp->irq_desc, host->ports[i]);
if (rc) if (rc)
goto out_free_irqs; goto out_free_irqs;
} }
......
...@@ -94,6 +94,7 @@ enum { ...@@ -94,6 +94,7 @@ enum {
/* HOST_CTL bits */ /* HOST_CTL bits */
HOST_RESET = (1 << 0), /* reset controller; self-clear */ HOST_RESET = (1 << 0), /* reset controller; self-clear */
HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */
HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */
HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
/* HOST_CAP bits */ /* HOST_CAP bits */
......
...@@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ...@@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
/* devices that don't properly handle queued TRIM commands */ /* devices that don't properly handle queued TRIM commands */
{ "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, { "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
{ "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, { "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, },
{ "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
{ "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, },
/* /*
* Some WD SATA-I drives spin up and down erratically when the link * Some WD SATA-I drives spin up and down erratically when the link
...@@ -4792,21 +4794,26 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) ...@@ -4792,21 +4794,26 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
{ {
struct ata_queued_cmd *qc = NULL; struct ata_queued_cmd *qc = NULL;
unsigned int i; unsigned int i, tag;
/* no command while frozen */ /* no command while frozen */
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL; return NULL;
for (i = 0; i < ATA_MAX_QUEUE; i++) {
tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
/* the last tag is reserved for internal command. */ /* the last tag is reserved for internal command. */
for (i = 0; i < ATA_MAX_QUEUE - 1; i++) if (tag == ATA_TAG_INTERNAL)
if (!test_and_set_bit(i, &ap->qc_allocated)) { continue;
qc = __ata_qc_from_tag(ap, i);
if (!test_and_set_bit(tag, &ap->qc_allocated)) {
qc = __ata_qc_from_tag(ap, tag);
qc->tag = tag;
ap->last_tag = tag;
break; break;
} }
}
if (qc)
qc->tag = i;
return qc; return qc;
} }
......
...@@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev) ...@@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev)
cf_card_detect(acdev, 0); cf_card_detect(acdev, 0);
return ata_host_activate(host, acdev->irq, irq_handler, 0, ret = ata_host_activate(host, acdev->irq, irq_handler, 0,
&arasan_cf_sht); &arasan_cf_sht);
if (!ret)
return 0;
cf_exit(acdev);
free_clk: free_clk:
clk_put(acdev->clk); clk_put(acdev->clk);
return ret; return ret;
......
...@@ -407,11 +407,12 @@ static int pata_at91_probe(struct platform_device *pdev) ...@@ -407,11 +407,12 @@ static int pata_at91_probe(struct platform_device *pdev)
host->private_data = info; host->private_data = info;
return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0,
gpio_is_valid(irq) ? ata_sff_interrupt : NULL, gpio_is_valid(irq) ? ata_sff_interrupt : NULL,
irq_flags, &pata_at91_sht); irq_flags, &pata_at91_sht);
if (ret)
goto err_put;
if (!ret)
return 0; return 0;
err_put: err_put:
......
...@@ -594,9 +594,13 @@ static int __init pata_s3c_probe(struct platform_device *pdev) ...@@ -594,9 +594,13 @@ static int __init pata_s3c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host); platform_set_drvdata(pdev, host);
return ata_host_activate(host, info->irq, ret = ata_host_activate(host, info->irq,
info->irq ? pata_s3c_irq : NULL, info->irq ? pata_s3c_irq : NULL,
0, &pata_s3c_sht); 0, &pata_s3c_sht);
if (ret)
goto stop_clk;
return 0;
stop_clk: stop_clk:
clk_disable(info->clk); clk_disable(info->clk);
......
...@@ -822,6 +822,7 @@ struct ata_port { ...@@ -822,6 +822,7 @@ struct ata_port {
unsigned long qc_allocated; unsigned long qc_allocated;
unsigned int qc_active; unsigned int qc_active;
int nr_active_links; /* #links with active qcs */ int nr_active_links; /* #links with active qcs */
unsigned int last_tag; /* track next tag hw expects */
struct ata_link link; /* host default link */ struct ata_link link; /* host default link */
struct ata_link *slave_link; /* see ata_slave_link_init() */ struct ata_link *slave_link; /* see ata_slave_link_init() */
......
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