aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-06 01:09:43 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-07 15:27:54 -0500
commitc4f7792c021cda9bbf65d0bc2253a593fd652b91 (patch)
treee0c727ba1bc934a8cbc58515c5b33e16eecde8a2
parentd1aa690a7d1afa673c3383bfcd6e96ddb350939a (diff)
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>
-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 {
193 ATA_FLAG_ACPI_SATA | ATA_FLAG_AN | 193 ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
194 ATA_FLAG_IPM, 194 ATA_FLAG_IPM,
195 AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY, 195 AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY,
196
197 ICH_MAP = 0x90, /* ICH MAP register */
196}; 198};
197 199
198struct ahci_cmd_hdr { 200struct ahci_cmd_hdr {
@@ -2273,6 +2275,22 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2273 if (rc) 2275 if (rc)
2274 return rc; 2276 return rc;
2275 2277
2278 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
2279 (pdev->device == 0x2652 || pdev->device == 0x2653)) {
2280 u8 map;
2281
2282 /* ICH6s share the same PCI ID for both piix and ahci
2283 * modes. Enabling ahci mode while MAP indicates
2284 * combined mode is a bad idea. Yield to ata_piix.
2285 */
2286 pci_read_config_byte(pdev, ICH_MAP, &map);
2287 if (map & 0x3) {
2288 dev_printk(KERN_INFO, &pdev->dev, "controller is in "
2289 "combined mode, can't enable AHCI mode\n");
2290 return -ENODEV;
2291 }
2292 }
2293
2276 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 2294 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
2277 if (!hpriv) 2295 if (!hpriv)
2278 return -ENOMEM; 2296 return -ENOMEM;