From a6e97ccf7008e575b90a62f3abadd34ec1713d58 Mon Sep 17 00:00:00 2001 From: Søren Schmidt Date: Thu, 14 Apr 2005 08:48:45 +0000 Subject: Read back the real taskfile register values when in 48BIT mode. --- sys/dev/ata/ata-all.h | 2 +- sys/dev/ata/ata-lowlevel.c | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'sys/dev/ata') diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index c749d74e52e7..381c44417f32 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 ba322ee48fca..717184d625bf 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 */ -- cgit v1.3