summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-11-01 00:09:01 +0000
committermav <mav@FreeBSD.org>2012-11-01 00:09:01 +0000
commit61059593f6e868232cd29036765f4a9609c237c4 (patch)
treea17a8de22bf93564fc437bf4352ec27b2ae2a610 /sys/dev/ata
parent95dd9f925421274a4e74528138704b9604243d5b (diff)
downloadFreeBSD-src-61059593f6e868232cd29036765f4a9609c237c4.zip
FreeBSD-src-61059593f6e868232cd29036765f4a9609c237c4.tar.gz
Only four specific ATA PIO commands transfer several sectors per DRQ block
(interrupt). All other ATA PIO commands transfer one sector or 512 bytes at one time. Hardcode these exceptions in ata(4) with ATA_CAM option. This fixes timeout of READ LOG EXT command used by `smartctl -x /dev/adaX`.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 5ad55cd..440db71 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -1501,6 +1501,14 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb)
request->flags |= ATA_R_READ;
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
request->flags |= ATA_R_WRITE;
+ if (ccb->ataio.cmd.command == ATA_READ_MUL ||
+ ccb->ataio.cmd.command == ATA_READ_MUL48 ||
+ ccb->ataio.cmd.command == ATA_WRITE_MUL ||
+ ccb->ataio.cmd.command == ATA_WRITE_MUL48) {
+ request->transfersize = min(request->bytecount,
+ ch->curr[ccb->ccb_h.target_id].bytecount);
+ } else
+ request->transfersize = min(request->bytecount, 512);
} else {
request->data = ccb->csio.data_ptr;
request->bytecount = ccb->csio.dxfer_len;
@@ -1517,9 +1525,9 @@ ata_cam_begin_transaction(device_t dev, union ccb *ccb)
request->flags |= ATA_R_READ;
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
request->flags |= ATA_R_WRITE;
+ request->transfersize = min(request->bytecount,
+ ch->curr[ccb->ccb_h.target_id].bytecount);
}
- request->transfersize = min(request->bytecount,
- ch->curr[ccb->ccb_h.target_id].bytecount);
request->retries = 0;
request->timeout = (ccb->ccb_h.timeout + 999) / 1000;
callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED);
OpenPOWER on IntegriCloud