diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-09 13:17:30 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-09-09 13:17:30 +0000 |
commit | 258c3c91359faddd228bdcc316478d993dbd6aa3 (patch) | |
tree | 8d288529801cee47b96deafb5f6690a015ed9f45 /sys/dev/ata/ata-lowlevel.c | |
parent | bf61bd49f55cf9af9d54bf6c18a64e95eec4b29c (diff) | |
download | FreeBSD-src-258c3c91359faddd228bdcc316478d993dbd6aa3.zip FreeBSD-src-258c3c91359faddd228bdcc316478d993dbd6aa3.tar.gz |
Fix a problem where device detection would work unreliably on Serverworks
K2 SATA controllers. The chip's status register must be read first, and
as a long, for other registers to be correctly updated after a command, and
this includes the command sequence in device detection as well as the
previously handled case after interrupts. While here, clean up some
previous hacks related to this controller.
Reported by: many
Reviewed by: mav
MFC after: 3 weeks
Diffstat (limited to 'sys/dev/ata/ata-lowlevel.c')
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 9174823..288fd17 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -516,10 +516,13 @@ ata_generic_reset(device_t dev) if ((mask & 0x01) && (stat0 & ATA_S_BUSY)) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_MASTER)); DELAY(10); + if (ch->flags & ATA_STATUS_IS_LONG) + stat0 = ATA_IDX_INL(ch, ATA_STATUS) & 0xff; + else + stat0 = ATA_IDX_INB(ch, ATA_STATUS); err = ATA_IDX_INB(ch, ATA_ERROR); lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); msb = ATA_IDX_INB(ch, ATA_CYL_MSB); - stat0 = ATA_IDX_INB(ch, ATA_STATUS); if (bootverbose) device_printf(dev, "stat0=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n", @@ -546,10 +549,13 @@ ata_generic_reset(device_t dev) !((mask & 0x01) && (stat0 & ATA_S_BUSY))) { ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_DEV(ATA_SLAVE)); DELAY(10); + if (ch->flags & ATA_STATUS_IS_LONG) + stat1 = ATA_IDX_INL(ch, ATA_STATUS) & 0xff; + else + stat1 = ATA_IDX_INB(ch, ATA_STATUS); err = ATA_IDX_INB(ch, ATA_ERROR); lsb = ATA_IDX_INB(ch, ATA_CYL_LSB); msb = ATA_IDX_INB(ch, ATA_CYL_MSB); - stat1 = ATA_IDX_INB(ch, ATA_STATUS); if (bootverbose) device_printf(dev, "stat1=0x%02x err=0x%02x lsb=0x%02x msb=0x%02x\n", |