aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2012-10-26 20:03:08 +0000
committerAlexander Motin <mav@FreeBSD.org>2012-10-26 20:03:08 +0000
commit23d9e39c1a3607fa92ea6da3e998ee0161771a62 (patch)
tree60b6260eac3a5401d19d36d10bfe65999c97ddc5 /sys
parentfdf3d9543a91d5bfbf2415d87f9f7817b9e95ee1 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.c2
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-lowlevel.c12
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c6
-rw-r--r--sys/dev/ata/chipsets/ata-siliconimage.c6
5 files changed, 21 insertions, 6 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index e0617440566c..5ad55cd83f56 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 7154d56055f0..3a6710ccaa7d 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 dd9cd5f4fe4b..de3060369d7b 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 23b226d625c2..8f19ecd5b714 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 16af524cd381..270a0d412e8e 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);