diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-05 14:53:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-05 14:53:44 -0400 |
commit | be94a4ba093c75e06b6fd2b0476f34812fbd359e (patch) | |
tree | 0e6929aa585c3d5bf576f214457ab67dd02474f4 /drivers | |
parent | a4e4b646eb62ca4ce755e2c17aef8f42c8608821 (diff) | |
parent | 65e31643115349fd7a81acbe75ec4a54d5df8aad (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
ata_piix: Add HP Compaq nc6000 to the broken poweroff list
ahci: add warning messages for hp laptops with broken suspend
pata_efar: fix PIO2 underclocking
pata_legacy: wait for async probing
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ahci.c | 72 | ||||
-rw-r--r-- | drivers/ata/ata_piix.c | 9 | ||||
-rw-r--r-- | drivers/ata/pata_efar.c | 17 | ||||
-rw-r--r-- | drivers/ata/pata_legacy.c | 2 |
4 files changed, 91 insertions, 9 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 08186ecbaf8d..6b91c26a4635 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -220,6 +220,7 @@ enum { | |||
220 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 220 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
221 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 221 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
222 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | 222 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ |
223 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ | ||
223 | 224 | ||
224 | /* ap->flags bits */ | 225 | /* ap->flags bits */ |
225 | 226 | ||
@@ -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 |
@@ -2610,6 +2619,63 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | |||
2610 | return false; | 2619 | return false; |
2611 | } | 2620 | } |
2612 | 2621 | ||
2622 | static bool ahci_broken_suspend(struct pci_dev *pdev) | ||
2623 | { | ||
2624 | static const struct dmi_system_id sysids[] = { | ||
2625 | /* | ||
2626 | * On HP dv[4-6] and HDX18 with earlier BIOSen, link | ||
2627 | * to the harddisk doesn't become online after | ||
2628 | * resuming from STR. Warn and fail suspend. | ||
2629 | */ | ||
2630 | { | ||
2631 | .ident = "dv4", | ||
2632 | .matches = { | ||
2633 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2634 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2635 | "HP Pavilion dv4 Notebook PC"), | ||
2636 | }, | ||
2637 | .driver_data = "F.30", /* cutoff BIOS version */ | ||
2638 | }, | ||
2639 | { | ||
2640 | .ident = "dv5", | ||
2641 | .matches = { | ||
2642 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2643 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2644 | "HP Pavilion dv5 Notebook PC"), | ||
2645 | }, | ||
2646 | .driver_data = "F.16", /* cutoff BIOS version */ | ||
2647 | }, | ||
2648 | { | ||
2649 | .ident = "dv6", | ||
2650 | .matches = { | ||
2651 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2652 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2653 | "HP Pavilion dv6 Notebook PC"), | ||
2654 | }, | ||
2655 | .driver_data = "F.21", /* cutoff BIOS version */ | ||
2656 | }, | ||
2657 | { | ||
2658 | .ident = "HDX18", | ||
2659 | .matches = { | ||
2660 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
2661 | DMI_MATCH(DMI_PRODUCT_NAME, | ||
2662 | "HP HDX18 Notebook PC"), | ||
2663 | }, | ||
2664 | .driver_data = "F.23", /* cutoff BIOS version */ | ||
2665 | }, | ||
2666 | { } /* terminate list */ | ||
2667 | }; | ||
2668 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | ||
2669 | const char *ver; | ||
2670 | |||
2671 | if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) | ||
2672 | return false; | ||
2673 | |||
2674 | ver = dmi_get_system_info(DMI_BIOS_VERSION); | ||
2675 | |||
2676 | return !ver || strcmp(ver, dmi->driver_data) < 0; | ||
2677 | } | ||
2678 | |||
2613 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2679 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2614 | { | 2680 | { |
2615 | static int printed_version; | 2681 | static int printed_version; |
@@ -2715,6 +2781,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2715 | "quirky BIOS, skipping spindown on poweroff\n"); | 2781 | "quirky BIOS, skipping spindown on poweroff\n"); |
2716 | } | 2782 | } |
2717 | 2783 | ||
2784 | if (ahci_broken_suspend(pdev)) { | ||
2785 | hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; | ||
2786 | dev_printk(KERN_WARNING, &pdev->dev, | ||
2787 | "BIOS update required for suspend/resume\n"); | ||
2788 | } | ||
2789 | |||
2718 | /* CAP.NP sometimes indicate the index of the last enabled | 2790 | /* CAP.NP sometimes indicate the index of the last enabled |
2719 | * port, at other times, that of the last possible port, so | 2791 | * port, at other times, that of the last possible port, so |
2720 | * determining the maximum port number requires looking at | 2792 | * determining the maximum port number requires looking at |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d51a17c0f59b..1aeb7082b0c4 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -1455,6 +1455,15 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) | |||
1455 | /* PCI slot number of the controller */ | 1455 | /* PCI slot number of the controller */ |
1456 | .driver_data = (void *)0x1FUL, | 1456 | .driver_data = (void *)0x1FUL, |
1457 | }, | 1457 | }, |
1458 | { | ||
1459 | .ident = "HP Compaq nc6000", | ||
1460 | .matches = { | ||
1461 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1462 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6000"), | ||
1463 | }, | ||
1464 | /* PCI slot number of the controller */ | ||
1465 | .driver_data = (void *)0x1FUL, | ||
1466 | }, | ||
1458 | 1467 | ||
1459 | { } /* terminate list */ | 1468 | { } /* terminate list */ |
1460 | }; | 1469 | }; |
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 2085e0a3a05a..2a6412f5d117 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/ata.h> | 22 | #include <linux/ata.h> |
23 | 23 | ||
24 | #define DRV_NAME "pata_efar" | 24 | #define DRV_NAME "pata_efar" |
25 | #define DRV_VERSION "0.4.4" | 25 | #define DRV_VERSION "0.4.5" |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * efar_pre_reset - Enable bits | 28 | * efar_pre_reset - Enable bits |
@@ -98,18 +98,17 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
98 | { 2, 1 }, | 98 | { 2, 1 }, |
99 | { 2, 3 }, }; | 99 | { 2, 3 }, }; |
100 | 100 | ||
101 | if (pio > 2) | 101 | if (pio > 1) |
102 | control |= 1; /* TIME1 enable */ | 102 | control |= 1; /* TIME */ |
103 | if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ | 103 | if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ |
104 | control |= 2; /* IE enable */ | 104 | control |= 2; /* IE */ |
105 | /* Intel specifies that the PPE functionality is for disk only */ | 105 | /* Intel specifies that the prefetch/posting is for disk only */ |
106 | if (adev->class == ATA_DEV_ATA) | 106 | if (adev->class == ATA_DEV_ATA) |
107 | control |= 4; /* PPE enable */ | 107 | control |= 4; /* PPE */ |
108 | 108 | ||
109 | pci_read_config_word(dev, idetm_port, &idetm_data); | 109 | pci_read_config_word(dev, idetm_port, &idetm_data); |
110 | 110 | ||
111 | /* Enable PPE, IE and TIME as appropriate */ | 111 | /* Set PPE, IE, and TIME as appropriate */ |
112 | |||
113 | if (adev->devno == 0) { | 112 | if (adev->devno == 0) { |
114 | idetm_data &= 0xCCF0; | 113 | idetm_data &= 0xCCF0; |
115 | idetm_data |= control; | 114 | idetm_data |= control; |
@@ -129,7 +128,7 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) | |||
129 | pci_write_config_byte(dev, 0x44, slave_data); | 128 | pci_write_config_byte(dev, 0x44, slave_data); |
130 | } | 129 | } |
131 | 130 | ||
132 | idetm_data |= 0x4000; /* Ensure SITRE is enabled */ | 131 | idetm_data |= 0x4000; /* Ensure SITRE is set */ |
133 | pci_write_config_word(dev, idetm_port, idetm_data); | 132 | pci_write_config_word(dev, idetm_port, idetm_data); |
134 | } | 133 | } |
135 | 134 | ||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index f72c6c5b820f..6932e56d179c 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -48,6 +48,7 @@ | |||
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | 50 | ||
51 | #include <linux/async.h> | ||
51 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
52 | #include <linux/module.h> | 53 | #include <linux/module.h> |
53 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
@@ -1028,6 +1029,7 @@ static __init int legacy_init_one(struct legacy_probe *probe) | |||
1028 | &legacy_sht); | 1029 | &legacy_sht); |
1029 | if (ret) | 1030 | if (ret) |
1030 | goto fail; | 1031 | goto fail; |
1032 | async_synchronize_full(); | ||
1031 | ld->platform_dev = pdev; | 1033 | ld->platform_dev = pdev; |
1032 | 1034 | ||
1033 | /* Nothing found means we drop the port as its probably not there */ | 1035 | /* Nothing found means we drop the port as its probably not there */ |