diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-24 12:57:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-24 12:57:02 -0400 |
| commit | fdd324aa5fcaf3cc82f71bde51bf884436c9a986 (patch) | |
| tree | 5c247d7cd214c5f80cfdc4478f0ea2e33fc5de49 | |
| parent | db725c88c74669603239a757761a2aecc390f55d (diff) | |
| parent | 8a4aeec8d2d6a3edeffbdfae451cdf05cbf0fefd (diff) | |
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
| -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 | ||
