PERFORCE change 106701 for review

Matt Jacob mjacob at FreeBSD.org
Mon Sep 25 20:33:29 PDT 2006


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

Change 106701 by mjacob at newisp on 2006/09/26 03:32:36

	Make the 24XX port login/logout function less chatty. Make both 24XX
	and other port login routines return the handle for MBOX_PORT_ID_USED
	failures in the top 16 bits because ....
	
	... When we're scanning a fabric and we try and log a port id into
	a handle and get back an error that says "this port id is using
	this other handle already", we should just use that handle. We may
	need to do some cleanup later.
	
	When thinking about logging into a port, see if we're already
	logged in.
	
	Make a function that gives you the next possible handle you could
	use, based upon the previously used handle (0xffff being the 'start'
	handle) and the hardware. There is no reason to limit ourselves for
	2K logins.
	
	When cleaning out old handles in isp_pdb_sync and we have a ISP_24XX,
	do *implicit* LOGO with FREE NPHDL- no need to go out on the wire.
	
	Limit timeout to 8191 seconds for the 24XX part. *Shrug*.

Affected files ...

.. //depot/projects/newisp/dev/isp/isp.c#13 edit

Differences ...

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

@@ -124,6 +124,7 @@
 static int isp_scan_fabric(ispsoftc_t *);
 static int isp_register_fc4_type(ispsoftc_t *);
 static int isp_register_fc4_type_24xx(ispsoftc_t *);
+static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t);
 static void isp_fw_state(ispsoftc_t *);
 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *, int);
@@ -2153,10 +2154,10 @@
 		    "PLOGX failed: invalid parameter at offset 0x%x", parm1);
 		break;
 	case PLOGX_IOCBERR_PORTUSED:
-		isp_prt(isp, ISP_LOGERR,
+		isp_prt(isp, ISP_LOGDEBUG0,
 		    "portid 0x%x already logged in with N-port handle 0x%x",
 		    portid, parm1);
-		*log_ret = MBOX_PORT_ID_USED;
+		*log_ret = MBOX_PORT_ID_USED | (handle << 16);
 		break;
 	case PLOGX_IOCBERR_HNDLUSED:
 		isp_prt(isp, ISP_LOGDEBUG0,
@@ -2198,10 +2199,10 @@
 
 	switch (mbs.param[0]) {
 	case MBOX_PORT_ID_USED:
-		isp_prt(isp, ISP_LOGERR,
+		isp_prt(isp, ISP_LOGDEBUG0,
 		    "isp_port_login: portid 0x%06x already logged in as %u",
 		    portid, mbs.param[1]);
-		return (MBOX_PORT_ID_USED);
+		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
 		break;
 
 	case MBOX_LOOP_ID_USED:
@@ -2226,7 +2227,8 @@
 
 	default:
 		isp_prt(isp, ISP_LOGERR,
-		    "isp_port_login: error 0x%x on port login", mbs.param[0]);
+		    "isp_port_login: error 0x%x on port login of 0x%06x at 0x%0x",
+		    mbs.param[0], portid, handle);
 		return (mbs.param[0]);
 	}
 }
@@ -2662,9 +2664,13 @@
 			lp->state = FC_PORTDB_STATE_NIL;
 			if (lp->autologin == 0) {
 				if (IS_24XX(isp)) {
+					int action =
+					    PLOGX_FLG_CMD_LOGO |
+					    PLOGX_FLG_IMPLICIT |
+					    PLOGX_FLG_FREE_NPHDL;
 					FC_SCRATCH_ACQUIRE(isp);
 					isp_plogx_24xx(isp, lp->handle,
-					    lp->portid, NULL);
+					    lp->portid, &action);
 					FC_SCRATCH_RELEASE(isp);
 				} else {
 					isp_port_logout(isp, lp->handle,
@@ -3160,6 +3166,7 @@
 {
 	fcparam *fcp = FCPARAM(isp);
 	uint32_t portid;
+	uint16_t handle, oldhandle;
 	int portidx, portlim, r;
 	sns_gid_ft_rsp_t *rs0, *rs1;
 
@@ -3227,6 +3234,11 @@
 	fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
 
 	/*
+	 * Prime the handle we will start using.
+	 */
+	oldhandle = 0xffff;
+
+	/*
 	 * Okay, we now have a list of Port IDs for all FC4 SCSI devices
 	 * that the Fabric Name server knows about. Go through the list
 	 * and remove duplicate port ids.
@@ -3294,12 +3306,12 @@
 	 * WWNN/WWPN duple, we enter the device into our database.
 	 */
 
+
 	for (portidx = 0; portidx < portlim; portidx++) {
 		fcportdb_t *lp;
-		uint16_t handle;
 		isp_pdb_t pdb;
 		uint64_t wwnn, wwpn;
-		int base, dbidx, r, nr;
+		int base, dbidx, r, nr, lim;
 
 		portid =
 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
@@ -3471,43 +3483,50 @@
 
 		if (dbidx == MAX_FC_TARG) {
 			isp_prt(isp, ISP_LOGERR,
-			    "port database too small to login fabric device");
+			    "port database too small to login fabric device"
+			    "- increase MAX_FC_TARG");
 			continue;
 		}
 
-		/*
-		 * Start the handle at the database index and search for
-		 * a handle that the f/w will like us to use.
-		 */
-		handle = dbidx;
-		for (r = 0; r < MAX_FC_TARG; r++) {
+		if (IS_24XX(isp)) {
+			lim = 0xffff;
+		} else {
+			lim = MAX_FC_TARG;
+		}
+		handle = isp_nxt_handle(isp, oldhandle);
+		for (r = 0; r < lim; r++) {
 			int logval;
-			if (handle >= FL_ID && handle <= SNS_ID) {
-				if (++handle == MAX_FC_TARG) {
-					handle = 0;
-				}
-				continue;
-			}
 
 			/*
-			 * Try and log out of the device first.
+			 * See if we're still logged into something with
+			 * this handle and that something agrees with this
+			 * port id.
 			 */
-			if (IS_24XX(isp)) {
-				logval = 0xc8;
-				isp_plogx_24xx(isp, handle, portid, &logval);
-			} else {
-				isp_port_logout(isp, handle, portid);
+			r = isp_getpdb(isp, handle, &pdb, 0);
+			if (r == 0 && pdb.portid != portid) {
+				if (IS_24XX(isp)) {
+					logval =
+					    PLOGX_FLG_CMD_LOGO |
+					    PLOGX_FLG_IMPLICIT;
+					isp_plogx_24xx(isp, handle, portid,
+					    &logval);
+				} else {
+					isp_port_logout(isp, handle, portid);
+				}
+			} else if (r == 0) {
+				break;
 			}
 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 				FC_SCRATCH_RELEASE(isp);
 				isp_mark_portdb(isp, 1);
 				return (-1);
 			}
+
 			/*
-			 * Try and log into the device.
+			 * Now try and log into the device
 			 */
 			if (IS_24XX(isp)) {
-				logval = 0;
+				logval = PLOGX_FLG_CMD_PLOGI;
 				isp_plogx_24xx(isp, handle, portid, &logval);
 			} else {
 				logval = isp_port_login(isp, handle, portid);
@@ -3518,20 +3537,21 @@
 				return (-1);
 			}
 			if (logval == 0) {
+				oldhandle = handle;
+				break;
+			} else if ((logval & 0xffff) == MBOX_PORT_ID_USED) {
+				handle = logval >> 16;
 				break;
-			}
-			if (logval == MBOX_LOOP_ID_USED) {
-				if (++handle == MAX_FC_TARG) {
-					handle = 0;
-				}
-				continue;
+			} else if (logval != MBOX_LOOP_ID_USED) {
+				r = lim;
+				break;
 			} else {
-				r =  MAX_FC_TARG;
-				break;
+				oldhandle = handle;
+				handle = isp_nxt_handle(isp, oldhandle);
 			}
 		}
 
-		if (r == MAX_FC_TARG) {
+		if (r == lim) {
 			isp_prt(isp, ISP_LOGERR,
 			    "could not log PortID 0x%06x in", portid);
 			continue;
@@ -3550,22 +3570,15 @@
 		}
 		if (r != 0) {
 			isp_prt(isp, ISP_LOGERR,
-			    "newly logged in device disappeared");
+			    "new device 0x%06x at 0x%x disappeared",
+			    portid, handle);
 			continue;
 		}
 
 		if (pdb.handle != handle || pdb.portid != portid) {
 			isp_prt(isp, ISP_LOGERR,
-			    "newly logged in device changed already");
-			isp_prt(isp, ISP_LOGERR,
-			    "handle %x portid %x pdb.handle %x pdb.portid %x",
-			    handle, portid, pdb.handle, pdb.portid);
-			if (IS_24XX(isp)) {
-				isp_plogx_24xx(isp, pdb.handle, pdb.portid,
-				    NULL);
-			} else {
-				isp_port_logout(isp, pdb.handle, pdb.portid);
-			}
+			    "new device 0x%06x at 0x%x changed (0x%06x at 0x%0x",
+			    portid, handle, pdb.portid, pdb.handle);
 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
 				FC_SCRATCH_RELEASE(isp);
 				isp_mark_portdb(isp, 1);
@@ -3580,7 +3593,7 @@
 
 		/*
 		 * And go through the database *one* more time to make sure
-		 * that we do not make more thane one entry that has the same
+		 * that we do not make more than one entry that has the same
 		 * WWNN/WWPN duple
 		 */
 		lp = &fcp->portdb[dbidx];
@@ -3767,6 +3780,36 @@
 	}
 }
 
+static uint16_t
+isp_nxt_handle(ispsoftc_t *isp, uint16_t handle)
+{
+	if (handle == 0xffff) {
+		if (FCPARAM(isp)->isp_topo == TOPO_F_PORT) {
+			handle = 0;
+		} else {
+			handle = SNS_ID+1;
+		}
+	} else {
+		handle += 1;
+		if (handle >= FL_ID && handle <= SNS_ID) {
+			handle = SNS_ID+1;
+		} else if (IS_24XX(isp)) {
+			if (handle == 0xffff) {
+				handle = 0;
+			}
+		} else {
+			if (handle == MAX_FC_TARG) {
+				handle = 0;
+			}
+		}
+	}
+	if (handle == FCPARAM(isp)->isp_loopid) {
+		return (isp_nxt_handle(isp, handle));
+	} else {
+		return (handle);
+	}
+}
+
 /*
  * Start a command. Locking is assumed done in the caller.
  */
@@ -3999,6 +4042,9 @@
 	if (*tptr == 0 && XS_TIME(xs)) {
 		*tptr = 1;
 	}
+	if (IS_24XX(isp) && *tptr > 0x1999) {
+		*tptr = 0x1999;
+	}
 
 	if (isp_save_xs(isp, xs, &handle)) {
 		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
@@ -4534,11 +4580,13 @@
 				 */
 			}
 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
-				isp_prt(isp, ISP_LOGERR,  "bad header flag");
+				isp_print_bytes(isp, "bad header flag",
+				    QENTRY_LEN, sp);
 				buddaboom++;
 			}
 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
-				isp_prt(isp, ISP_LOGERR, "bad request packet");
+				isp_print_bytes(isp, "bad request packet",
+				    QENTRY_LEN, sp);
 				buddaboom++;
 			}
 		}


More information about the p4-projects mailing list