diff options
| author | Sean Bruno <sbruno@FreeBSD.org> | 2013-04-27 08:40:37 +0000 |
|---|---|---|
| committer | Sean Bruno <sbruno@FreeBSD.org> | 2013-04-27 08:40:37 +0000 |
| commit | bdde5705621e7a14945de475aae7893746c4e7b9 (patch) | |
| tree | a7046b6aeaab0e2c2177169602e332f39a777590 /sys/dev/ciss | |
| parent | c46db3529c1612736ec935b80369eec750f2d8e0 (diff) | |
Notes
Diffstat (limited to 'sys/dev/ciss')
| -rw-r--r-- | sys/dev/ciss/ciss.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index d4c3583a9a68e..1dcf88b553396 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -2985,6 +2985,7 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb) case XPT_PATH_INQ: { struct ccb_pathinq *cpi = &ccb->cpi; + int sg_length; debug(1, "XPT_PATH_INQ %d:%d:%d", cam_sim_bus(sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun); @@ -3005,7 +3006,22 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb) cpi->transport_version = 2; cpi->protocol = PROTO_SCSI; cpi->protocol_version = SCSI_REV_2; - cpi->maxio = (min(CISS_MAX_SG_ELEMENTS - 1, sc->ciss_cfg->max_sg_length)) * PAGE_SIZE; + if (sc->ciss_cfg->max_sg_length == 0) { + sg_length = 16; + } else { + /* XXX Fix for ZMR cards that advertise max_sg_length == 32 + * Confusing bit here. max_sg_length is usually a power of 2. We always + * need to subtract 1 to account for partial pages. Then we need to + * align on a valid PAGE_SIZE so we round down to the nearest power of 2. + * Add 1 so we can then subtract it out in the assignment to maxio. + * The reason for all these shenanigans is to create a maxio value that + * creates IO operations to volumes that yield consistent operations + * with good performance. + */ + sg_length = sc->ciss_cfg->max_sg_length - 1; + sg_length = (1 << (fls(sg_length) - 1)) + 1; + } + cpi->maxio = (min(CISS_MAX_SG_ELEMENTS, sg_length) - 1) * PAGE_SIZE; ccb->ccb_h.status = CAM_REQ_CMP; break; } |
