aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2012-11-01 00:09:01 +0000
committerAlexander Motin <mav@FreeBSD.org>2012-11-01 00:09:01 +0000
commit76eb28f3503bfe23503f29d2435030146d914355 (patch)
treea17a8de22bf93564fc437bf4352ec27b2ae2a610 /sys/dev
parent8fce93a144ac4b6d9b76604c73843a9626037d55 (diff)
downloadsrc-76eb28f3503bfe23503f29d2435030146d914355.tar.gz
src-76eb28f3503bfe23503f29d2435030146d914355.zip
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`.
Notes
Notes: svn path=/head/; revision=242422
Diffstat (limited to 'sys/dev')
-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 5ad55cd83f56..440db7143425 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);