diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 159 |
1 files changed, 140 insertions, 19 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 08186ecbaf8d..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); |
78 | static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | 78 | static 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 | ||
83 | enum { | 81 | enum { |
84 | AHCI_PCI_BAR = 5, | 82 | AHCI_PCI_BAR = 5, |
@@ -220,6 +218,7 @@ enum { | |||
220 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 218 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
221 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 219 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
222 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | 220 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ |
221 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ | ||
223 | 222 | ||
224 | /* ap->flags bits */ | 223 | /* ap->flags bits */ |
225 | 224 | ||
@@ -230,6 +229,10 @@ enum { | |||
230 | 229 | ||
231 | ICH_MAP = 0x90, /* ICH MAP register */ | 230 | ICH_MAP = 0x90, /* ICH MAP register */ |
232 | 231 | ||
232 | /* em constants */ | ||
233 | EM_MAX_SLOTS = 8, | ||
234 | EM_MAX_RETRY = 5, | ||
235 | |||
233 | /* em_ctl bits */ | 236 | /* em_ctl bits */ |
234 | EM_CTL_RST = (1 << 9), /* Reset */ | 237 | EM_CTL_RST = (1 << 9), /* Reset */ |
235 | EM_CTL_TM = (1 << 8), /* Transmit Message */ | 238 | EM_CTL_TM = (1 << 8), /* Transmit Message */ |
@@ -281,8 +284,8 @@ struct ahci_port_priv { | |||
281 | unsigned int ncq_saw_dmas:1; | 284 | unsigned int ncq_saw_dmas:1; |
282 | unsigned int ncq_saw_sdb:1; | 285 | unsigned int ncq_saw_sdb:1; |
283 | u32 intr_mask; /* interrupts to enable */ | 286 | u32 intr_mask; /* interrupts to enable */ |
284 | struct ahci_em_priv em_priv[MAX_SLOTS];/* enclosure management info | 287 | /* enclosure management info per PM slot */ |
285 | * per PM slot */ | 288 | struct ahci_em_priv em_priv[EM_MAX_SLOTS]; |
286 | }; | 289 | }; |
287 | 290 | ||
288 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 291 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
@@ -312,7 +315,6 @@ static void ahci_error_handler(struct ata_port *ap); | |||
312 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 315 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
313 | static int ahci_port_resume(struct ata_port *ap); | 316 | static int ahci_port_resume(struct ata_port *ap); |
314 | static void ahci_dev_config(struct ata_device *dev); | 317 | static void ahci_dev_config(struct ata_device *dev); |
315 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); | ||
316 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 318 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
317 | u32 opts); | 319 | u32 opts); |
318 | #ifdef CONFIG_PM | 320 | #ifdef CONFIG_PM |
@@ -403,14 +405,14 @@ static struct ata_port_operations ahci_sb600_ops = { | |||
403 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 405 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
404 | 406 | ||
405 | static const struct ata_port_info ahci_port_info[] = { | 407 | static const struct ata_port_info ahci_port_info[] = { |
406 | /* board_ahci */ | 408 | [board_ahci] = |
407 | { | 409 | { |
408 | .flags = AHCI_FLAG_COMMON, | 410 | .flags = AHCI_FLAG_COMMON, |
409 | .pio_mask = ATA_PIO4, | 411 | .pio_mask = ATA_PIO4, |
410 | .udma_mask = ATA_UDMA6, | 412 | .udma_mask = ATA_UDMA6, |
411 | .port_ops = &ahci_ops, | 413 | .port_ops = &ahci_ops, |
412 | }, | 414 | }, |
413 | /* board_ahci_vt8251 */ | 415 | [board_ahci_vt8251] = |
414 | { | 416 | { |
415 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), | 417 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), |
416 | .flags = AHCI_FLAG_COMMON, | 418 | .flags = AHCI_FLAG_COMMON, |
@@ -418,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
418 | .udma_mask = ATA_UDMA6, | 420 | .udma_mask = ATA_UDMA6, |
419 | .port_ops = &ahci_vt8251_ops, | 421 | .port_ops = &ahci_vt8251_ops, |
420 | }, | 422 | }, |
421 | /* board_ahci_ign_iferr */ | 423 | [board_ahci_ign_iferr] = |
422 | { | 424 | { |
423 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), | 425 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), |
424 | .flags = AHCI_FLAG_COMMON, | 426 | .flags = AHCI_FLAG_COMMON, |
@@ -426,17 +428,16 @@ static const struct ata_port_info ahci_port_info[] = { | |||
426 | .udma_mask = ATA_UDMA6, | 428 | .udma_mask = ATA_UDMA6, |
427 | .port_ops = &ahci_ops, | 429 | .port_ops = &ahci_ops, |
428 | }, | 430 | }, |
429 | /* board_ahci_sb600 */ | 431 | [board_ahci_sb600] = |
430 | { | 432 | { |
431 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 433 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
432 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | 434 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), |
433 | AHCI_HFLAG_SECT255), | ||
434 | .flags = AHCI_FLAG_COMMON, | 435 | .flags = AHCI_FLAG_COMMON, |
435 | .pio_mask = ATA_PIO4, | 436 | .pio_mask = ATA_PIO4, |
436 | .udma_mask = ATA_UDMA6, | 437 | .udma_mask = ATA_UDMA6, |
437 | .port_ops = &ahci_sb600_ops, | 438 | .port_ops = &ahci_sb600_ops, |
438 | }, | 439 | }, |
439 | /* board_ahci_mv */ | 440 | [board_ahci_mv] = |
440 | { | 441 | { |
441 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | | 442 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | |
442 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), | 443 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), |
@@ -446,7 +447,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
446 | .udma_mask = ATA_UDMA6, | 447 | .udma_mask = ATA_UDMA6, |
447 | .port_ops = &ahci_ops, | 448 | .port_ops = &ahci_ops, |
448 | }, | 449 | }, |
449 | /* board_ahci_sb700, for SB700 and SB800 */ | 450 | [board_ahci_sb700] = /* for SB700 and SB800 */ |
450 | { | 451 | { |
451 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), | 452 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), |
452 | .flags = AHCI_FLAG_COMMON, | 453 | .flags = AHCI_FLAG_COMMON, |
@@ -454,7 +455,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
454 | .udma_mask = ATA_UDMA6, | 455 | .udma_mask = ATA_UDMA6, |
455 | .port_ops = &ahci_sb600_ops, | 456 | .port_ops = &ahci_sb600_ops, |
456 | }, | 457 | }, |
457 | /* board_ahci_mcp65 */ | 458 | [board_ahci_mcp65] = |
458 | { | 459 | { |
459 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | 460 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), |
460 | .flags = AHCI_FLAG_COMMON, | 461 | .flags = AHCI_FLAG_COMMON, |
@@ -462,7 +463,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
462 | .udma_mask = ATA_UDMA6, | 463 | .udma_mask = ATA_UDMA6, |
463 | .port_ops = &ahci_ops, | 464 | .port_ops = &ahci_ops, |
464 | }, | 465 | }, |
465 | /* board_ahci_nopmp */ | 466 | [board_ahci_nopmp] = |
466 | { | 467 | { |
467 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), | 468 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), |
468 | .flags = AHCI_FLAG_COMMON, | 469 | .flags = AHCI_FLAG_COMMON, |
@@ -1140,12 +1141,12 @@ static void ahci_start_port(struct ata_port *ap) | |||
1140 | emp = &pp->em_priv[link->pmp]; | 1141 | emp = &pp->em_priv[link->pmp]; |
1141 | 1142 | ||
1142 | /* EM Transmit bit maybe busy during init */ | 1143 | /* EM Transmit bit maybe busy during init */ |
1143 | for (i = 0; i < MAX_RETRY; i++) { | 1144 | for (i = 0; i < EM_MAX_RETRY; i++) { |
1144 | rc = ahci_transmit_led_message(ap, | 1145 | rc = ahci_transmit_led_message(ap, |
1145 | emp->led_state, | 1146 | emp->led_state, |
1146 | 4); | 1147 | 4); |
1147 | if (rc == -EBUSY) | 1148 | if (rc == -EBUSY) |
1148 | udelay(100); | 1149 | msleep(1); |
1149 | else | 1150 | else |
1150 | break; | 1151 | break; |
1151 | } | 1152 | } |
@@ -1339,7 +1340,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1339 | 1340 | ||
1340 | /* get the slot number from the message */ | 1341 | /* get the slot number from the message */ |
1341 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | 1342 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; |
1342 | if (pmp < MAX_SLOTS) | 1343 | if (pmp < EM_MAX_SLOTS) |
1343 | emp = &pp->em_priv[pmp]; | 1344 | emp = &pp->em_priv[pmp]; |
1344 | else | 1345 | else |
1345 | return -EINVAL; | 1346 | return -EINVAL; |
@@ -1407,7 +1408,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | |||
1407 | 1408 | ||
1408 | /* get the slot number from the message */ | 1409 | /* get the slot number from the message */ |
1409 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | 1410 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; |
1410 | if (pmp < MAX_SLOTS) | 1411 | if (pmp < EM_MAX_SLOTS) |
1411 | emp = &pp->em_priv[pmp]; | 1412 | emp = &pp->em_priv[pmp]; |
1412 | else | 1413 | else |
1413 | return -EINVAL; | 1414 | return -EINVAL; |
@@ -2316,9 +2317,17 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) | |||
2316 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) | 2317 | static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) |
2317 | { | 2318 | { |
2318 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 2319 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
2320 | struct ahci_host_priv *hpriv = host->private_data; | ||
2319 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; | 2321 | void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; |
2320 | u32 ctl; | 2322 | u32 ctl; |
2321 | 2323 | ||
2324 | if (mesg.event & PM_EVENT_SUSPEND && | ||
2325 | hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { | ||
2326 | dev_printk(KERN_ERR, &pdev->dev, | ||
2327 | "BIOS update required for suspend/resume\n"); | ||
2328 | return -EIO; | ||
2329 | } | ||
2330 | |||
2322 | if (mesg.event & PM_EVENT_SLEEP) { | 2331 | if (mesg.event & PM_EVENT_SLEEP) { |
2323 | /* AHCI spec rev1.1 section 8.3.3: | 2332 | /* AHCI spec rev1.1 section 8.3.3: |
2324 | * Software must disable interrupts prior to requesting a | 2333 | * Software must disable interrupts prior to requesting a |
@@ -2575,6 +2584,51 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2575 | } | 2584 | } |
2576 | } | 2585 | } |
2577 | 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 | */ | ||
2593 | static 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 | |||
2578 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | 2632 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) |
2579 | { | 2633 | { |
2580 | static const struct dmi_system_id broken_systems[] = { | 2634 | static const struct dmi_system_id broken_systems[] = { |
@@ -2610,6 +2664,63 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | |||
2610 | return false; | 2664 | return false; |
2611 | } | 2665 | } |
2612 | 2666 | ||
2667 | static bool ahci_broken_suspend(struct pci_dev *pdev) | ||
2668 | { | ||
2669 | static const struct dmi_system_id sysids[] = { | ||
2670 | /* | ||
2671 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link | ||
2672 | * to the harddisk doesn't become online after | ||
2673 | * resuming from STR. Warn and fail suspend. | ||
2674 | */ | ||
2675 | { | ||
2676 | .ident = "dv4", | ||
2677 | .matches = { | ||
2678 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2679 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2680 | "HP Pavilion dv4 Notebook PC"), | ||
2681 | }, | ||
2682 | .driver_data = "F.30", /* cutoff BIOS version */ | ||
2683 | }, | ||
2684 | { | ||
2685 | .ident = "dv5", | ||
2686 | .matches = { | ||
2687 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2688 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2689 | "HP Pavilion dv5 Notebook PC"), | ||
2690 | }, | ||
2691 | .driver_data = "F.16", /* cutoff BIOS version */ | ||
2692 | }, | ||
2693 | { | ||
2694 | .ident = "dv6", | ||
2695 | .matches = { | ||
2696 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2697 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2698 | "HP Pavilion dv6 Notebook PC"), | ||
2699 | }, | ||
2700 | .driver_data = "F.21", /* cutoff BIOS version */ | ||
2701 | }, | ||
2702 | { | ||
2703 | .ident = "HDX18", | ||
2704 | .matches = { | ||
2705 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2706 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2707 | "HP HDX18 Notebook PC"), | ||
2708 | }, | ||
2709 | .driver_data = "F.23", /* cutoff BIOS version */ | ||
2710 | }, | ||
2711 | { } /* terminate list */ | ||
2712 | }; | ||
2713 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | ||
2714 | const char *ver; | ||
2715 | |||
2716 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) | ||
2717 | return false; | ||
2718 | |||
2719 | ver = dmi_get_system_info(DMI_BIOS_VERSION); | ||
2720 | |||
2721 | return !ver || strcmp(ver, dmi->driver_data) < 0; | ||
2722 | } | ||
2723 | |||
2613 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2724 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2614 | { | 2725 | { |
2615 | static int printed_version; | 2726 | static int printed_version; |
@@ -2678,6 +2789,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2678 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) | 2789 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2679 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2790 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2680 | 2791 | ||
2792 | /* apply ASUS M2A_VM quirk */ | ||
2793 | if (ahci_asus_m2a_vm_32bit_only(pdev)) | ||
2794 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; | ||
2795 | |||
2681 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) | 2796 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) |
2682 | pci_enable_msi(pdev); | 2797 | pci_enable_msi(pdev); |
2683 | 2798 | ||
@@ -2715,6 +2830,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2715 | "quirky BIOS, skipping spindown on poweroff\n"); | 2830 | "quirky BIOS, skipping spindown on poweroff\n"); |
2716 | } | 2831 | } |
2717 | 2832 | ||
2833 | if (ahci_broken_suspend(pdev)) { | ||
2834 | hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; | ||
2835 | dev_printk(KERN_WARNING, &pdev->dev, | ||
2836 | "BIOS update required for suspend/resume\n"); | ||
2837 | } | ||
2838 | |||
2718 | /* CAP.NP sometimes indicate the index of the last enabled | 2839 | /* CAP.NP sometimes indicate the index of the last enabled |
2719 | * port, at other times, that of the last possible port, so | 2840 | * port, at other times, that of the last possible port, so |
2720 | * determining the maximum port number requires looking at | 2841 | * determining the maximum port number requires looking at |