summaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-06 15:09:43 +0900
committerJeff Garzik <jeff@garzik.org>2007-12-07 15:27:54 -0500
commitc4f7792c021cda9bbf65d0bc2253a593fd652b91 (patch)
treee0c727ba1bc934a8cbc58515c5b33e16eecde8a2 /drivers/ata
parentd1aa690a7d1afa673c3383bfcd6e96ddb350939a (diff)
downloadkernel-crypto-c4f7792c021cda9bbf65d0bc2253a593fd652b91.tar.gz
kernel-crypto-c4f7792c021cda9bbf65d0bc2253a593fd652b91.tar.xz
kernel-crypto-c4f7792c021cda9bbf65d0bc2253a593fd652b91.zip
ahci: don't attach if ICH6 is in combined mode
ICH6 R/Ms share PCI ID between piix and ahci modes and we've been allowing ahci to attach regardless of how BIOS configured it. However, enabling AHCI mode when the controller is in combined mode can result in unexpected behavior. Don't attach if the controller is in combined mode. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Bill Nottingham <notting@redhat.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 588ab2fd59e..cb7853b7335 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -193,6 +193,8 @@ enum {
ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
ATA_FLAG_IPM,
AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY,
+
+ ICH_MAP = 0x90, /* ICH MAP register */
};
struct ahci_cmd_hdr {
@@ -2273,6 +2275,22 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+ (pdev->device == 0x2652 || pdev->device == 0x2653)) {
+ u8 map;
+
+ /* ICH6s share the same PCI ID for both piix and ahci
+ * modes. Enabling ahci mode while MAP indicates
+ * combined mode is a bad idea. Yield to ata_piix.
+ */
+ pci_read_config_byte(pdev, ICH_MAP, &map);
+ if (map & 0x3) {
+ dev_printk(KERN_INFO, &pdev->dev, "controller is in "
+ "combined mode, can't enable AHCI mode\n");
+ return -ENODEV;
+ }
+ }
+
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;