diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-09-02 02:17:56 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-02 02:17:56 -0400 |
commit | 936e894a976dd3b0f07f1f6f43c17b77b7e6146d (patch) | |
tree | 5ed5c1f6735dcd26550594df23c8f7fe2aa21a15 /drivers/ata/ahci.c | |
parent | 69575d388603365f2afbf4166df93152df59b165 (diff) | |
parent | 326ba5010a5429a5a528b268b36a5900d4ab0eba (diff) |
Merge commit 'v2.6.31-rc8' into x86/txt
Conflicts:
arch/x86/kernel/reboot.c
security/Kconfig
Merge reason: resolve the conflicts, bump up from rc3 to rc8.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 336eb1ed73cc..fe3eba5d6b3e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -219,6 +219,8 @@ enum { | |||
219 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 219 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
220 | 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 */ | 221 | AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ |
222 | AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as | ||
223 | link offline */ | ||
222 | 224 | ||
223 | /* ap->flags bits */ | 225 | /* ap->flags bits */ |
224 | 226 | ||
@@ -515,10 +517,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
515 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ | 517 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ |
516 | { PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */ | 518 | { PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */ |
517 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ | 519 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ |
520 | { PCI_VDEVICE(INTEL, 0x3b22), board_ahci }, /* PCH AHCI */ | ||
521 | { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ | ||
518 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ | 522 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ |
519 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ | 523 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ |
524 | { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */ | ||
520 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ | 525 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ |
521 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ | 526 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ |
527 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ | ||
522 | 528 | ||
523 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 529 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
524 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 530 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
@@ -1659,6 +1665,7 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
1659 | int (*check_ready)(struct ata_link *link)) | 1665 | int (*check_ready)(struct ata_link *link)) |
1660 | { | 1666 | { |
1661 | struct ata_port *ap = link->ap; | 1667 | struct ata_port *ap = link->ap; |
1668 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
1662 | const char *reason = NULL; | 1669 | const char *reason = NULL; |
1663 | unsigned long now, msecs; | 1670 | unsigned long now, msecs; |
1664 | struct ata_taskfile tf; | 1671 | struct ata_taskfile tf; |
@@ -1697,12 +1704,21 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, | |||
1697 | 1704 | ||
1698 | /* wait for link to become ready */ | 1705 | /* wait for link to become ready */ |
1699 | rc = ata_wait_after_reset(link, deadline, check_ready); | 1706 | rc = ata_wait_after_reset(link, deadline, check_ready); |
1700 | /* link occupied, -ENODEV too is an error */ | 1707 | if (rc == -EBUSY && hpriv->flags & AHCI_HFLAG_SRST_TOUT_IS_OFFLINE) { |
1701 | if (rc) { | 1708 | /* |
1709 | * Workaround for cases where link online status can't | ||
1710 | * be trusted. Treat device readiness timeout as link | ||
1711 | * offline. | ||
1712 | */ | ||
1713 | ata_link_printk(link, KERN_INFO, | ||
1714 | "device not ready, treating as offline\n"); | ||
1715 | *class = ATA_DEV_NONE; | ||
1716 | } else if (rc) { | ||
1717 | /* link occupied, -ENODEV too is an error */ | ||
1702 | reason = "device not ready"; | 1718 | reason = "device not ready"; |
1703 | goto fail; | 1719 | goto fail; |
1704 | } | 1720 | } else |
1705 | *class = ahci_dev_classify(ap); | 1721 | *class = ahci_dev_classify(ap); |
1706 | 1722 | ||
1707 | DPRINTK("EXIT, class=%u\n", *class); | 1723 | DPRINTK("EXIT, class=%u\n", *class); |
1708 | return 0; | 1724 | return 0; |
@@ -1769,7 +1785,8 @@ static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, | |||
1769 | irq_sts = readl(port_mmio + PORT_IRQ_STAT); | 1785 | irq_sts = readl(port_mmio + PORT_IRQ_STAT); |
1770 | if (irq_sts & PORT_IRQ_BAD_PMP) { | 1786 | if (irq_sts & PORT_IRQ_BAD_PMP) { |
1771 | ata_link_printk(link, KERN_WARNING, | 1787 | ata_link_printk(link, KERN_WARNING, |
1772 | "failed due to HW bug, retry pmp=0\n"); | 1788 | "applying SB600 PMP SRST workaround " |
1789 | "and retrying\n"); | ||
1773 | rc = ahci_do_softreset(link, class, 0, deadline, | 1790 | rc = ahci_do_softreset(link, class, 0, deadline, |
1774 | ahci_check_ready); | 1791 | ahci_check_ready); |
1775 | } | 1792 | } |
@@ -2722,6 +2739,56 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2722 | return !ver || strcmp(ver, dmi->driver_data) < 0; | 2739 | return !ver || strcmp(ver, dmi->driver_data) < 0; |
2723 | } | 2740 | } |
2724 | 2741 | ||
2742 | static bool ahci_broken_online(struct pci_dev *pdev) | ||
2743 | { | ||
2744 | #define ENCODE_BUSDEVFN(bus, slot, func) \ | ||
2745 | (void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func))) | ||
2746 | static const struct dmi_system_id sysids[] = { | ||
2747 | /* | ||
2748 | * There are several gigabyte boards which use | ||
2749 | * SIMG5723s configured as hardware RAID. Certain | ||
2750 | * 5723 firmware revisions shipped there keep the link | ||
2751 | * online but fail to answer properly to SRST or | ||
2752 | * IDENTIFY when no device is attached downstream | ||
2753 | * causing libata to retry quite a few times leading | ||
2754 | * to excessive detection delay. | ||
2755 | * | ||
2756 | * As these firmwares respond to the second reset try | ||
2757 | * with invalid device signature, considering unknown | ||
2758 | * sig as offline works around the problem acceptably. | ||
2759 | */ | ||
2760 | { | ||
2761 | .ident = "EP45-DQ6", | ||
2762 | .matches = { | ||
2763 | DMI_MATCH(DMI_BOARD_VENDOR, | ||
2764 | "Gigabyte Technology Co., Ltd."), | ||
2765 | DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"), | ||
2766 | }, | ||
2767 | .driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0), | ||
2768 | }, | ||
2769 | { | ||
2770 | .ident = "EP45-DS5", | ||
2771 | .matches = { | ||
2772 | DMI_MATCH(DMI_BOARD_VENDOR, | ||
2773 | "Gigabyte Technology Co., Ltd."), | ||
2774 | DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"), | ||
2775 | }, | ||
2776 | .driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0), | ||
2777 | }, | ||
2778 | { } /* terminate list */ | ||
2779 | }; | ||
2780 | #undef ENCODE_BUSDEVFN | ||
2781 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | ||
2782 | unsigned int val; | ||
2783 | |||
2784 | if (!dmi) | ||
2785 | return false; | ||
2786 | |||
2787 | val = (unsigned long)dmi->driver_data; | ||
2788 | |||
2789 | return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); | ||
2790 | } | ||
2791 | |||
2725 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2792 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2726 | { | 2793 | { |
2727 | static int printed_version; | 2794 | static int printed_version; |
@@ -2837,6 +2904,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2837 | "BIOS update required for suspend/resume\n"); | 2904 | "BIOS update required for suspend/resume\n"); |
2838 | } | 2905 | } |
2839 | 2906 | ||
2907 | if (ahci_broken_online(pdev)) { | ||
2908 | hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE; | ||
2909 | dev_info(&pdev->dev, | ||
2910 | "online status unreliable, applying workaround\n"); | ||
2911 | } | ||
2912 | |||
2840 | /* CAP.NP sometimes indicate the index of the last enabled | 2913 | /* CAP.NP sometimes indicate the index of the last enabled |
2841 | * port, at other times, that of the last possible port, so | 2914 | * port, at other times, that of the last possible port, so |
2842 | * determining the maximum port number requires looking at | 2915 | * determining the maximum port number requires looking at |