Make pass, sg and targ drivers respect HBA's maxio.
Previous limitation of 64K (DFLTPHYS) is quite annoying.
This commit is contained in:
parent
2aea45f0d5
commit
de2393124c
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user