PERFORCE change 100110 for review

Scott Long scottl at FreeBSD.org
Tue Jun 27 04:23:58 UTC 2006


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

Change 100110 by scottl at scottl-wv1u on 2006/06/27 04:23:02

	Anonymous ccbs allocated through xpt_alloc_ccb() were not getting
	their callout and callout_handle objects initialized.  Make these
	calls slightly less anonymous by passing in the SIM object so that
	the MPSAFE status can be determined for callout_init.
	
	Drop some locks into the bus scan path to satisfy the locking
	protocol.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#39 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt_periph.h#8 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_low.c#8 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_pass.c#11 edit

Differences ...

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

@@ -1062,7 +1062,7 @@
 		case XPT_ENG_INQ:
 		case XPT_SCAN_LUN:
 
-			ccb = xpt_alloc_ccb();
+			ccb = xpt_alloc_ccb(bus->sim);
 
 			CAM_SIM_LOCK(bus->sim);
 
@@ -4405,7 +4405,7 @@
 	struct ccb_pathinq cpi;
 	int s;
 
-	GIANT_REQUIRED;
+	mtx_assert(sim->mtx, MA_OWNED);
 
 	sim->bus_id = bus;
 	new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
@@ -4971,20 +4971,26 @@
 }
 
 union ccb *
-xpt_alloc_ccb()
+xpt_alloc_ccb(struct cam_sim *sim)
 {
 	union ccb *new_ccb;
 
 	new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_WAITOK);
+	callout_handle_init(&new_ccb->ccb_h.timeout_ch);
+	callout_init(&new_ccb->ccb_h.callout,
+	    (sim->flags & CAM_SIM_MPSAFE) ? 1 : 0);
 	return (new_ccb);
 }
 
 union ccb *
-xpt_alloc_ccb_nowait()
+xpt_alloc_ccb_nowait(struct cam_sim *sim)
 {
 	union ccb *new_ccb;
 
 	new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_NOWAIT);
+	callout_handle_init(&new_ccb->ccb_h.timeout_ch);
+	callout_init(&new_ccb->ccb_h.callout,
+	    (sim->flags & CAM_SIM_MPSAFE) ? 1 : 0);
 	return (new_ccb);
 }
 
@@ -5015,12 +5021,11 @@
 	s = splsoftcam();
 	sim = device->sim;
 	if ((new_ccb = (union ccb *)SLIST_FIRST(&sim->ccb_freeq)) == NULL) {
-		new_ccb = xpt_alloc_ccb_nowait();
+		new_ccb = xpt_alloc_ccb_nowait(sim);
                 if (new_ccb == NULL) {
 			splx(s);
 			return (NULL);
 		}
-		callout_handle_init(&new_ccb->ccb_h.timeout_ch);
 		SLIST_INSERT_HEAD(&sim->ccb_freeq, &new_ccb->ccb_h,
 				  xpt_links.sle);
 		sim->ccb_count++;
@@ -5344,7 +5349,7 @@
 		u_int	initiator_id;
 
 		/* Find out the characteristics of the bus */
-		work_ccb = xpt_alloc_ccb();
+		work_ccb = xpt_alloc_ccb_nowait(periph->sim);
 		xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
 			      request_ccb->ccb_h.pinfo.priority);
 		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
@@ -5369,7 +5374,7 @@
 
 		/* Save some state for use while we probe for devices */
 		scan_info = (xpt_scan_bus_info *)
-		    malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_WAITOK);
+		    malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_NOWAIT);
 		scan_info->request_ccb = request_ccb;
 		scan_info->cpi = &work_ccb->cpi;
 
@@ -5409,7 +5414,7 @@
 				xpt_done(request_ccb);
 				break;
 			}
-			work_ccb = xpt_alloc_ccb();
+			work_ccb = xpt_alloc_ccb_nowait(periph->sim);
 			xpt_setup_ccb(&work_ccb->ccb_h, path,
 				      request_ccb->ccb_h.pinfo.priority);
 			work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
@@ -6932,6 +6937,7 @@
 static int
 xptconfigbuscountfunc(struct cam_eb *bus, void *arg)
 {
+	mtx_lock(bus->sim->mtx);
 	if (bus->path_id != CAM_XPT_PATH_ID) {
 		struct cam_path path;
 		struct ccb_pathinq cpi;
@@ -6950,6 +6956,7 @@
 			busses_to_reset++;
 		xpt_release_path(&path);
 	}
+	mtx_unlock(bus->sim->mtx);
 
 	return(1);
 }
@@ -6960,11 +6967,12 @@
 	struct	cam_path *path;
 	union	ccb *work_ccb;
 
+	mtx_lock(bus->sim->mtx);
 	if (bus->path_id != CAM_XPT_PATH_ID) {
 		cam_status status;
 		int can_negotiate;
 
-		work_ccb = xpt_alloc_ccb();
+		work_ccb = xpt_alloc_ccb_nowait(bus->sim);
 		if ((status = xpt_create_path(&path, xpt_periph, bus->path_id,
 					      CAM_TARGET_WILDCARD,
 					      CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){
@@ -6974,6 +6982,7 @@
 			xpt_free_ccb(work_ccb);
 			busses_to_config--;
 			xpt_finishconfig(xpt_periph, NULL);
+			mtx_unlock(bus->sim->mtx);
 			return(0);
 		}
 		xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1);
@@ -6984,6 +6993,7 @@
 			       "with status %d\n", bus->path_id,
 			       work_ccb->ccb_h.status);
 			xpt_finishconfig(xpt_periph, work_ccb);
+			mtx_unlock(bus->sim->mtx);
 			return(1);
 		}
 
@@ -7005,6 +7015,7 @@
 		}
 	}
 
+	mtx_unlock(bus->sim->mtx);
 	return(1);
 }
 

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt_periph.h#8 (text+ko) ====

@@ -38,8 +38,8 @@
 /* Functions accessed by the peripheral drivers */
 #ifdef _KERNEL
 void		xpt_polled_action(union ccb *ccb);
-union ccb	*xpt_alloc_ccb(void);
-union ccb	*xpt_alloc_ccb_nowait(void);
+union ccb	*xpt_alloc_ccb(struct cam_sim *sim);
+union ccb	*xpt_alloc_ccb_nowait(struct cam_sim *sim);
 void		xpt_free_ccb(union ccb *free_ccb);
 void		xpt_release_ccb(union ccb *released_ccb);
 void		xpt_schedule(struct cam_periph *perph, u_int32_t new_priority);

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_low.c#8 (text+ko) ====

@@ -966,7 +966,7 @@
 	struct scsi_low_softc *slp;
 {
   	struct cam_path *path;
-	union ccb *ccb = xpt_alloc_ccb();
+	union ccb *ccb = xpt_alloc_ccb(path->sim);
 	cam_status status;
 
 	bzero(ccb, sizeof(union ccb));

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_pass.c#11 (text+ko) ====

@@ -503,7 +503,7 @@
 						inccb->ccb_h.pinfo.priority);
 			ccb_malloced = 0;
 		} else {
-			ccb = xpt_alloc_ccb();
+			ccb = xpt_alloc_ccb(periph->sim);
 
 			if (ccb != NULL)
 				xpt_setup_ccb(&ccb->ccb_h, periph->path,


More information about the p4-projects mailing list