diff options
author | mav <mav@FreeBSD.org> | 2015-09-30 13:31:37 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2015-09-30 13:31:37 +0000 |
commit | efed61f85c8d42437b2f71f0e78164039dbf876b (patch) | |
tree | f93ec68cb45de7a3c0f34e6d6eb086a29122c036 | |
parent | 0ed33a9921d09f4a4c791d98ffe797a71936e42a (diff) | |
download | FreeBSD-src-efed61f85c8d42437b2f71f0e78164039dbf876b.zip FreeBSD-src-efed61f85c8d42437b2f71f0e78164039dbf876b.tar.gz |
Make pass, sg and targ drivers respect HBA's maxio.
Previous limitation of 64K (DFLTPHYS) is quite annoying.
-rw-r--r-- | sys/cam/cam_compat.c | 2 | ||||
-rw-r--r-- | sys/cam/cam_periph.c | 9 | ||||
-rw-r--r-- | sys/cam/cam_periph.h | 3 | ||||
-rw-r--r-- | sys/cam/cam_xpt.c | 2 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pass.c | 10 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_sg.c | 10 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_target.c | 9 |
7 files changed, 36 insertions, 9 deletions
diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c index bcce814..b8e57bb 100644 --- a/sys/cam/cam_compat.c +++ b/sys/cam/cam_compat.c @@ -300,7 +300,7 @@ cam_compat_translate_dev_match_0x18(union ccb *ccb) /* Remap the CCB into kernel address space */ bzero(&mapinfo, sizeof(mapinfo)); - cam_periph_mapmem(ccb, &mapinfo); + cam_periph_mapmem(ccb, &mapinfo, MAXPHYS); dm = ccb->cdm.matches; /* Translate in-place: old fields are smaller */ diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 956e5d0..91cb45d 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -716,16 +716,19 @@ camperiphfree(struct cam_periph *periph) * buffers to map stuff in and out, we're limited to the buffer size. */ int -cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) +cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo, + u_int maxmap) { int numbufs, i, j; int flags[CAM_PERIPH_MAXMAPS]; u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS]; u_int32_t lengths[CAM_PERIPH_MAXMAPS]; u_int32_t dirs[CAM_PERIPH_MAXMAPS]; - /* Some controllers may not be able to handle more data. */ - size_t maxmap = DFLTPHYS; + if (maxmap == 0) + maxmap = DFLTPHYS; /* traditional default */ + else if (maxmap > MAXPHYS) + maxmap = MAXPHYS; /* for safety */ switch(ccb->ccb_h.func_code) { case XPT_DEV_MATCH: if (ccb->cdm.match_buf_len == 0) { diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index ebcf1a4..e28d5b1 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -160,7 +160,8 @@ int cam_periph_hold(struct cam_periph *periph, int priority); void cam_periph_unhold(struct cam_periph *periph); void cam_periph_invalidate(struct cam_periph *periph); int cam_periph_mapmem(union ccb *ccb, - struct cam_periph_map_info *mapinfo); + struct cam_periph_map_info *mapinfo, + u_int maxmap); void cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo); union ccb *cam_periph_getccb(struct cam_periph *periph, diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index ad55373..4ce48a3 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -536,7 +536,7 @@ xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread * * Map the pattern and match buffers into kernel * virtual address space. */ - error = cam_periph_mapmem(inccb, &mapinfo); + error = cam_periph_mapmem(inccb, &mapinfo, MAXPHYS); if (error) { inccb->ccb_h.path = old_path; diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 584b6b3..055291b 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -77,6 +77,7 @@ struct pass_softc { u_int8_t pd_type; union ccb saved_ccb; int open_count; + u_int maxio; struct devstat *device_stats; struct cdev *dev; struct cdev *alias_dev; @@ -366,6 +367,13 @@ passregister(struct cam_periph *periph, void *arg) cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ + /* * We pass in 0 for a blocksize, since we don't * know what the blocksize of this device is, if @@ -657,7 +665,7 @@ passsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb) * Dropping it here is reasonably safe. */ cam_periph_unlock(periph); - error = cam_periph_mapmem(ccb, &mapinfo); + error = cam_periph_mapmem(ccb, &mapinfo, softc->maxio); cam_periph_lock(periph); /* diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c index 3e80ac3..3e13003 100644 --- a/sys/cam/scsi/scsi_sg.c +++ b/sys/cam/scsi/scsi_sg.c @@ -99,6 +99,7 @@ struct sg_softc { sg_state state; sg_flags flags; int open_count; + u_int maxio; struct devstat *device_stats; TAILQ_HEAD(, sg_rdwr) rdwr_done; struct cdev *dev; @@ -325,6 +326,13 @@ sgregister(struct cam_periph *periph, void *arg) cpi.ccb_h.func_code = XPT_PATH_INQ; xpt_action((union ccb *)&cpi); + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ + /* * We pass in 0 for all blocksize, since we don't know what the * blocksize of the device is, if it even has a blocksize. @@ -894,7 +902,7 @@ sgsendccb(struct cam_periph *periph, union ccb *ccb) * need for additional checks. */ cam_periph_unlock(periph); - error = cam_periph_mapmem(ccb, &mapinfo); + error = cam_periph_mapmem(ccb, &mapinfo, softc->maxio); cam_periph_lock(periph); if (error) return (error); diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c index 42dc152..f2504ab 100644 --- a/sys/cam/scsi/scsi_target.c +++ b/sys/cam/scsi/scsi_target.c @@ -94,6 +94,7 @@ struct targ_softc { struct cam_periph *periph; struct cam_path *path; targ_state state; + u_int maxio; struct selinfo read_select; struct devstat device_stats; }; @@ -403,6 +404,12 @@ targenable(struct targ_softc *softc, struct cam_path *path, int grp6_len, status = CAM_FUNC_NOTAVAIL; goto enable_fail; } + if (cpi.maxio == 0) + softc->maxio = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->maxio = MAXPHYS; /* for safety */ + else + softc->maxio = cpi.maxio; /* real value */ /* Destroy any periph on our path if it is disabled */ periph = cam_periph_find(path, "targ"); @@ -725,7 +732,7 @@ targsendccb(struct targ_softc *softc, union ccb *ccb, if ((ccb_h->func_code == XPT_CONT_TARGET_IO) || (ccb_h->func_code == XPT_DEV_MATCH)) { - error = cam_periph_mapmem(ccb, mapinfo); + error = cam_periph_mapmem(ccb, mapinfo, softc->maxio); /* * cam_periph_mapmem returned an error, we can't continue. |