PERFORCE change 97448 for review

Scott Long scottl at FreeBSD.org
Fri May 19 07:12:02 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=97448

Change 97448 by scottl at scottl-x64 on 2006/05/19 07:10:54

	Mark the xpt cdevsw as MPSAFE.  Add appropriate locking to the
	associated device entry points.  xpt_find_bus() turns out to be
	incredibly convenient for making xptioctl work.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#33 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#33 (text+ko) ====

@@ -83,6 +83,9 @@
 SLIST_HEAD(async_list, async_node);
 SLIST_HEAD(periph_list, cam_periph);
 
+#define CAM_SIM_LOCK(sim)	mtx_lock((sim)->mtx);
+#define CAM_SIM_UNLOCK(sim)	mtx_unlock((sim)->mtx);
+
 /*
  * This is the maximum number of high powered commands (e.g. start unit)
  * that can be outstanding at a particular time.
@@ -676,7 +679,7 @@
 
 static struct cdevsw xpt_cdevsw = {
 	.d_version =	D_VERSION,
-	.d_flags =	D_NEEDGIANT,
+	.d_flags =	0,
 	.d_open =	xptopen,
 	.d_close =	xptclose,
 	.d_ioctl =	xptioctl,
@@ -997,7 +1000,9 @@
 	}
 
 	/* Mark ourselves open */
+	mtx_lock(&xsoftc.xpt_lock);
 	xsoftc.flags |= XPT_FLAG_OPEN;
+	mtx_unlock(&xsoftc.xpt_lock);
 	
 	return(0);
 }
@@ -1007,7 +1012,9 @@
 {
 
 	/* Mark ourselves closed */
+	mtx_lock(&xsoftc.xpt_lock);
 	xsoftc.flags &= ~XPT_FLAG_OPEN;
+	mtx_unlock(&xsoftc.xpt_lock);
 
 	return(0);
 }
@@ -1029,9 +1036,16 @@
 	case CAMIOCOMMAND: {
 		union ccb *ccb;
 		union ccb *inccb;
+		struct cam_eb *bus;
 
 		inccb = (union ccb *)addr;
 
+		bus = xpt_find_bus(inccb->ccb_h.path_id);
+		if (bus == NULL) {
+			error = EINVAL;
+			break;
+		}
+
 		switch(inccb->ccb_h.func_code) {
 		case XPT_SCAN_BUS:
 		case XPT_RESET_BUS:
@@ -1047,6 +1061,8 @@
 
 			ccb = xpt_alloc_ccb();
 
+			CAM_SIM_LOCK(bus->sim);
+
 			/*
 			 * Create a path using the bus, target, and lun the
 			 * user passed in.
@@ -1057,6 +1073,7 @@
 					    inccb->ccb_h.target_lun) !=
 					    CAM_REQ_CMP){
 				error = EINVAL;
+				CAM_SIM_UNLOCK(bus->sim);
 				xpt_free_ccb(ccb);
 				break;
 			}
@@ -1066,6 +1083,7 @@
 			xpt_merge_ccb(ccb, inccb);
 			ccb->ccb_h.cbfcnp = xptdone;
 			cam_periph_runccb(ccb, NULL, 0, 0, NULL);
+			CAM_SIM_UNLOCK(bus->sim);
 			bcopy(ccb, inccb, sizeof(union ccb));
 			xpt_free_path(ccb->ccb_h.path);
 			xpt_free_ccb(ccb);
@@ -1079,6 +1097,8 @@
 			 * allocate it on the stack.
 			 */
 
+			CAM_SIM_LOCK(bus->sim);
+
 			/*
 			 * Create a path using the bus, target, and lun the
 			 * user passed in.
@@ -1097,6 +1117,7 @@
 			xpt_merge_ccb(&ccb, inccb);
 			ccb.ccb_h.cbfcnp = xptdone;
 			xpt_action(&ccb);
+			CAM_SIM_UNLOCK(bus->sim);
 			bcopy(&ccb, inccb, sizeof(union ccb));
 			xpt_free_path(ccb.ccb_h.path);
 			break;
@@ -1145,7 +1166,9 @@
 			/*
 			 * This is an immediate CCB, we can send it on directly.
 			 */
+			CAM_SIM_LOCK(bus->sim);
 			xpt_action(inccb);
+			CAM_SIM_UNLOCK(bus->sim);
 
 			/*
 			 * Map the buffers back into user space.
@@ -1452,6 +1475,7 @@
 
 	xpt_sim = (struct cam_sim *)arg;
 	xpt_sim->softc = periph;
+	xpt_periph = periph;
 	periph->softc = NULL;
 
 	return(CAM_REQ_CMP);


More information about the p4-projects mailing list