summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2005-04-14 08:48:45 +0000
committersos <sos@FreeBSD.org>2005-04-14 08:48:45 +0000
commit08ff41b73d58eff36c650fa7d3478e99c9f1a0b8 (patch)
treef3926284fff967f47bcecd9116fd550ae912cf7c
parentff75aa6dbdbb8c40b2cc154d53d356cf63cce1b9 (diff)
downloadFreeBSD-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.h2
-rw-r--r--sys/dev/ata/ata-lowlevel.c27
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 */
OpenPOWER on IntegriCloud