diff options
author | sos <sos@FreeBSD.org> | 2005-04-14 08:48:45 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2005-04-14 08:48:45 +0000 |
commit | 08ff41b73d58eff36c650fa7d3478e99c9f1a0b8 (patch) | |
tree | f3926284fff967f47bcecd9116fd550ae912cf7c | |
parent | ff75aa6dbdbb8c40b2cc154d53d356cf63cce1b9 (diff) | |
download | FreeBSD-src-08ff41b73d58eff36c650fa7d3478e99c9f1a0b8.zip FreeBSD-src-08ff41b73d58eff36c650fa7d3478e99c9f1a0b8.tar.gz |
Read back the real taskfile register values when in 48BIT mode.
-rw-r--r-- | sys/dev/ata/ata-all.h | 2 | ||||
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 27 |
2 files changed, 23 insertions, 6 deletions
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index c749d74..381c444 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -258,7 +258,7 @@ struct ata_request { union { struct { u_int8_t command; /* command reg */ - u_int8_t feature; /* feature reg */ + u_int16_t feature; /* feature reg */ u_int16_t count; /* count reg */ u_int64_t lba; /* lba reg */ } ata; diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index ba322ee..717184d 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -391,11 +391,28 @@ ata_end_transaction(struct ata_request *request) /* on control commands read back registers to the request struct */ if (request->flags & ATA_R_CONTROL) { - request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); - request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | - (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | - (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) | - ((ATA_IDX_INB(ch, ATA_DRIVE) & 0x0f) << 24); + if (ch->flags & ATA_48BIT_ACTIVE) { + ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT | ATA_A_HOB); + request->u.ata.count = (ATA_IDX_INB(ch, ATA_COUNT) << 8); + request->u.ata.lba = + ((u_int64_t)(ATA_IDX_INB(ch, ATA_SECTOR)) << 24) | + ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_LSB)) << 32) | + ((u_int64_t)(ATA_IDX_INB(ch, ATA_CYL_MSB)) << 40); + + ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_4BIT); + request->u.ata.count |= ATA_IDX_INB(ch, ATA_COUNT); + request->u.ata.lba |= + (ATA_IDX_INB(ch, ATA_SECTOR) | + (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | + (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16)); + } + else { + request->u.ata.count = ATA_IDX_INB(ch, ATA_COUNT); + request->u.ata.lba = ATA_IDX_INB(ch, ATA_SECTOR) | + (ATA_IDX_INB(ch, ATA_CYL_LSB) << 8) | + (ATA_IDX_INB(ch, ATA_CYL_MSB) << 16) | + ((ATA_IDX_INB(ch, ATA_DRIVE) & 0xf) << 24); + } } /* if we got an error we are done with the HW */ |