summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/ata-lowlevel.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2010-09-09 13:17:30 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2010-09-09 13:17:30 +0000
commit258c3c91359faddd228bdcc316478d993dbd6aa3 (patch)
tree8d288529801cee47b96deafb5f6690a015ed9f45 /sys/dev/ata/ata-lowlevel.c
parentbf61bd49f55cf9af9d54bf6c18a64e95eec4b29c (diff)
downloadFreeBSD-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.c10
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",
OpenPOWER on IntegriCloud