diff options
author | mav <mav@FreeBSD.org> | 2012-10-26 20:03:08 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2012-10-26 20:03:08 +0000 |
commit | cca98d66c9602102fa43b858538e520d0c3c1f06 (patch) | |
tree | 60b6260eac3a5401d19d36d10bfe65999c97ddc5 /sys/dev/ata | |
parent | cdbf140d9201a4adc8cbbca3025d62118b5a7475 (diff) | |
download | FreeBSD-src-cca98d66c9602102fa43b858538e520d0c3c1f06.zip FreeBSD-src-cca98d66c9602102fa43b858538e520d0c3c1f06.tar.gz |
Implement CAM_ATAIO_NEEDRESULT (fetching full set of result registers) for
ata(4) driver in ATA_CAM mode. That slighty improves error reporting and
also should fix `smartctl -l scterc /dev/adaX` operation.
MFC after: 3 weeks
Diffstat (limited to 'sys/dev/ata')
-rw-r--r-- | sys/dev/ata/ata-all.c | 2 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 1 | ||||
-rw-r--r-- | sys/dev/ata/ata-lowlevel.c | 12 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-ahci.c | 6 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-siliconimage.c | 6 |
5 files changed, 21 insertions, 6 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index e061744..5ad55cd 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -1492,6 +1492,8 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb) request->u.ata.lba |= ((uint64_t)ccb->ataio.cmd.lba_high << 16) | ((uint64_t)ccb->ataio.cmd.lba_mid << 8) | (uint64_t)ccb->ataio.cmd.lba_low; + if (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT) + request->flags |= ATA_R_NEEDRESULT; if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE && ccb->ataio.cmd.flags & CAM_ATAIO_DMA) request->flags |= ATA_R_DMA; diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index 7154d56..3a6710c 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -397,6 +397,7 @@ struct ata_request { #define ATA_R_REQUEUE 0x00000400 #define ATA_R_THREAD 0x00000800 #define ATA_R_DIRECT 0x00001000 +#define ATA_R_NEEDRESULT 0x00002000 #define ATA_R_ATAPI16 0x00010000 #define ATA_R_ATAPI_INTR 0x00020000 diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index dd9cd5f..de30603 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -116,6 +116,7 @@ ata_begin_transaction(struct ata_request *request) } while (request->status & ATA_S_BUSY && timeout--); if (request->status & ATA_S_ERROR) request->error = ATA_IDX_INB(ch, ATA_ERROR); + ch->hw.tf_read(request); goto begin_finished; } @@ -253,8 +254,9 @@ ata_end_transaction(struct ata_request *request) if (request->flags & ATA_R_TIMEOUT) goto end_finished; - /* on control commands read back registers to the request struct */ - if (request->flags & ATA_R_CONTROL) { + /* Read back registers to the request struct. */ + if ((request->status & ATA_S_ERROR) || + (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) { ch->hw.tf_read(request); } @@ -332,6 +334,12 @@ ata_end_transaction(struct ata_request *request) else if (!(request->flags & ATA_R_TIMEOUT)) request->donecount = request->bytecount; + /* Read back registers to the request struct. */ + if ((request->status & ATA_S_ERROR) || + (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT))) { + ch->hw.tf_read(request); + } + /* release SG list etc */ ch->dma.unload(request); diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c index 23b226d..8f19ecd 100644 --- a/sys/dev/ata/chipsets/ata-ahci.c +++ b/sys/dev/ata/chipsets/ata-ahci.c @@ -555,8 +555,10 @@ ata_ahci_end_transaction(struct ata_request *request) if (request->status & ATA_S_ERROR) request->error = tf_data >> 8; - /* on control commands read back registers to the request struct */ - if (request->flags & ATA_R_CONTROL) { + /* Read back registers to the request struct. */ + if ((request->flags & ATA_R_ATAPI) == 0 && + ((request->status & ATA_S_ERROR) || + (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT)))) { u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40; request->u.ata.count = fis[12] | ((u_int16_t)fis[13] << 8); diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index 16af524..270a0d4 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -658,8 +658,10 @@ ata_siiprb_end_transaction(struct ata_request *request) } } - /* on control commands read back registers to the request struct */ - if (request->flags & ATA_R_CONTROL) { + /* Read back registers to the request struct. */ + if ((request->flags & ATA_R_ATAPI) == 0 && + ((request->status & ATA_S_ERROR) || + (request->flags & (ATA_R_CONTROL | ATA_R_NEEDRESULT)))) { request->u.ata.count = prb->fis[12] | ((u_int16_t)prb->fis[13] << 8); request->u.ata.lba = prb->fis[4] | ((u_int64_t)prb->fis[5] << 8) | ((u_int64_t)prb->fis[6] << 16); |