diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 7f701cbe14ab..a603bbf9b1b7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -61,9 +61,14 @@ | |||
61 | #define EM_MSG_LED_VALUE_ON 0x00010000 | 61 | #define EM_MSG_LED_VALUE_ON 0x00010000 |
62 | 62 | ||
63 | static int ahci_skip_host_reset; | 63 | static int ahci_skip_host_reset; |
64 | static int ahci_ignore_sss; | ||
65 | |||
64 | module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); | 66 | module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); |
65 | MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); | 67 | MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); |
66 | 68 | ||
69 | module_param_named(ignore_sss, ahci_ignore_sss, int, 0444); | ||
70 | MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)"); | ||
71 | |||
67 | static int ahci_enable_alpm(struct ata_port *ap, | 72 | static int ahci_enable_alpm(struct ata_port *ap, |
68 | enum link_pm policy); | 73 | enum link_pm policy); |
69 | static void ahci_disable_alpm(struct ata_port *ap); | 74 | static void ahci_disable_alpm(struct ata_port *ap); |
@@ -2548,6 +2553,32 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2548 | } | 2553 | } |
2549 | } | 2554 | } |
2550 | 2555 | ||
2556 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | ||
2557 | { | ||
2558 | static const struct dmi_system_id broken_systems[] = { | ||
2559 | { | ||
2560 | .ident = "HP Compaq nx6310", | ||
2561 | .matches = { | ||
2562 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2563 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"), | ||
2564 | }, | ||
2565 | /* PCI slot number of the controller */ | ||
2566 | .driver_data = (void *)0x1FUL, | ||
2567 | }, | ||
2568 | |||
2569 | { } /* terminate list */ | ||
2570 | }; | ||
2571 | const struct dmi_system_id *dmi = dmi_first_match(broken_systems); | ||
2572 | |||
2573 | if (dmi) { | ||
2574 | unsigned long slot = (unsigned long)dmi->driver_data; | ||
2575 | /* apply the quirk only to on-board controllers */ | ||
2576 | return slot == PCI_SLOT(pdev->devfn); | ||
2577 | } | ||
2578 | |||
2579 | return false; | ||
2580 | } | ||
2581 | |||
2551 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2582 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2552 | { | 2583 | { |
2553 | static int printed_version; | 2584 | static int printed_version; |
@@ -2647,6 +2678,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2647 | } | 2678 | } |
2648 | } | 2679 | } |
2649 | 2680 | ||
2681 | if (ahci_broken_system_poweroff(pdev)) { | ||
2682 | pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN; | ||
2683 | dev_info(&pdev->dev, | ||
2684 | "quirky BIOS, skipping spindown on poweroff\n"); | ||
2685 | } | ||
2686 | |||
2650 | /* CAP.NP sometimes indicate the index of the last enabled | 2687 | /* CAP.NP sometimes indicate the index of the last enabled |
2651 | * port, at other times, that of the last possible port, so | 2688 | * port, at other times, that of the last possible port, so |
2652 | * determining the maximum port number requires looking at | 2689 | * determining the maximum port number requires looking at |
@@ -2660,6 +2697,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2660 | host->iomap = pcim_iomap_table(pdev); | 2697 | host->iomap = pcim_iomap_table(pdev); |
2661 | host->private_data = hpriv; | 2698 | host->private_data = hpriv; |
2662 | 2699 | ||
2700 | if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss) | ||
2701 | host->flags |= ATA_HOST_PARALLEL_SCAN; | ||
2702 | else | ||
2703 | printk(KERN_INFO "ahci: SSS flag set, parallel bus scan disabled\n"); | ||
2704 | |||
2663 | if (pi.flags & ATA_FLAG_EM) | 2705 | if (pi.flags & ATA_FLAG_EM) |
2664 | ahci_reset_em(host); | 2706 | ahci_reset_em(host); |
2665 | 2707 | ||