diff options
-rw-r--r-- | drivers/ata/Kconfig | 5 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 35 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 1 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 27 | ||||
-rw-r--r-- | drivers/ata/pata_arasan_cf.c | 7 | ||||
-rw-r--r-- | drivers/ata/pata_at91.c | 11 | ||||
-rw-r--r-- | drivers/ata/pata_samsung_cf.c | 10 | ||||
-rw-r--r-- | include/linux/libata.h | 1 |
8 files changed, 60 insertions, 37 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 20e03a7eb8b4..c2706047337f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -116,7 +116,7 @@ config AHCI_ST | |||
116 | 116 | ||
117 | config AHCI_IMX | 117 | config AHCI_IMX |
118 | tristate "Freescale i.MX AHCI SATA support" | 118 | tristate "Freescale i.MX AHCI SATA support" |
119 | depends on MFD_SYSCON | 119 | depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) |
120 | help | 120 | help |
121 | This option enables support for the Freescale i.MX SoC's | 121 | This option enables support for the Freescale i.MX SoC's |
122 | onboard AHCI SATA. | 122 | onboard AHCI SATA. |
@@ -134,8 +134,7 @@ config AHCI_SUNXI | |||
134 | 134 | ||
135 | config AHCI_XGENE | 135 | config AHCI_XGENE |
136 | tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" | 136 | tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" |
137 | depends on ARM64 || COMPILE_TEST | 137 | depends on PHY_XGENE |
138 | select PHY_XGENE | ||
139 | help | 138 | help |
140 | This option enables support for APM X-Gene SoC SATA host controller. | 139 | This option enables support for APM X-Gene SoC SATA host controller. |
141 | 140 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5a0bf8ed649b..71e15b73513d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1164,9 +1164,9 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1164 | #endif | 1164 | #endif |
1165 | 1165 | ||
1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | 1166 | static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1167 | struct ahci_host_priv *hpriv) | 1167 | struct ahci_host_priv *hpriv) |
1168 | { | 1168 | { |
1169 | int nvec; | 1169 | int rc, nvec; |
1170 | 1170 | ||
1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) | 1171 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1172 | goto intx; | 1172 | goto intx; |
@@ -1183,12 +1183,19 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1183 | if (nvec < n_ports) | 1183 | if (nvec < n_ports) |
1184 | goto single_msi; | 1184 | goto single_msi; |
1185 | 1185 | ||
1186 | nvec = pci_enable_msi_range(pdev, nvec, nvec); | 1186 | rc = pci_enable_msi_exact(pdev, nvec); |
1187 | if (nvec == -ENOSPC) | 1187 | if (rc == -ENOSPC) |
1188 | goto single_msi; | 1188 | goto single_msi; |
1189 | else if (nvec < 0) | 1189 | else if (rc < 0) |
1190 | goto intx; | 1190 | goto intx; |
1191 | 1191 | ||
1192 | /* fallback to single MSI mode if the controller enforced MRSM mode */ | ||
1193 | if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { | ||
1194 | pci_disable_msi(pdev); | ||
1195 | printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); | ||
1196 | goto single_msi; | ||
1197 | } | ||
1198 | |||
1192 | return nvec; | 1199 | return nvec; |
1193 | 1200 | ||
1194 | single_msi: | 1201 | single_msi: |
@@ -1232,18 +1239,18 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) | |||
1232 | return rc; | 1239 | return rc; |
1233 | 1240 | ||
1234 | for (i = 0; i < host->n_ports; i++) { | 1241 | for (i = 0; i < host->n_ports; i++) { |
1235 | const char* desc; | ||
1236 | struct ahci_port_priv *pp = host->ports[i]->private_data; | 1242 | struct ahci_port_priv *pp = host->ports[i]->private_data; |
1237 | 1243 | ||
1238 | /* pp is NULL for dummy ports */ | 1244 | /* Do not receive interrupts sent by dummy ports */ |
1239 | if (pp) | 1245 | if (!pp) { |
1240 | desc = pp->irq_desc; | 1246 | disable_irq(irq + i); |
1241 | else | 1247 | continue; |
1242 | desc = dev_driver_string(host->dev); | 1248 | } |
1243 | 1249 | ||
1244 | rc = devm_request_threaded_irq(host->dev, | 1250 | rc = devm_request_threaded_irq(host->dev, irq + i, |
1245 | irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED, | 1251 | ahci_hw_interrupt, |
1246 | desc, host->ports[i]); | 1252 | ahci_thread_fn, IRQF_SHARED, |
1253 | pp->irq_desc, host->ports[i]); | ||
1247 | if (rc) | 1254 | if (rc) |
1248 | goto out_free_irqs; | 1255 | goto out_free_irqs; |
1249 | } | 1256 | } |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 51af275b3388..b5eb886da226 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -94,6 +94,7 @@ enum { | |||
94 | /* HOST_CTL bits */ | 94 | /* HOST_CTL bits */ |
95 | HOST_RESET = (1 << 0), /* reset controller; self-clear */ | 95 | HOST_RESET = (1 << 0), /* reset controller; self-clear */ |
96 | HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ | 96 | HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ |
97 | HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */ | ||
97 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | 98 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ |
98 | 99 | ||
99 | /* HOST_CAP bits */ | 100 | /* HOST_CAP bits */ |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c19734d96d7e..943cc8b83e59 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4224 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, | 4224 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, |
4225 | 4225 | ||
4226 | /* devices that don't properly handle queued TRIM commands */ | 4226 | /* devices that don't properly handle queued TRIM commands */ |
4227 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4227 | { "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, |
4228 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4228 | { "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, |
4229 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | ||
4230 | { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | ||
4229 | 4231 | ||
4230 | /* | 4232 | /* |
4231 | * Some WD SATA-I drives spin up and down erratically when the link | 4233 | * 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 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | 4794 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) |
4793 | { | 4795 | { |
4794 | struct ata_queued_cmd *qc = NULL; | 4796 | struct ata_queued_cmd *qc = NULL; |
4795 | unsigned int i; | 4797 | unsigned int i, tag; |
4796 | 4798 | ||
4797 | /* no command while frozen */ | 4799 | /* no command while frozen */ |
4798 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | 4800 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) |
4799 | return NULL; | 4801 | return NULL; |
4800 | 4802 | ||
4801 | /* the last tag is reserved for internal command. */ | 4803 | for (i = 0; i < ATA_MAX_QUEUE; i++) { |
4802 | for (i = 0; i < ATA_MAX_QUEUE - 1; i++) | 4804 | tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE; |
4803 | if (!test_and_set_bit(i, &ap->qc_allocated)) { | 4805 | |
4804 | qc = __ata_qc_from_tag(ap, i); | 4806 | /* the last tag is reserved for internal command. */ |
4807 | if (tag == ATA_TAG_INTERNAL) | ||
4808 | continue; | ||
4809 | |||
4810 | if (!test_and_set_bit(tag, &ap->qc_allocated)) { | ||
4811 | qc = __ata_qc_from_tag(ap, tag); | ||
4812 | qc->tag = tag; | ||
4813 | ap->last_tag = tag; | ||
4805 | break; | 4814 | break; |
4806 | } | 4815 | } |
4807 | 4816 | } | |
4808 | if (qc) | ||
4809 | qc->tag = i; | ||
4810 | 4817 | ||
4811 | return qc; | 4818 | return qc; |
4812 | } | 4819 | } |
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 6fac524c2f50..4edb1a81f63f 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c | |||
@@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev) | |||
898 | 898 | ||
899 | cf_card_detect(acdev, 0); | 899 | cf_card_detect(acdev, 0); |
900 | 900 | ||
901 | return ata_host_activate(host, acdev->irq, irq_handler, 0, | 901 | ret = ata_host_activate(host, acdev->irq, irq_handler, 0, |
902 | &arasan_cf_sht); | 902 | &arasan_cf_sht); |
903 | if (!ret) | ||
904 | return 0; | ||
903 | 905 | ||
906 | cf_exit(acdev); | ||
904 | free_clk: | 907 | free_clk: |
905 | clk_put(acdev->clk); | 908 | clk_put(acdev->clk); |
906 | return ret; | 909 | return ret; |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index e9c87274a781..8a66f23af4c4 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c | |||
@@ -407,12 +407,13 @@ static int pata_at91_probe(struct platform_device *pdev) | |||
407 | 407 | ||
408 | host->private_data = info; | 408 | host->private_data = info; |
409 | 409 | ||
410 | return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, | 410 | ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, |
411 | gpio_is_valid(irq) ? ata_sff_interrupt : NULL, | 411 | gpio_is_valid(irq) ? ata_sff_interrupt : NULL, |
412 | irq_flags, &pata_at91_sht); | 412 | irq_flags, &pata_at91_sht); |
413 | if (ret) | ||
414 | goto err_put; | ||
413 | 415 | ||
414 | if (!ret) | 416 | return 0; |
415 | return 0; | ||
416 | 417 | ||
417 | err_put: | 418 | err_put: |
418 | clk_put(info->mck); | 419 | clk_put(info->mck); |
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index a79566d05666..0610e78c8a2a 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c | |||
@@ -594,9 +594,13 @@ static int __init pata_s3c_probe(struct platform_device *pdev) | |||
594 | 594 | ||
595 | platform_set_drvdata(pdev, host); | 595 | platform_set_drvdata(pdev, host); |
596 | 596 | ||
597 | return ata_host_activate(host, info->irq, | 597 | ret = ata_host_activate(host, info->irq, |
598 | info->irq ? pata_s3c_irq : NULL, | 598 | info->irq ? pata_s3c_irq : NULL, |
599 | 0, &pata_s3c_sht); | 599 | 0, &pata_s3c_sht); |
600 | if (ret) | ||
601 | goto stop_clk; | ||
602 | |||
603 | return 0; | ||
600 | 604 | ||
601 | stop_clk: | 605 | stop_clk: |
602 | clk_disable(info->clk); | 606 | clk_disable(info->clk); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 1de36be64df4..5ab4e3a76721 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -822,6 +822,7 @@ struct ata_port { | |||
822 | unsigned long qc_allocated; | 822 | unsigned long qc_allocated; |
823 | unsigned int qc_active; | 823 | unsigned int qc_active; |
824 | int nr_active_links; /* #links with active qcs */ | 824 | int nr_active_links; /* #links with active qcs */ |
825 | unsigned int last_tag; /* track next tag hw expects */ | ||
825 | 826 | ||
826 | struct ata_link link; /* host default link */ | 827 | struct ata_link link; /* host default link */ |
827 | struct ata_link *slave_link; /* see ata_slave_link_init() */ | 828 | struct ata_link *slave_link; /* see ata_slave_link_init() */ |