aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c87
1 files changed, 68 insertions, 19 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 6b91c26a4635..15a23031833f 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -77,8 +77,6 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
77 size_t size); 77 size_t size);
78static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, 78static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
79 ssize_t size); 79 ssize_t size);
80#define MAX_SLOTS 8
81#define MAX_RETRY 15
82 80
83enum { 81enum {
84 AHCI_PCI_BAR = 5, 82 AHCI_PCI_BAR = 5,
@@ -231,6 +229,10 @@ enum {
231 229
232 ICH_MAP = 0x90, /* ICH MAP register */ 230 ICH_MAP = 0x90, /* ICH MAP register */
233 231
232 /* em constants */
233 EM_MAX_SLOTS = 8,
234 EM_MAX_RETRY = 5,
235
234 /* em_ctl bits */ 236 /* em_ctl bits */
235 EM_CTL_RST = (1 << 9), /* Reset */ 237 EM_CTL_RST = (1 << 9), /* Reset */
236 EM_CTL_TM = (1 << 8), /* Transmit Message */ 238 EM_CTL_TM = (1 << 8), /* Transmit Message */
@@ -282,8 +284,8 @@ struct ahci_port_priv {
282 unsigned int ncq_saw_dmas:1; 284 unsigned int ncq_saw_dmas:1;
283 unsigned int ncq_saw_sdb:1; 285 unsigned int ncq_saw_sdb:1;
284 u32 intr_mask; /* interrupts to enable */ 286 u32 intr_mask; /* interrupts to enable */
285 struct ahci_em_priv em_priv[MAX_SLOTS];/* enclosure management info 287 /* enclosure management info per PM slot */
286 * per PM slot */ 288 struct ahci_em_priv em_priv[EM_MAX_SLOTS];
287}; 289};
288 290
289static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); 291static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
@@ -313,7 +315,6 @@ static void ahci_error_handler(struct ata_port *ap);
313static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 315static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
314static int ahci_port_resume(struct ata_port *ap); 316static int ahci_port_resume(struct ata_port *ap);
315static void ahci_dev_config(struct ata_device *dev); 317static void ahci_dev_config(struct ata_device *dev);
316static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
317static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, 318static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
318 u32 opts); 319 u32 opts);
319#ifdef CONFIG_PM 320#ifdef CONFIG_PM
@@ -404,14 +405,14 @@ static struct ata_port_operations ahci_sb600_ops = {
404#define AHCI_HFLAGS(flags) .private_data = (void *)(flags) 405#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
405 406
406static const struct ata_port_info ahci_port_info[] = { 407static const struct ata_port_info ahci_port_info[] = {
407 /* board_ahci */ 408 [board_ahci] =
408 { 409 {
409 .flags = AHCI_FLAG_COMMON, 410 .flags = AHCI_FLAG_COMMON,
410 .pio_mask = ATA_PIO4, 411 .pio_mask = ATA_PIO4,
411 .udma_mask = ATA_UDMA6, 412 .udma_mask = ATA_UDMA6,
412 .port_ops = &ahci_ops, 413 .port_ops = &ahci_ops,
413 }, 414 },
414 /* board_ahci_vt8251 */ 415 [board_ahci_vt8251] =
415 { 416 {
416 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), 417 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
417 .flags = AHCI_FLAG_COMMON, 418 .flags = AHCI_FLAG_COMMON,
@@ -419,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = {
419 .udma_mask = ATA_UDMA6, 420 .udma_mask = ATA_UDMA6,
420 .port_ops = &ahci_vt8251_ops, 421 .port_ops = &ahci_vt8251_ops,
421 }, 422 },
422 /* board_ahci_ign_iferr */ 423 [board_ahci_ign_iferr] =
423 { 424 {
424 AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), 425 AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
425 .flags = AHCI_FLAG_COMMON, 426 .flags = AHCI_FLAG_COMMON,
@@ -427,17 +428,16 @@ static const struct ata_port_info ahci_port_info[] = {
427 .udma_mask = ATA_UDMA6, 428 .udma_mask = ATA_UDMA6,
428 .port_ops = &ahci_ops, 429 .port_ops = &ahci_ops,
429 }, 430 },
430 /* board_ahci_sb600 */ 431 [board_ahci_sb600] =
431 { 432 {
432 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | 433 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
433 AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | 434 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255),
434 AHCI_HFLAG_SECT255),
435 .flags = AHCI_FLAG_COMMON, 435 .flags = AHCI_FLAG_COMMON,
436 .pio_mask = ATA_PIO4, 436 .pio_mask = ATA_PIO4,
437 .udma_mask = ATA_UDMA6, 437 .udma_mask = ATA_UDMA6,
438 .port_ops = &ahci_sb600_ops, 438 .port_ops = &ahci_sb600_ops,
439 }, 439 },
440 /* board_ahci_mv */ 440 [board_ahci_mv] =
441 { 441 {
442 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | 442 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
443 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), 443 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
@@ -447,7 +447,7 @@ static const struct ata_port_info ahci_port_info[] = {
447 .udma_mask = ATA_UDMA6, 447 .udma_mask = ATA_UDMA6,
448 .port_ops = &ahci_ops, 448 .port_ops = &ahci_ops,
449 }, 449 },
450 /* board_ahci_sb700, for SB700 and SB800 */ 450 [board_ahci_sb700] = /* for SB700 and SB800 */
451 { 451 {
452 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), 452 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
453 .flags = AHCI_FLAG_COMMON, 453 .flags = AHCI_FLAG_COMMON,
@@ -455,7 +455,7 @@ static const struct ata_port_info ahci_port_info[] = {
455 .udma_mask = ATA_UDMA6, 455 .udma_mask = ATA_UDMA6,
456 .port_ops = &ahci_sb600_ops, 456 .port_ops = &ahci_sb600_ops,
457 }, 457 },
458 /* board_ahci_mcp65 */ 458 [board_ahci_mcp65] =
459 { 459 {
460 AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), 460 AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
461 .flags = AHCI_FLAG_COMMON, 461 .flags = AHCI_FLAG_COMMON,
@@ -463,7 +463,7 @@ static const struct ata_port_info ahci_port_info[] = {
463 .udma_mask = ATA_UDMA6, 463 .udma_mask = ATA_UDMA6,
464 .port_ops = &ahci_ops, 464 .port_ops = &ahci_ops,
465 }, 465 },
466 /* board_ahci_nopmp */ 466 [board_ahci_nopmp] =
467 { 467 {
468 AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), 468 AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
469 .flags = AHCI_FLAG_COMMON, 469 .flags = AHCI_FLAG_COMMON,
@@ -1141,12 +1141,12 @@ static void ahci_start_port(struct ata_port *ap)
1141 emp = &pp->em_priv[link->pmp]; 1141 emp = &pp->em_priv[link->pmp];
1142 1142
1143 /* EM Transmit bit maybe busy during init */ 1143 /* EM Transmit bit maybe busy during init */
1144 for (i = 0; i < MAX_RETRY; i++) { 1144 for (i = 0; i < EM_MAX_RETRY; i++) {
1145 rc = ahci_transmit_led_message(ap, 1145 rc = ahci_transmit_led_message(ap,
1146 emp->led_state, 1146 emp->led_state,
1147 4); 1147 4);
1148 if (rc == -EBUSY) 1148 if (rc == -EBUSY)
1149 udelay(100); 1149 msleep(1);
1150 else 1150 else
1151 break; 1151 break;
1152 } 1152 }
@@ -1340,7 +1340,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
1340 1340
1341 /* get the slot number from the message */ 1341 /* get the slot number from the message */
1342 pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; 1342 pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
1343 if (pmp < MAX_SLOTS) 1343 if (pmp < EM_MAX_SLOTS)
1344 emp = &pp->em_priv[pmp]; 1344 emp = &pp->em_priv[pmp];
1345 else 1345 else
1346 return -EINVAL; 1346 return -EINVAL;
@@ -1408,7 +1408,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
1408 1408
1409 /* get the slot number from the message */ 1409 /* get the slot number from the message */
1410 pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; 1410 pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
1411 if (pmp < MAX_SLOTS) 1411 if (pmp < EM_MAX_SLOTS)
1412 emp = &pp->em_priv[pmp]; 1412 emp = &pp->em_priv[pmp];
1413 else 1413 else
1414 return -EINVAL; 1414 return -EINVAL;
@@ -2584,6 +2584,51 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
2584 } 2584 }
2585} 2585}
2586 2586
2587/*
2588 * SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older
2589 * BIOS. The oldest version known to be broken is 0901 and working is
2590 * 1501 which was released on 2007-10-26. Force 32bit DMA on anything
2591 * older than 1501. Please read bko#9412 for more info.
2592 */
2593static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev)
2594{
2595 static const struct dmi_system_id sysids[] = {
2596 {
2597 .ident = "ASUS M2A-VM",
2598 .matches = {
2599 DMI_MATCH(DMI_BOARD_VENDOR,
2600 "ASUSTeK Computer INC."),
2601 DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
2602 },
2603 },
2604 { }
2605 };
2606 const char *cutoff_mmdd = "10/26";
2607 const char *date;
2608 int year;
2609
2610 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
2611 !dmi_check_system(sysids))
2612 return false;
2613
2614 /*
2615 * Argh.... both version and date are free form strings.
2616 * Let's hope they're using the same date format across
2617 * different versions.
2618 */
2619 date = dmi_get_system_info(DMI_BIOS_DATE);
2620 year = dmi_get_year(DMI_BIOS_DATE);
2621 if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' &&
2622 (year > 2007 ||
2623 (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0)))
2624 return false;
2625
2626 dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, "
2627 "forcing 32bit DMA, update BIOS\n");
2628
2629 return true;
2630}
2631
2587static bool ahci_broken_system_poweroff(struct pci_dev *pdev) 2632static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
2588{ 2633{
2589 static const struct dmi_system_id broken_systems[] = { 2634 static const struct dmi_system_id broken_systems[] = {
@@ -2744,6 +2789,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2744 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) 2789 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
2745 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; 2790 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
2746 2791
2792 /* apply ASUS M2A_VM quirk */
2793 if (ahci_asus_m2a_vm_32bit_only(pdev))
2794 hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
2795
2747 if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) 2796 if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
2748 pci_enable_msi(pdev); 2797 pci_enable_msi(pdev);
2749 2798