svn commit: r288420 - in head/sys/cam: . scsi

Alexander Motin mav at FreeBSD.org
Wed Sep 30 13:31:40 UTC 2015


Author: mav
Date: Wed Sep 30 13:31:37 2015
New Revision: 288420
URL: https://svnweb.freebsd.org/changeset/base/288420

Log:
  Make pass, sg and targ drivers respect HBA's maxio.
  
  Previous limitation of 64K (DFLTPHYS) is quite annoying.

Modified:
  head/sys/cam/cam_compat.c
  head/sys/cam/cam_periph.c
  head/sys/cam/cam_periph.h
  head/sys/cam/cam_xpt.c
  head/sys/cam/scsi/scsi_pass.c
  head/sys/cam/scsi/scsi_sg.c
  head/sys/cam/scsi/scsi_target.c

Modified: head/sys/cam/cam_compat.c
==============================================================================
--- head/sys/cam/cam_compat.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/cam_compat.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -300,7 +300,7 @@ cam_compat_translate_dev_match_0x18(unio
 
 	/* 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 */

Modified: head/sys/cam/cam_periph.c
==============================================================================
--- head/sys/cam/cam_periph.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/cam_periph.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -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) {

Modified: head/sys/cam/cam_periph.h
==============================================================================
--- head/sys/cam/cam_periph.h	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/cam_periph.h	Wed Sep 30 13:31:37 2015	(r288420)
@@ -160,7 +160,8 @@ int		cam_periph_hold(struct cam_periph *
 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,

Modified: head/sys/cam/cam_xpt.c
==============================================================================
--- head/sys/cam/cam_xpt.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/cam_xpt.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -536,7 +536,7 @@ xptdoioctl(struct cdev *dev, u_long cmd,
 			 * 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;

Modified: head/sys/cam/scsi/scsi_pass.c
==============================================================================
--- head/sys/cam/scsi/scsi_pass.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/scsi/scsi_pass.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -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, 
 	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, u
 		 * 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);
 
 		/*

Modified: head/sys/cam/scsi/scsi_sg.c
==============================================================================
--- head/sys/cam/scsi/scsi_sg.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/scsi/scsi_sg.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -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, vo
 	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, uni
 	 * 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);

Modified: head/sys/cam/scsi/scsi_target.c
==============================================================================
--- head/sys/cam/scsi/scsi_target.c	Wed Sep 30 12:40:51 2015	(r288419)
+++ head/sys/cam/scsi/scsi_target.c	Wed Sep 30 13:31:37 2015	(r288420)
@@ -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, str
 		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, un
 	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.


More information about the svn-src-all mailing list