diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 355 |
1 files changed, 316 insertions, 39 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a3241a1a710b..5326af28a410 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/dma-mapping.h> | 42 | #include <linux/dma-mapping.h> |
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | #include <linux/dmi.h> | 44 | #include <linux/dmi.h> |
45 | #include <linux/gfp.h> | ||
45 | #include <scsi/scsi_host.h> | 46 | #include <scsi/scsi_host.h> |
46 | #include <scsi/scsi_cmnd.h> | 47 | #include <scsi/scsi_cmnd.h> |
47 | #include <linux/libata.h> | 48 | #include <linux/libata.h> |
@@ -93,6 +94,9 @@ enum { | |||
93 | AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS, | 94 | AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS, |
94 | AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + | 95 | AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + |
95 | AHCI_RX_FIS_SZ, | 96 | AHCI_RX_FIS_SZ, |
97 | AHCI_PORT_PRIV_FBS_DMA_SZ = AHCI_CMD_SLOT_SZ + | ||
98 | AHCI_CMD_TBL_AR_SZ + | ||
99 | (AHCI_RX_FIS_SZ * 16), | ||
96 | AHCI_IRQ_ON_SG = (1 << 31), | 100 | AHCI_IRQ_ON_SG = (1 << 31), |
97 | AHCI_CMD_ATAPI = (1 << 5), | 101 | AHCI_CMD_ATAPI = (1 << 5), |
98 | AHCI_CMD_WRITE = (1 << 6), | 102 | AHCI_CMD_WRITE = (1 << 6), |
@@ -113,6 +117,7 @@ enum { | |||
113 | board_ahci_mcp65 = 6, | 117 | board_ahci_mcp65 = 6, |
114 | board_ahci_nopmp = 7, | 118 | board_ahci_nopmp = 7, |
115 | board_ahci_yesncq = 8, | 119 | board_ahci_yesncq = 8, |
120 | board_ahci_nosntf = 9, | ||
116 | 121 | ||
117 | /* global controller registers */ | 122 | /* global controller registers */ |
118 | HOST_CAP = 0x00, /* host capabilities */ | 123 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -169,6 +174,7 @@ enum { | |||
169 | PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ | 174 | PORT_SCR_ERR = 0x30, /* SATA phy register: SError */ |
170 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ | 175 | PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */ |
171 | PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ | 176 | PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */ |
177 | PORT_FBS = 0x40, /* FIS-based Switching */ | ||
172 | 178 | ||
173 | /* PORT_IRQ_{STAT,MASK} bits */ | 179 | /* PORT_IRQ_{STAT,MASK} bits */ |
174 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ | 180 | PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ |
@@ -207,6 +213,7 @@ enum { | |||
207 | PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */ | 213 | PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */ |
208 | PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */ | 214 | PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */ |
209 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ | 215 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ |
216 | PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */ | ||
210 | PORT_CMD_PMP = (1 << 17), /* PMP attached */ | 217 | PORT_CMD_PMP = (1 << 17), /* PMP attached */ |
211 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ | 218 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ |
212 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ | 219 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ |
@@ -221,6 +228,14 @@ enum { | |||
221 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ | 228 | PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ |
222 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ | 229 | PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ |
223 | 230 | ||
231 | PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ | ||
232 | PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ | ||
233 | PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */ | ||
234 | PORT_FBS_DEV_MASK = (0xf << PORT_FBS_DEV_OFFSET), /* FBS.DEV */ | ||
235 | PORT_FBS_SDE = (1 << 2), /* FBS single device error */ | ||
236 | PORT_FBS_DEC = (1 << 1), /* FBS device error clear */ | ||
237 | PORT_FBS_EN = (1 << 0), /* Enable FBS */ | ||
238 | |||
224 | /* hpriv->flags bits */ | 239 | /* hpriv->flags bits */ |
225 | AHCI_HFLAG_NO_NCQ = (1 << 0), | 240 | AHCI_HFLAG_NO_NCQ = (1 << 0), |
226 | AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ | 241 | AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ |
@@ -235,6 +250,7 @@ enum { | |||
235 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ | 250 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ |
236 | AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as | 251 | AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as |
237 | link offline */ | 252 | link offline */ |
253 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ | ||
238 | 254 | ||
239 | /* ap->flags bits */ | 255 | /* ap->flags bits */ |
240 | 256 | ||
@@ -302,6 +318,9 @@ struct ahci_port_priv { | |||
302 | unsigned int ncq_saw_dmas:1; | 318 | unsigned int ncq_saw_dmas:1; |
303 | unsigned int ncq_saw_sdb:1; | 319 | unsigned int ncq_saw_sdb:1; |
304 | u32 intr_mask; /* interrupts to enable */ | 320 | u32 intr_mask; /* interrupts to enable */ |
321 | bool fbs_supported; /* set iff FBS is supported */ | ||
322 | bool fbs_enabled; /* set iff FBS is enabled */ | ||
323 | int fbs_last_dev; /* save FBS.DEV of last FIS */ | ||
305 | /* enclosure management info per PM slot */ | 324 | /* enclosure management info per PM slot */ |
306 | struct ahci_em_priv em_priv[EM_MAX_SLOTS]; | 325 | struct ahci_em_priv em_priv[EM_MAX_SLOTS]; |
307 | }; | 326 | }; |
@@ -313,9 +332,12 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | |||
313 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); | 332 | static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); |
314 | static int ahci_port_start(struct ata_port *ap); | 333 | static int ahci_port_start(struct ata_port *ap); |
315 | static void ahci_port_stop(struct ata_port *ap); | 334 | static void ahci_port_stop(struct ata_port *ap); |
335 | static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc); | ||
316 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | 336 | static void ahci_qc_prep(struct ata_queued_cmd *qc); |
317 | static void ahci_freeze(struct ata_port *ap); | 337 | static void ahci_freeze(struct ata_port *ap); |
318 | static void ahci_thaw(struct ata_port *ap); | 338 | static void ahci_thaw(struct ata_port *ap); |
339 | static void ahci_enable_fbs(struct ata_port *ap); | ||
340 | static void ahci_disable_fbs(struct ata_port *ap); | ||
319 | static void ahci_pmp_attach(struct ata_port *ap); | 341 | static void ahci_pmp_attach(struct ata_port *ap); |
320 | static void ahci_pmp_detach(struct ata_port *ap); | 342 | static void ahci_pmp_detach(struct ata_port *ap); |
321 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | 343 | static int ahci_softreset(struct ata_link *link, unsigned int *class, |
@@ -354,10 +376,10 @@ static ssize_t ahci_show_host_version(struct device *dev, | |||
354 | static ssize_t ahci_show_port_cmd(struct device *dev, | 376 | static ssize_t ahci_show_port_cmd(struct device *dev, |
355 | struct device_attribute *attr, char *buf); | 377 | struct device_attribute *attr, char *buf); |
356 | 378 | ||
357 | DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); | 379 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); |
358 | DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); | 380 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); |
359 | DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); | 381 | static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); |
360 | DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | 382 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); |
361 | 383 | ||
362 | static struct device_attribute *ahci_shost_attrs[] = { | 384 | static struct device_attribute *ahci_shost_attrs[] = { |
363 | &dev_attr_link_power_management_policy, | 385 | &dev_attr_link_power_management_policy, |
@@ -388,7 +410,7 @@ static struct scsi_host_template ahci_sht = { | |||
388 | static struct ata_port_operations ahci_ops = { | 410 | static struct ata_port_operations ahci_ops = { |
389 | .inherits = &sata_pmp_port_ops, | 411 | .inherits = &sata_pmp_port_ops, |
390 | 412 | ||
391 | .qc_defer = sata_pmp_qc_defer_cmd_switch, | 413 | .qc_defer = ahci_pmp_qc_defer, |
392 | .qc_prep = ahci_qc_prep, | 414 | .qc_prep = ahci_qc_prep, |
393 | .qc_issue = ahci_qc_issue, | 415 | .qc_issue = ahci_qc_issue, |
394 | .qc_fill_rtf = ahci_qc_fill_rtf, | 416 | .qc_fill_rtf = ahci_qc_fill_rtf, |
@@ -508,7 +530,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
508 | .udma_mask = ATA_UDMA6, | 530 | .udma_mask = ATA_UDMA6, |
509 | .port_ops = &ahci_ops, | 531 | .port_ops = &ahci_ops, |
510 | }, | 532 | }, |
511 | /* board_ahci_yesncq */ | 533 | [board_ahci_yesncq] = |
512 | { | 534 | { |
513 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | 535 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), |
514 | .flags = AHCI_FLAG_COMMON, | 536 | .flags = AHCI_FLAG_COMMON, |
@@ -516,6 +538,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
516 | .udma_mask = ATA_UDMA6, | 538 | .udma_mask = ATA_UDMA6, |
517 | .port_ops = &ahci_ops, | 539 | .port_ops = &ahci_ops, |
518 | }, | 540 | }, |
541 | [board_ahci_nosntf] = | ||
542 | { | ||
543 | AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF), | ||
544 | .flags = AHCI_FLAG_COMMON, | ||
545 | .pio_mask = ATA_PIO4, | ||
546 | .udma_mask = ATA_UDMA6, | ||
547 | .port_ops = &ahci_ops, | ||
548 | }, | ||
519 | }; | 549 | }; |
520 | 550 | ||
521 | static const struct pci_device_id ahci_pci_tbl[] = { | 551 | static const struct pci_device_id ahci_pci_tbl[] = { |
@@ -531,7 +561,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
531 | { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ | 561 | { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ |
532 | { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ | 562 | { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ |
533 | { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ | 563 | { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ |
534 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */ | 564 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */ |
535 | { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ | 565 | { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ |
536 | { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ | 566 | { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ |
537 | { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ | 567 | { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ |
@@ -560,6 +590,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
560 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ | 590 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ |
561 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ | 591 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ |
562 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ | 592 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ |
593 | { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ | ||
594 | { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ | ||
595 | { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ | ||
596 | { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */ | ||
597 | { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ | ||
598 | { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ | ||
563 | 599 | ||
564 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 600 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
565 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 601 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
@@ -606,6 +642,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
606 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ | 642 | { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_yesncq }, /* MCP67 */ |
607 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ | 643 | { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_yesncq }, /* MCP67 */ |
608 | { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ | 644 | { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_yesncq }, /* Linux ID */ |
645 | { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_yesncq }, /* Linux ID */ | ||
646 | { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_yesncq }, /* Linux ID */ | ||
647 | { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_yesncq }, /* Linux ID */ | ||
648 | { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_yesncq }, /* Linux ID */ | ||
649 | { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_yesncq }, /* Linux ID */ | ||
650 | { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_yesncq }, /* Linux ID */ | ||
651 | { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_yesncq }, /* Linux ID */ | ||
652 | { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_yesncq }, /* Linux ID */ | ||
653 | { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_yesncq }, /* Linux ID */ | ||
654 | { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_yesncq }, /* Linux ID */ | ||
655 | { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_yesncq }, /* Linux ID */ | ||
656 | { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_yesncq }, /* Linux ID */ | ||
657 | { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_yesncq }, /* Linux ID */ | ||
658 | { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_yesncq }, /* Linux ID */ | ||
659 | { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_yesncq }, /* Linux ID */ | ||
609 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ | 660 | { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_yesncq }, /* MCP73 */ |
610 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ | 661 | { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_yesncq }, /* MCP73 */ |
611 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ | 662 | { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_yesncq }, /* MCP73 */ |
@@ -849,6 +900,12 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
849 | cap &= ~HOST_CAP_PMP; | 900 | cap &= ~HOST_CAP_PMP; |
850 | } | 901 | } |
851 | 902 | ||
903 | if ((cap & HOST_CAP_SNTF) && (hpriv->flags & AHCI_HFLAG_NO_SNTF)) { | ||
904 | dev_printk(KERN_INFO, &pdev->dev, | ||
905 | "controller can't do SNTF, turning off CAP_SNTF\n"); | ||
906 | cap &= ~HOST_CAP_SNTF; | ||
907 | } | ||
908 | |||
852 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 && | 909 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 && |
853 | port_map != 1) { | 910 | port_map != 1) { |
854 | dev_printk(KERN_INFO, &pdev->dev, | 911 | dev_printk(KERN_INFO, &pdev->dev, |
@@ -2029,6 +2086,17 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) | |||
2029 | return si; | 2086 | return si; |
2030 | } | 2087 | } |
2031 | 2088 | ||
2089 | static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc) | ||
2090 | { | ||
2091 | struct ata_port *ap = qc->ap; | ||
2092 | struct ahci_port_priv *pp = ap->private_data; | ||
2093 | |||
2094 | if (!sata_pmp_attached(ap) || pp->fbs_enabled) | ||
2095 | return ata_std_qc_defer(qc); | ||
2096 | else | ||
2097 | return sata_pmp_qc_defer_cmd_switch(qc); | ||
2098 | } | ||
2099 | |||
2032 | static void ahci_qc_prep(struct ata_queued_cmd *qc) | 2100 | static void ahci_qc_prep(struct ata_queued_cmd *qc) |
2033 | { | 2101 | { |
2034 | struct ata_port *ap = qc->ap; | 2102 | struct ata_port *ap = qc->ap; |
@@ -2067,6 +2135,31 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
2067 | ahci_fill_cmd_slot(pp, qc->tag, opts); | 2135 | ahci_fill_cmd_slot(pp, qc->tag, opts); |
2068 | } | 2136 | } |
2069 | 2137 | ||
2138 | static void ahci_fbs_dec_intr(struct ata_port *ap) | ||
2139 | { | ||
2140 | struct ahci_port_priv *pp = ap->private_data; | ||
2141 | void __iomem *port_mmio = ahci_port_base(ap); | ||
2142 | u32 fbs = readl(port_mmio + PORT_FBS); | ||
2143 | int retries = 3; | ||
2144 | |||
2145 | DPRINTK("ENTER\n"); | ||
2146 | BUG_ON(!pp->fbs_enabled); | ||
2147 | |||
2148 | /* time to wait for DEC is not specified by AHCI spec, | ||
2149 | * add a retry loop for safety. | ||
2150 | */ | ||
2151 | writel(fbs | PORT_FBS_DEC, port_mmio + PORT_FBS); | ||
2152 | fbs = readl(port_mmio + PORT_FBS); | ||
2153 | while ((fbs & PORT_FBS_DEC) && retries--) { | ||
2154 | udelay(1); | ||
2155 | fbs = readl(port_mmio + PORT_FBS); | ||
2156 | } | ||
2157 | |||
2158 | if (fbs & PORT_FBS_DEC) | ||
2159 | dev_printk(KERN_ERR, ap->host->dev, | ||
2160 | "failed to clear device error\n"); | ||
2161 | } | ||
2162 | |||
2070 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | 2163 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) |
2071 | { | 2164 | { |
2072 | struct ahci_host_priv *hpriv = ap->host->private_data; | 2165 | struct ahci_host_priv *hpriv = ap->host->private_data; |
@@ -2075,12 +2168,26 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
2075 | struct ata_link *link = NULL; | 2168 | struct ata_link *link = NULL; |
2076 | struct ata_queued_cmd *active_qc; | 2169 | struct ata_queued_cmd *active_qc; |
2077 | struct ata_eh_info *active_ehi; | 2170 | struct ata_eh_info *active_ehi; |
2171 | bool fbs_need_dec = false; | ||
2078 | u32 serror; | 2172 | u32 serror; |
2079 | 2173 | ||
2080 | /* determine active link */ | 2174 | /* determine active link with error */ |
2081 | ata_for_each_link(link, ap, EDGE) | 2175 | if (pp->fbs_enabled) { |
2082 | if (ata_link_active(link)) | 2176 | void __iomem *port_mmio = ahci_port_base(ap); |
2083 | break; | 2177 | u32 fbs = readl(port_mmio + PORT_FBS); |
2178 | int pmp = fbs >> PORT_FBS_DWE_OFFSET; | ||
2179 | |||
2180 | if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) && | ||
2181 | ata_link_online(&ap->pmp_link[pmp])) { | ||
2182 | link = &ap->pmp_link[pmp]; | ||
2183 | fbs_need_dec = true; | ||
2184 | } | ||
2185 | |||
2186 | } else | ||
2187 | ata_for_each_link(link, ap, EDGE) | ||
2188 | if (ata_link_active(link)) | ||
2189 | break; | ||
2190 | |||
2084 | if (!link) | 2191 | if (!link) |
2085 | link = &ap->link; | 2192 | link = &ap->link; |
2086 | 2193 | ||
@@ -2137,8 +2244,13 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
2137 | } | 2244 | } |
2138 | 2245 | ||
2139 | if (irq_stat & PORT_IRQ_IF_ERR) { | 2246 | if (irq_stat & PORT_IRQ_IF_ERR) { |
2140 | host_ehi->err_mask |= AC_ERR_ATA_BUS; | 2247 | if (fbs_need_dec) |
2141 | host_ehi->action |= ATA_EH_RESET; | 2248 | active_ehi->err_mask |= AC_ERR_DEV; |
2249 | else { | ||
2250 | host_ehi->err_mask |= AC_ERR_ATA_BUS; | ||
2251 | host_ehi->action |= ATA_EH_RESET; | ||
2252 | } | ||
2253 | |||
2142 | ata_ehi_push_desc(host_ehi, "interface fatal error"); | 2254 | ata_ehi_push_desc(host_ehi, "interface fatal error"); |
2143 | } | 2255 | } |
2144 | 2256 | ||
@@ -2153,7 +2265,10 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) | |||
2153 | 2265 | ||
2154 | if (irq_stat & PORT_IRQ_FREEZE) | 2266 | if (irq_stat & PORT_IRQ_FREEZE) |
2155 | ata_port_freeze(ap); | 2267 | ata_port_freeze(ap); |
2156 | else | 2268 | else if (fbs_need_dec) { |
2269 | ata_link_abort(link); | ||
2270 | ahci_fbs_dec_intr(ap); | ||
2271 | } else | ||
2157 | ata_port_abort(ap); | 2272 | ata_port_abort(ap); |
2158 | } | 2273 | } |
2159 | 2274 | ||
@@ -2164,7 +2279,7 @@ static void ahci_port_intr(struct ata_port *ap) | |||
2164 | struct ahci_port_priv *pp = ap->private_data; | 2279 | struct ahci_port_priv *pp = ap->private_data; |
2165 | struct ahci_host_priv *hpriv = ap->host->private_data; | 2280 | struct ahci_host_priv *hpriv = ap->host->private_data; |
2166 | int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); | 2281 | int resetting = !!(ap->pflags & ATA_PFLAG_RESETTING); |
2167 | u32 status, qc_active; | 2282 | u32 status, qc_active = 0; |
2168 | int rc; | 2283 | int rc; |
2169 | 2284 | ||
2170 | status = readl(port_mmio + PORT_IRQ_STAT); | 2285 | status = readl(port_mmio + PORT_IRQ_STAT); |
@@ -2206,20 +2321,38 @@ static void ahci_port_intr(struct ata_port *ap) | |||
2206 | /* If the 'N' bit in word 0 of the FIS is set, | 2321 | /* If the 'N' bit in word 0 of the FIS is set, |
2207 | * we just received asynchronous notification. | 2322 | * we just received asynchronous notification. |
2208 | * Tell libata about it. | 2323 | * Tell libata about it. |
2324 | * | ||
2325 | * Lack of SNotification should not appear in | ||
2326 | * ahci 1.2, so the workaround is unnecessary | ||
2327 | * when FBS is enabled. | ||
2209 | */ | 2328 | */ |
2210 | const __le32 *f = pp->rx_fis + RX_FIS_SDB; | 2329 | if (pp->fbs_enabled) |
2211 | u32 f0 = le32_to_cpu(f[0]); | 2330 | WARN_ON_ONCE(1); |
2212 | 2331 | else { | |
2213 | if (f0 & (1 << 15)) | 2332 | const __le32 *f = pp->rx_fis + RX_FIS_SDB; |
2214 | sata_async_notification(ap); | 2333 | u32 f0 = le32_to_cpu(f[0]); |
2334 | if (f0 & (1 << 15)) | ||
2335 | sata_async_notification(ap); | ||
2336 | } | ||
2215 | } | 2337 | } |
2216 | } | 2338 | } |
2217 | 2339 | ||
2218 | /* pp->active_link is valid iff any command is in flight */ | 2340 | /* pp->active_link is not reliable once FBS is enabled, both |
2219 | if (ap->qc_active && pp->active_link->sactive) | 2341 | * PORT_SCR_ACT and PORT_CMD_ISSUE should be checked because |
2220 | qc_active = readl(port_mmio + PORT_SCR_ACT); | 2342 | * NCQ and non-NCQ commands may be in flight at the same time. |
2221 | else | 2343 | */ |
2222 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | 2344 | if (pp->fbs_enabled) { |
2345 | if (ap->qc_active) { | ||
2346 | qc_active = readl(port_mmio + PORT_SCR_ACT); | ||
2347 | qc_active |= readl(port_mmio + PORT_CMD_ISSUE); | ||
2348 | } | ||
2349 | } else { | ||
2350 | /* pp->active_link is valid iff any command is in flight */ | ||
2351 | if (ap->qc_active && pp->active_link->sactive) | ||
2352 | qc_active = readl(port_mmio + PORT_SCR_ACT); | ||
2353 | else | ||
2354 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); | ||
2355 | } | ||
2223 | 2356 | ||
2224 | rc = ata_qc_complete_multiple(ap, qc_active); | 2357 | rc = ata_qc_complete_multiple(ap, qc_active); |
2225 | 2358 | ||
@@ -2305,6 +2438,15 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
2305 | 2438 | ||
2306 | if (qc->tf.protocol == ATA_PROT_NCQ) | 2439 | if (qc->tf.protocol == ATA_PROT_NCQ) |
2307 | writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); | 2440 | writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); |
2441 | |||
2442 | if (pp->fbs_enabled && pp->fbs_last_dev != qc->dev->link->pmp) { | ||
2443 | u32 fbs = readl(port_mmio + PORT_FBS); | ||
2444 | fbs &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC); | ||
2445 | fbs |= qc->dev->link->pmp << PORT_FBS_DEV_OFFSET; | ||
2446 | writel(fbs, port_mmio + PORT_FBS); | ||
2447 | pp->fbs_last_dev = qc->dev->link->pmp; | ||
2448 | } | ||
2449 | |||
2308 | writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); | 2450 | writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); |
2309 | 2451 | ||
2310 | ahci_sw_activity(qc->dev->link); | 2452 | ahci_sw_activity(qc->dev->link); |
@@ -2317,6 +2459,9 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) | |||
2317 | struct ahci_port_priv *pp = qc->ap->private_data; | 2459 | struct ahci_port_priv *pp = qc->ap->private_data; |
2318 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | 2460 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; |
2319 | 2461 | ||
2462 | if (pp->fbs_enabled) | ||
2463 | d2h_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ; | ||
2464 | |||
2320 | ata_tf_from_fis(d2h_fis, &qc->result_tf); | 2465 | ata_tf_from_fis(d2h_fis, &qc->result_tf); |
2321 | return true; | 2466 | return true; |
2322 | } | 2467 | } |
@@ -2365,6 +2510,71 @@ static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | |||
2365 | ahci_kick_engine(ap); | 2510 | ahci_kick_engine(ap); |
2366 | } | 2511 | } |
2367 | 2512 | ||
2513 | static void ahci_enable_fbs(struct ata_port *ap) | ||
2514 | { | ||
2515 | struct ahci_port_priv *pp = ap->private_data; | ||
2516 | void __iomem *port_mmio = ahci_port_base(ap); | ||
2517 | u32 fbs; | ||
2518 | int rc; | ||
2519 | |||
2520 | if (!pp->fbs_supported) | ||
2521 | return; | ||
2522 | |||
2523 | fbs = readl(port_mmio + PORT_FBS); | ||
2524 | if (fbs & PORT_FBS_EN) { | ||
2525 | pp->fbs_enabled = true; | ||
2526 | pp->fbs_last_dev = -1; /* initialization */ | ||
2527 | return; | ||
2528 | } | ||
2529 | |||
2530 | rc = ahci_stop_engine(ap); | ||
2531 | if (rc) | ||
2532 | return; | ||
2533 | |||
2534 | writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS); | ||
2535 | fbs = readl(port_mmio + PORT_FBS); | ||
2536 | if (fbs & PORT_FBS_EN) { | ||
2537 | dev_printk(KERN_INFO, ap->host->dev, "FBS is enabled.\n"); | ||
2538 | pp->fbs_enabled = true; | ||
2539 | pp->fbs_last_dev = -1; /* initialization */ | ||
2540 | } else | ||
2541 | dev_printk(KERN_ERR, ap->host->dev, "Failed to enable FBS\n"); | ||
2542 | |||
2543 | ahci_start_engine(ap); | ||
2544 | } | ||
2545 | |||
2546 | static void ahci_disable_fbs(struct ata_port *ap) | ||
2547 | { | ||
2548 | struct ahci_port_priv *pp = ap->private_data; | ||
2549 | void __iomem *port_mmio = ahci_port_base(ap); | ||
2550 | u32 fbs; | ||
2551 | int rc; | ||
2552 | |||
2553 | if (!pp->fbs_supported) | ||
2554 | return; | ||
2555 | |||
2556 | fbs = readl(port_mmio + PORT_FBS); | ||
2557 | if ((fbs & PORT_FBS_EN) == 0) { | ||
2558 | pp->fbs_enabled = false; | ||
2559 | return; | ||
2560 | } | ||
2561 | |||
2562 | rc = ahci_stop_engine(ap); | ||
2563 | if (rc) | ||
2564 | return; | ||
2565 | |||
2566 | writel(fbs & ~PORT_FBS_EN, port_mmio + PORT_FBS); | ||
2567 | fbs = readl(port_mmio + PORT_FBS); | ||
2568 | if (fbs & PORT_FBS_EN) | ||
2569 | dev_printk(KERN_ERR, ap->host->dev, "Failed to disable FBS\n"); | ||
2570 | else { | ||
2571 | dev_printk(KERN_INFO, ap->host->dev, "FBS is disabled.\n"); | ||
2572 | pp->fbs_enabled = false; | ||
2573 | } | ||
2574 | |||
2575 | ahci_start_engine(ap); | ||
2576 | } | ||
2577 | |||
2368 | static void ahci_pmp_attach(struct ata_port *ap) | 2578 | static void ahci_pmp_attach(struct ata_port *ap) |
2369 | { | 2579 | { |
2370 | void __iomem *port_mmio = ahci_port_base(ap); | 2580 | void __iomem *port_mmio = ahci_port_base(ap); |
@@ -2375,6 +2585,8 @@ static void ahci_pmp_attach(struct ata_port *ap) | |||
2375 | cmd |= PORT_CMD_PMP; | 2585 | cmd |= PORT_CMD_PMP; |
2376 | writel(cmd, port_mmio + PORT_CMD); | 2586 | writel(cmd, port_mmio + PORT_CMD); |
2377 | 2587 | ||
2588 | ahci_enable_fbs(ap); | ||
2589 | |||
2378 | pp->intr_mask |= PORT_IRQ_BAD_PMP; | 2590 | pp->intr_mask |= PORT_IRQ_BAD_PMP; |
2379 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 2591 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); |
2380 | } | 2592 | } |
@@ -2385,6 +2597,8 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
2385 | struct ahci_port_priv *pp = ap->private_data; | 2597 | struct ahci_port_priv *pp = ap->private_data; |
2386 | u32 cmd; | 2598 | u32 cmd; |
2387 | 2599 | ||
2600 | ahci_disable_fbs(ap); | ||
2601 | |||
2388 | cmd = readl(port_mmio + PORT_CMD); | 2602 | cmd = readl(port_mmio + PORT_CMD); |
2389 | cmd &= ~PORT_CMD_PMP; | 2603 | cmd &= ~PORT_CMD_PMP; |
2390 | writel(cmd, port_mmio + PORT_CMD); | 2604 | writel(cmd, port_mmio + PORT_CMD); |
@@ -2476,20 +2690,40 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) | |||
2476 | 2690 | ||
2477 | static int ahci_port_start(struct ata_port *ap) | 2691 | static int ahci_port_start(struct ata_port *ap) |
2478 | { | 2692 | { |
2693 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
2479 | struct device *dev = ap->host->dev; | 2694 | struct device *dev = ap->host->dev; |
2480 | struct ahci_port_priv *pp; | 2695 | struct ahci_port_priv *pp; |
2481 | void *mem; | 2696 | void *mem; |
2482 | dma_addr_t mem_dma; | 2697 | dma_addr_t mem_dma; |
2698 | size_t dma_sz, rx_fis_sz; | ||
2483 | 2699 | ||
2484 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); | 2700 | pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); |
2485 | if (!pp) | 2701 | if (!pp) |
2486 | return -ENOMEM; | 2702 | return -ENOMEM; |
2487 | 2703 | ||
2488 | mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, | 2704 | /* check FBS capability */ |
2489 | GFP_KERNEL); | 2705 | if ((hpriv->cap & HOST_CAP_FBS) && sata_pmp_supported(ap)) { |
2706 | void __iomem *port_mmio = ahci_port_base(ap); | ||
2707 | u32 cmd = readl(port_mmio + PORT_CMD); | ||
2708 | if (cmd & PORT_CMD_FBSCP) | ||
2709 | pp->fbs_supported = true; | ||
2710 | else | ||
2711 | dev_printk(KERN_WARNING, dev, | ||
2712 | "The port is not capable of FBS\n"); | ||
2713 | } | ||
2714 | |||
2715 | if (pp->fbs_supported) { | ||
2716 | dma_sz = AHCI_PORT_PRIV_FBS_DMA_SZ; | ||
2717 | rx_fis_sz = AHCI_RX_FIS_SZ * 16; | ||
2718 | } else { | ||
2719 | dma_sz = AHCI_PORT_PRIV_DMA_SZ; | ||
2720 | rx_fis_sz = AHCI_RX_FIS_SZ; | ||
2721 | } | ||
2722 | |||
2723 | mem = dmam_alloc_coherent(dev, dma_sz, &mem_dma, GFP_KERNEL); | ||
2490 | if (!mem) | 2724 | if (!mem) |
2491 | return -ENOMEM; | 2725 | return -ENOMEM; |
2492 | memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); | 2726 | memset(mem, 0, dma_sz); |
2493 | 2727 | ||
2494 | /* | 2728 | /* |
2495 | * First item in chunk of DMA memory: 32-slot command table, | 2729 | * First item in chunk of DMA memory: 32-slot command table, |
@@ -2507,8 +2741,8 @@ static int ahci_port_start(struct ata_port *ap) | |||
2507 | pp->rx_fis = mem; | 2741 | pp->rx_fis = mem; |
2508 | pp->rx_fis_dma = mem_dma; | 2742 | pp->rx_fis_dma = mem_dma; |
2509 | 2743 | ||
2510 | mem += AHCI_RX_FIS_SZ; | 2744 | mem += rx_fis_sz; |
2511 | mem_dma += AHCI_RX_FIS_SZ; | 2745 | mem_dma += rx_fis_sz; |
2512 | 2746 | ||
2513 | /* | 2747 | /* |
2514 | * Third item: data area for storing a single command | 2748 | * Third item: data area for storing a single command |
@@ -2815,6 +3049,14 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2815 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link | 3049 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link |
2816 | * to the harddisk doesn't become online after | 3050 | * to the harddisk doesn't become online after |
2817 | * resuming from STR. Warn and fail suspend. | 3051 | * resuming from STR. Warn and fail suspend. |
3052 | * | ||
3053 | * http://bugzilla.kernel.org/show_bug.cgi?id=12276 | ||
3054 | * | ||
3055 | * Use dates instead of versions to match as HP is | ||
3056 | * apparently recycling both product and version | ||
3057 | * strings. | ||
3058 | * | ||
3059 | * http://bugzilla.kernel.org/show_bug.cgi?id=15462 | ||
2818 | */ | 3060 | */ |
2819 | { | 3061 | { |
2820 | .ident = "dv4", | 3062 | .ident = "dv4", |
@@ -2823,7 +3065,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2823 | DMI_MATCH(DMI_PRODUCT_NAME, | 3065 | DMI_MATCH(DMI_PRODUCT_NAME, |
2824 | "HP Pavilion dv4 Notebook PC"), | 3066 | "HP Pavilion dv4 Notebook PC"), |
2825 | }, | 3067 | }, |
2826 | .driver_data = "F.30", /* cutoff BIOS version */ | 3068 | .driver_data = "20090105", /* F.30 */ |
2827 | }, | 3069 | }, |
2828 | { | 3070 | { |
2829 | .ident = "dv5", | 3071 | .ident = "dv5", |
@@ -2832,7 +3074,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2832 | DMI_MATCH(DMI_PRODUCT_NAME, | 3074 | DMI_MATCH(DMI_PRODUCT_NAME, |
2833 | "HP Pavilion dv5 Notebook PC"), | 3075 | "HP Pavilion dv5 Notebook PC"), |
2834 | }, | 3076 | }, |
2835 | .driver_data = "F.16", /* cutoff BIOS version */ | 3077 | .driver_data = "20090506", /* F.16 */ |
2836 | }, | 3078 | }, |
2837 | { | 3079 | { |
2838 | .ident = "dv6", | 3080 | .ident = "dv6", |
@@ -2841,7 +3083,7 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2841 | DMI_MATCH(DMI_PRODUCT_NAME, | 3083 | DMI_MATCH(DMI_PRODUCT_NAME, |
2842 | "HP Pavilion dv6 Notebook PC"), | 3084 | "HP Pavilion dv6 Notebook PC"), |
2843 | }, | 3085 | }, |
2844 | .driver_data = "F.21", /* cutoff BIOS version */ | 3086 | .driver_data = "20090423", /* F.21 */ |
2845 | }, | 3087 | }, |
2846 | { | 3088 | { |
2847 | .ident = "HDX18", | 3089 | .ident = "HDX18", |
@@ -2850,19 +3092,38 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2850 | DMI_MATCH(DMI_PRODUCT_NAME, | 3092 | DMI_MATCH(DMI_PRODUCT_NAME, |
2851 | "HP HDX18 Notebook PC"), | 3093 | "HP HDX18 Notebook PC"), |
2852 | }, | 3094 | }, |
2853 | .driver_data = "F.23", /* cutoff BIOS version */ | 3095 | .driver_data = "20090430", /* F.23 */ |
3096 | }, | ||
3097 | /* | ||
3098 | * Acer eMachines G725 has the same problem. BIOS | ||
3099 | * V1.03 is known to be broken. V3.04 is known to | ||
3100 | * work. Inbetween, there are V1.06, V2.06 and V3.03 | ||
3101 | * that we don't have much idea about. For now, | ||
3102 | * blacklist anything older than V3.04. | ||
3103 | * | ||
3104 | * http://bugzilla.kernel.org/show_bug.cgi?id=15104 | ||
3105 | */ | ||
3106 | { | ||
3107 | .ident = "G725", | ||
3108 | .matches = { | ||
3109 | DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), | ||
3110 | DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), | ||
3111 | }, | ||
3112 | .driver_data = "20091216", /* V3.04 */ | ||
2854 | }, | 3113 | }, |
2855 | { } /* terminate list */ | 3114 | { } /* terminate list */ |
2856 | }; | 3115 | }; |
2857 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | 3116 | const struct dmi_system_id *dmi = dmi_first_match(sysids); |
2858 | const char *ver; | 3117 | int year, month, date; |
3118 | char buf[9]; | ||
2859 | 3119 | ||
2860 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) | 3120 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) |
2861 | return false; | 3121 | return false; |
2862 | 3122 | ||
2863 | ver = dmi_get_system_info(DMI_BIOS_VERSION); | 3123 | dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); |
3124 | snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); | ||
2864 | 3125 | ||
2865 | return !ver || strcmp(ver, dmi->driver_data) < 0; | 3126 | return strcmp(buf, dmi->driver_data) < 0; |
2866 | } | 3127 | } |
2867 | 3128 | ||
2868 | static bool ahci_broken_online(struct pci_dev *pdev) | 3129 | static bool ahci_broken_online(struct pci_dev *pdev) |
@@ -2988,6 +3249,14 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2988 | if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable) | 3249 | if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable) |
2989 | return -ENODEV; | 3250 | return -ENODEV; |
2990 | 3251 | ||
3252 | /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode. | ||
3253 | * At the moment, we can only use the AHCI mode. Let the users know | ||
3254 | * that for SAS drives they're out of luck. | ||
3255 | */ | ||
3256 | if (pdev->vendor == PCI_VENDOR_ID_PROMISE) | ||
3257 | dev_printk(KERN_INFO, &pdev->dev, "PDC42819 " | ||
3258 | "can only drive SATA devices with this driver\n"); | ||
3259 | |||
2991 | /* acquire resources */ | 3260 | /* acquire resources */ |
2992 | rc = pcim_enable_device(pdev); | 3261 | rc = pcim_enable_device(pdev); |
2993 | if (rc) | 3262 | if (rc) |
@@ -3043,8 +3312,16 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3043 | ahci_save_initial_config(pdev, hpriv); | 3312 | ahci_save_initial_config(pdev, hpriv); |
3044 | 3313 | ||
3045 | /* prepare host */ | 3314 | /* prepare host */ |
3046 | if (hpriv->cap & HOST_CAP_NCQ) | 3315 | if (hpriv->cap & HOST_CAP_NCQ) { |
3047 | pi.flags |= ATA_FLAG_NCQ | ATA_FLAG_FPDMA_AA; | 3316 | pi.flags |= ATA_FLAG_NCQ; |
3317 | /* Auto-activate optimization is supposed to be supported on | ||
3318 | all AHCI controllers indicating NCQ support, but it seems | ||
3319 | to be broken at least on some NVIDIA MCP79 chipsets. | ||
3320 | Until we get info on which NVIDIA chipsets don't have this | ||
3321 | issue, if any, disable AA on all NVIDIA AHCIs. */ | ||
3322 | if (pdev->vendor != PCI_VENDOR_ID_NVIDIA) | ||
3323 | pi.flags |= ATA_FLAG_FPDMA_AA; | ||
3324 | } | ||
3048 | 3325 | ||
3049 | if (hpriv->cap & HOST_CAP_PMP) | 3326 | if (hpriv->cap & HOST_CAP_PMP) |
3050 | pi.flags |= ATA_FLAG_PMP; | 3327 | pi.flags |= ATA_FLAG_PMP; |