diff options
author | mav <mav@FreeBSD.org> | 2012-11-01 00:09:01 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2012-11-01 00:09:01 +0000 |
commit | 61059593f6e868232cd29036765f4a9609c237c4 (patch) | |
tree | a17a8de22bf93564fc437bf4352ec27b2ae2a610 /sys/dev/ata | |
parent | 95dd9f925421274a4e74528138704b9604243d5b (diff) | |
download | FreeBSD-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.c | 12 |
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); |