diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-24 23:22:55 +0100 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-03-24 23:22:55 +0100 |
commit | 62bd0441a60b0499db339b3dc1be039f8ed9fd35 (patch) | |
tree | 8704e305e665bb8aee277f6e408b2195b52f4db9 /drivers/ide/ide-iops.c | |
parent | 2f40c9b0b65b5635e2e13dfa068bd56fe7a8ff98 (diff) | |
download | lwn-62bd0441a60b0499db339b3dc1be039f8ed9fd35.tar.gz lwn-62bd0441a60b0499db339b3dc1be039f8ed9fd35.zip |
ide: propagate AltStatus workarounds to ide_driveid_update()
Propagate AltStatus workarounds from try_to_identify()
to ide_driveid_update().
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index a955483d2404..944cd857c90a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -293,8 +293,8 @@ int ide_driveid_update(ide_drive_t *drive) const struct ide_tp_ops *tp_ops = hwif->tp_ops; u16 *id; unsigned long flags; - int rc; - u8 uninitialized_var(s); + int use_altstatus = 0, rc; + u8 a, uninitialized_var(s); id = kmalloc(SECTOR_SIZE, GFP_ATOMIC); if (id == NULL) @@ -308,9 +308,24 @@ int ide_driveid_update(ide_drive_t *drive) SELECT_MASK(drive, 1); tp_ops->set_irq(hwif, 0); msleep(50); + + if (hwif->io_ports.ctl_addr && + (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) { + a = tp_ops->read_altstatus(hwif); + s = tp_ops->read_status(hwif); + if ((a ^ s) & ~ATA_IDX) + /* ancient Seagate drives, broken interfaces */ + printk(KERN_INFO "%s: probing with STATUS(0x%02x) " + "instead of ALTSTATUS(0x%02x)\n", + drive->name, s, a); + else + /* use non-intrusive polling */ + use_altstatus = 1; + } + tp_ops->exec_command(hwif, ATA_CMD_ID_ATA); - if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) { + if (ide_busy_sleep(hwif, WAIT_WORSTCASE, use_altstatus)) { rc = 1; goto out_err; } |