PERFORCE change 112570 for review

Matt Jacob mjacob at FreeBSD.org
Fri Jan 5 14:53:16 PST 2007


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

Change 112570 by mjacob at mjexp on 2007/01/05 22:53:08

	(Temp) xpt_rescan code to checkpoint things.

Affected files ...

.. //depot/projects/mjexp/sys/cam/cam_xpt.c#5 edit
.. //depot/projects/mjexp/sys/cam/cam_xpt.h#3 edit
.. //depot/projects/mjexp/sys/dev/isp/isp_freebsd.c#7 edit
.. //depot/projects/mjexp/sys/dev/mpt/mpt_cam.c#8 edit
.. //depot/projects/mjexp/sys/dev/mpt/mpt_cam.h#2 edit

Differences ...

==== //depot/projects/mjexp/sys/cam/cam_xpt.c#5 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/sysctl.h>
+#include <sys/kthread.h>
 
 #ifdef PC98
 #include <pc98/pc98/pc98_machdep.h>	/* geometry translation */
@@ -1412,10 +1413,50 @@
 	return 0;
 }
 
+/* thread to handle bus rescans */
+static TAILQ_HEAD(, ccb_hdr) ccb_scanq;
+static void
+xpt_scanner_thread(void *dummy)
+{
+	mtx_lock(&Giant);
+	for (;;) {
+		union ccb *ccb;
+		tsleep(&ccb_scanq, PRIBIO, "ccb_scanq", 0);
+		while ((ccb = (union ccb *)TAILQ_FIRST(&ccb_scanq)) != NULL) {
+			TAILQ_REMOVE(&ccb_scanq, &ccb->ccb_h, sim_links.tqe);
+			ccb->ccb_h.func_code = XPT_SCAN_BUS;
+			ccb->ccb_h.cbfcnp = xptdone;
+			xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5);
+			cam_periph_runccb(ccb, NULL, 0, 0, NULL);
+			xpt_free_path(ccb->ccb_h.path);
+			xpt_free_ccb(ccb);
+		}
+	}
+}
+
+void
+xpt_rescan(union ccb *ccb)
+{
+	struct ccb_hdr *hdr;
+	GIANT_REQUIRED;
+	/*
+	 * Don't make duplicate entries for the same paths.
+	 */
+	TAILQ_FOREACH(hdr, &ccb_scanq, sim_links.tqe) {
+		if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
+			xpt_print(ccb->ccb_h.path, "rescan already queued\n");
+			xpt_free_path(ccb->ccb_h.path);
+			xpt_free_ccb(ccb);
+			return;
+		}
+	}
+	TAILQ_INSERT_TAIL(&ccb_scanq, &ccb->ccb_h, sim_links.tqe);
+	wakeup(&ccb_scanq);
+}
+
 /* Functions accessed by the peripheral drivers */
 static void
-xpt_init(dummy)
-	void *dummy;
+xpt_init(void *dummy)
 {
 	struct cam_sim *xpt_sim;
 	struct cam_path *path;
@@ -1425,6 +1466,7 @@
 	TAILQ_INIT(&xpt_busses);
 	TAILQ_INIT(&cam_bioq);
 	SLIST_INIT(&ccb_freeq);
+	TAILQ_INIT(&ccb_scanq);
 	STAILQ_INIT(&highpowerq);
 
 	mtx_init(&cam_bioq_lock, "CAM BIOQ lock", NULL, MTX_DEF);
@@ -1490,6 +1532,10 @@
 		       "- failing attach\n");
 	}
 
+	/* fire up rescan thread */
+	if (kthread_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
+		printf("xpt_init: failed to create rescan thread\n");
+	}
 	/* Install our software interrupt handlers */
 	swi_add(NULL, "cambio", camisr, &cam_bioq, SWI_CAMBIO, 0, &cambio_ih);
 }
@@ -4453,8 +4499,7 @@
 	bus = TAILQ_FIRST(&xpt_busses);
 retry:
 	/* Find an unoccupied pathid */
-	while (bus != NULL
-	    && bus->path_id <= pathid) {
+	while (bus != NULL && bus->path_id <= pathid) {
 		if (bus->path_id == pathid)
 			pathid++;
 		bus = TAILQ_NEXT(bus, links);

==== //depot/projects/mjexp/sys/cam/cam_xpt.h#3 (text+ko) ====

@@ -72,6 +72,7 @@
 struct cam_periph	*xpt_path_periph(struct cam_path *path);
 void			xpt_async(u_int32_t async_code, struct cam_path *path,
 				  void *async_arg);
+void			xpt_rescan(union ccb *ccb);
 #endif /* _KERNEL */
 
 #endif /* _CAM_CAM_XPT_H */

==== //depot/projects/mjexp/sys/dev/isp/isp_freebsd.c#7 (text+ko) ====

@@ -42,6 +42,7 @@
 #include <sys/sysctl.h>
 #endif
 #include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
 
 #if !defined(CAM_NEW_TRAN_CODE) && __FreeBSD_version >= 700025
 #define	CAM_NEW_TRAN_CODE	1
@@ -2128,21 +2129,44 @@
 
 
 #if __FreeBSD_version >= 500000  
-#define	isp_make_here(isp, tgt)	isp_announce(isp, tgt, AC_FOUND_DEVICE)
-#define	isp_make_gone(isp, tgt)	isp_announce(isp, tgt, AC_LOST_DEVICE)
-
 /*
- * Support function for Announcement
+ * Support functions for Found/Lost
  */
 static void
-isp_announce(ispsoftc_t *isp, int tgt, int action)
+isp_make_here(ispsoftc_t *isp, int tgt)
+{
+	union ccb *ccb;
+	ISPLOCK_2_CAMLOCK(mpt);
+	/*
+	 * Allocate a CCB, create a wildcard path for this bus,
+	 * and schedule a rescan.
+	 */
+	ccb = xpt_alloc_ccb_nowait();
+	if (ccb == NULL) {
+		isp_prt(isp, ISP_LOGWARN, "unable to alloc CCB for rescan");
+		CAMLOCK_2_ISPLOCK(mpt);
+		return;
+	}
+	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
+	    cam_sim_path(isp->isp_sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+		CAMLOCK_2_ISPLOCK(mpt);
+		isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan");
+		xpt_free_ccb(ccb);
+		return;
+	}
+	xpt_rescan(ccb);
+	CAMLOCK_2_ISPLOCK(mpt);
+}
+
+static void
+isp_make_gone(ispsoftc_t *isp, int tgt)
 {
-	struct cam_path *tmppath;
+	struct cam_path *tp;
 	ISPLOCK_2_CAMLOCK(isp);
-	if (xpt_create_path(&tmppath, NULL, cam_sim_path(isp->isp_sim), tgt,
+	if (xpt_create_path(&tp, NULL, cam_sim_path(isp->isp_sim), tgt,
 	    CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
-		xpt_async(action, tmppath, NULL);
-		xpt_free_path(tmppath);
+		xpt_async(AC_LOST_DEVICE, tp, NULL);
+		xpt_free_path(tp);
 	}
 	CAMLOCK_2_ISPLOCK(isp);
 }

==== //depot/projects/mjexp/sys/dev/mpt/mpt_cam.c#8 (text+ko) ====

@@ -2083,13 +2083,44 @@
 		break;
 
 	case MPI_EVENT_RESCAN:
+	{
+		union ccb *ccb;
+		uint32_t pathid;
 		/*
 		 * In general this means a device has been added to the loop.
 		 */
 		mpt_prt(mpt, "Rescan Port: %d\n", (data0 >> 8) & 0xff);
-/*		xpt_async(AC_FOUND_DEVICE, path, NULL);  */
+		if (mpt->ready == 0) {
+			break;
+		}
+		if (mpt->phydisk_sim) {
+			pathid = cam_sim_path(mpt->phydisk_sim);;
+		} else {
+			pathid = cam_sim_path(mpt->sim);
+		}
+		MPTLOCK_2_CAMLOCK(mpt);
+		/*
+		 * Allocate a CCB, create a wildcard path for this bus,
+		 * and schedule a rescan.
+		 */
+		ccb = xpt_alloc_ccb_nowait();
+		if (ccb == NULL) {
+			mpt_prt(mpt, "unable to alloc CCB for rescan\n");
+			CAMLOCK_2_MPTLOCK(mpt);
+			break;
+		}
+
+		if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, pathid,
+		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+			CAMLOCK_2_MPTLOCK(mpt);
+			mpt_prt(mpt, "unable to create path for rescan\n");
+			xpt_free_ccb(ccb);
+			break;
+		}
+		xpt_rescan(ccb);
+		CAMLOCK_2_MPTLOCK(mpt);
 		break;
-
+	}
 	case MPI_EVENT_LINK_STATUS_CHANGE:
 		mpt_prt(mpt, "Port %d: LinkState: %s\n",
 		    (data1 >> 8) & 0xff,

==== //depot/projects/mjexp/sys/dev/mpt/mpt_cam.h#2 (text+ko) ====

@@ -101,6 +101,8 @@
 #include <cam/cam_ccb.h>
 #include <cam/cam_sim.h>
 #include <cam/cam_xpt.h>
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
 #include <cam/cam_xpt_sim.h>
 #include <cam/cam_debug.h>
 #include <cam/scsi/scsi_all.h>


More information about the p4-projects mailing list