PERFORCE change 109456 for review

Matt Jacob mjacob at FreeBSD.org
Tue Nov 7 18:04:09 UTC 2006


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

Change 109456 by mjacob at newisp on 2006/11/07 18:03:41

	Move code that cleans up after dead or new devices into
	the outer layer where policy can be applied.

Affected files ...

.. //depot/projects/newisp/dev/isp/isp.c#27 edit
.. //depot/projects/newisp/dev/isp/isp_freebsd.c#19 edit
.. //depot/projects/newisp/dev/isp/ispvar.h#11 edit

Differences ...

==== //depot/projects/newisp/dev/isp/isp.c#27 (text+ko) ====

@@ -2757,11 +2757,10 @@
 		switch (lp->state) {
 		case FC_PORTDB_STATE_PROBATIONAL:
 		case FC_PORTDB_STATE_DEAD:
+			/*
+			 * It's up to the outer layers to clear isp_ini_map.
+			 */
 			isp_async(isp, ISPASYNC_DEV_GONE, lp);
-			if (lp->ini_map_idx) {
-				fcp->isp_ini_map[lp->ini_map_idx-1] = 0;
-				lp->ini_map_idx = 0;
-			}
 			lp->state = FC_PORTDB_STATE_NIL;
 			if (lp->autologin == 0) {
 				if (IS_24XX(isp)) {
@@ -2790,53 +2789,40 @@
 			 */
 			lp->portid = lp->new_portid;
 			lp->roles = lp->new_roles;
+			/*
+			 * It's up to the outer layers to assign a virtual
+			 * target id in isp_ini_map (if any).
+			 */
+			isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
 			lp->state = FC_PORTDB_STATE_VALID;
-			if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
-			    (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
-				int i, t = dbidx;
-				for (i = 0; i < MAX_FC_TARG; i++) {
-					if (i < FL_ID || i > SNS_ID) {
-						if (fcp->isp_ini_map[t] == 0) {
-							break;
-						}
-					}
-					if (++t == MAX_FC_TARG) {
-						t = 0;
-					}
-				}
-				if (i < MAX_FC_TARG) {
-					fcp->isp_ini_map[t] = dbidx + 1;
-					lp->ini_map_idx = t + 1;
-				} else {
-					isp_prt(isp, ISP_LOGWARN,
-					    "out of target ids");
-				}
-			}
-			isp_async(isp, ISPASYNC_DEV_ARRIVED, lp);
 			lp->new_roles = 0;
 			lp->new_portid = 0;
 			break;
 		case FC_PORTDB_STATE_CHANGED:
+			/*
+			 * For now, just have a policy of accepting 'changed'
+			 * devices.
+			 */
 			lp->portid = lp->new_portid;
 			lp->roles = lp->new_roles;
-			lp->state = FC_PORTDB_STATE_VALID;
 			if (lp->ini_map_idx) {
 				int t = lp->ini_map_idx - 1;
 				fcp->isp_ini_map[t] = dbidx + 1;
 			}
 			isp_async(isp, ISPASYNC_DEV_CHANGED, lp);
+			lp->state = FC_PORTDB_STATE_VALID;
 			lp->new_roles = 0;
 			lp->new_portid = 0;
 			break;
 		case FC_PORTDB_STATE_PENDING_VALID:
 			lp->portid = lp->new_portid;
 			lp->roles = lp->new_roles;
-			lp->state = FC_PORTDB_STATE_VALID;
 			if (lp->ini_map_idx) {
 				int t = lp->ini_map_idx - 1;
 				fcp->isp_ini_map[t] = dbidx + 1;
 			}
 			isp_async(isp, ISPASYNC_DEV_STAYED, lp);
+			lp->state = FC_PORTDB_STATE_VALID;
 			if (dbidx != FL_ID) {
 				lp->new_roles = 0;
 				lp->new_portid = 0;
@@ -3950,7 +3936,7 @@
 	ispreq_t *reqp, *qep;
 	void *cdbp;
 	uint16_t *tptr;
-	int target, i;
+	int target, i, hdlidx = 0;
 
 	XS_INITERR(xs);
 	isp = XS_ISP(xs);
@@ -4006,14 +3992,14 @@
 			return (CMD_COMPLETE);
 		}
 
-		i = fcp->isp_ini_map[XS_TGT(xs)];
+		hdlidx = fcp->isp_ini_map[XS_TGT(xs)] - 1;
 		isp_prt(isp, ISP_LOGDEBUG1, "XS_TGT(xs)=%d- handle value %d",
-		    XS_TGT(xs), i);
-		if (i < 1 || i >= MAX_FC_TARG) {
+		    XS_TGT(xs), hdlidx);
+		if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
 			XS_SETERR(xs, HBA_SELTIMEOUT);
 			return (CMD_COMPLETE);
 		}
-		target = fcp->portdb[i - 1].handle;
+		target = fcp->portdb[hdlidx].handle;
 	}
 
 	/*
@@ -4141,9 +4127,7 @@
 	} else if (IS_24XX(isp)) {
 		fcportdb_t *lp;
 
-		i = FCPARAM(isp)->isp_ini_map[XS_TGT(xs)] - 1;
-		lp = &FCPARAM(isp)->portdb[i];
-
+		lp = &FCPARAM(isp)->portdb[hdlidx];
 		((ispreqt7_t *)reqp)->req_nphdl = target;
 		((ispreqt7_t *)reqp)->req_tidlo = lp->portid;
 		((ispreqt7_t *)reqp)->req_tidhi = lp->portid >> 16;

==== //depot/projects/newisp/dev/isp/isp_freebsd.c#19 (text+ko) ====

@@ -49,6 +49,7 @@
 int isp_fabric_hysteresis = 5;
 int isp_loop_down_limit = 300;	/* default loop down limit */
 int isp_quickboot_time = 5;	/* don't wait more than N secs for loop up */
+int isp_lost_device_time = 30;	/* grace time before reporting device lost */
 
 static d_ioctl_t ispioctl;
 static void isp_intr_enable(void *);
@@ -2918,7 +2919,26 @@
 		break;
 	case ISPASYNC_DEV_ARRIVED:
 		lp = arg;
+		if ((isp->isp_role & ISP_ROLE_INITIATOR) &&
+		    (lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT))) {
+			int dbidx = lp - FCPARAM(isp)->portdb;
+			int i;
 
+			for (i = 0; i < MAX_FC_TARG; i++) {
+				if (i >= FL_ID || i <=  SNS_ID) {
+					continue;
+				}
+				if (FCPARAM(isp)->isp_ini_map[i] == 0) {
+					break;
+				}
+			}
+			if (i < MAX_FC_TARG) {
+				FCPARAM(isp)->isp_ini_map[i] = dbidx + 1;
+				lp->ini_map_idx = i + 1;
+			} else {
+				isp_prt(isp, ISP_LOGWARN, "out of target ids");
+			}
+		}
 		if (lp->ini_map_idx) {
 			tgt = lp->ini_map_idx - 1;
 			isp_prt(isp, ISP_LOGCONFIG, prom2,
@@ -2995,7 +3015,12 @@
 	case ISPASYNC_DEV_GONE:
 		lp = arg;
 		if (lp->ini_map_idx) {
+/*
+ * XXX: HERE IS WHERE WE'D START A TIMER
+ */
 			tgt = lp->ini_map_idx - 1;
+			FCPARAM(isp)->isp_ini_map[tgt] = 0;
+			lp->ini_map_idx = 0;
 			isp_prt(isp, ISP_LOGCONFIG, prom2,
 			    lp->portid, lp->handle,
 		            roles[lp->roles & 0x3], "departed from", tgt,

==== //depot/projects/newisp/dev/isp/ispvar.h#11 (text+ko) ====

@@ -75,7 +75,7 @@
  * Overall parameters
  */
 #define	MAX_TARGETS		16
-#define	MAX_FC_TARG		256
+#define	MAX_FC_TARG		512
 #define	ISP_MAX_TARGETS(isp)	(IS_FC(isp)? MAX_FC_TARG : MAX_TARGETS)
 #define	ISP_MAX_LUNS(isp)	(isp)->isp_maxluns
 
@@ -303,7 +303,26 @@
  *    value.
  */
 typedef struct {
+	/*
+	 * This is the handle that the firmware needs in order for us to
+	 * send commands to the device. For pre-24XX cards, this would be
+	 * the 'loopid'.
+	 */
 	uint16_t	handle;
+	/*
+	 * The ini_map_idx, if nonzero, is the system virtual target ID (+1)
+	 * as a cross-reference with the isp_ini_map.
+	 *
+	 * A device is 'autologin' if the firmware automatically logs into
+	 * it (re-logins as needed). Basically, local private loop devices.
+	 *
+	 * The state is the current state of thsi entry.
+	 *
+	 * Role is Initiator, Target, Both
+	 *
+	 * Portid is obvious, as or node && port WWNs. The new_role and
+	 * new_portid is for when we are pending a change.
+	 */
 	uint16_t	ini_map_idx	: 12,
 			autologin	: 1,	/* F/W does PLOGI/PLOGO */
 			state		: 3;
@@ -357,8 +376,21 @@
 	uint16_t		isp_maxfrmlen;
 	uint64_t		isp_nodewwn;
 	uint64_t		isp_portwwn;
+
+	/*
+	 * Our Port Data Base
+	 */
 	fcportdb_t		portdb[MAX_FC_TARG];
+
+	/*
+	 * This maps system virtual 'target' id to a portdb entry.
+	 *
+	 * The mapping function is to take any non-zero entry and
+	 * subtract one to get the portdb index. This means that
+	 * entries which are zero are unmapped (i.e., don't exist).
+	 */
 	uint16_t		isp_ini_map[MAX_FC_TARG];
+
 	/*
 	 * Scratch DMA mapped in area to fetch Port Database stuff, etc.
 	 */


More information about the p4-projects mailing list