Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2015 08:31:49 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r288714 - stable/10/sys/dev/isp
Message-ID:  <201510050831.t958VnYU009266@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Oct  5 08:31:48 2015
New Revision: 288714
URL: https://svnweb.freebsd.org/changeset/base/288714

Log:
  MFC r285459: Unify port database use for target and initiator roles.
  
  Aside from cleaner and more consistent code, this allows ports to be both
  target and initiator same time, and easily switch from any role to any.

Modified:
  stable/10/sys/dev/isp/isp.c
  stable/10/sys/dev/isp/isp_freebsd.c
  stable/10/sys/dev/isp/isp_library.c
  stable/10/sys/dev/isp/isp_library.h
  stable/10/sys/dev/isp/isp_target.h
  stable/10/sys/dev/isp/ispvar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c	Mon Oct  5 08:30:49 2015	(r288713)
+++ stable/10/sys/dev/isp/isp.c	Mon Oct  5 08:31:48 2015	(r288714)
@@ -65,16 +65,18 @@ __FBSDID("$FreeBSD$");
  */
 #define	MBOX_DELAY_COUNT	1000000 / 100
 #define	ISP_MARK_PORTDB(a, b, c)				\
-    isp_prt(isp, ISP_LOG_SANCFG, 				\
-	"Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);	\
-    isp_mark_portdb(a, b, c)
+	do {								\
+		isp_prt(isp, ISP_LOG_SANCFG, 				\
+		    "Chan %d ISP_MARK_PORTDB@LINE %d", (b), __LINE__);	\
+		isp_mark_portdb((a), (b), (c));				\
+	} while (0)
 
 /*
  * Local static data
  */
 static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
 static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
-static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
+static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x handle 0x%x, Connection '%s'";
 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
 static const char sacq[] = "unable to acquire scratch area";
@@ -2223,36 +2225,10 @@ isp_fibre_init_2400(ispsoftc_t *isp)
 }
 
 static void
-isp_del_all_init_entries(ispsoftc_t *isp, int chan)
-{
-	fcparam *fcp = FCPARAM(isp, chan);
-	fcportdb_t *lp;
-	int i;
-
-	for (i = 0; i < MAX_FC_TARG; i++) {
-		lp = &fcp->portdb[i];
-		if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode)
-			continue;
-		lp->state = FC_PORTDB_STATE_NIL;
-		isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 1);
-		if (lp->autologin == 0) {
-			(void) isp_plogx(isp, chan, lp->handle,
-			    lp->portid,
-			    PLOGX_FLG_CMD_LOGO |
-			    PLOGX_FLG_IMPLICIT |
-			    PLOGX_FLG_FREE_NPHDL, 0);
-		} else {
-			lp->autologin = 0;
-		}
-		lp->new_prli_word3 = 0;
-		lp->new_portid = 0;
-	}
-}
-
-static void
 isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
 {
 	fcparam *fcp = FCPARAM(isp, chan);
+	fcportdb_t *lp;
 	int i;
 
 	if (chan < 0 || chan >= isp->isp_nchan) {
@@ -2260,32 +2236,28 @@ isp_mark_portdb(ispsoftc_t *isp, int cha
 		return;
 	}
 	for (i = 0; i < MAX_FC_TARG; i++) {
-		if (fcp->portdb[i].target_mode) {
-			if (disposition < 0) {
-				isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
-				    fcp->portdb[i].handle, fcp->portdb[i].portid);
-				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
-			}
-			continue;
-		}
-		if (disposition == 0) {
-			ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
-		} else {
-			switch (fcp->portdb[i].state) {
-			case FC_PORTDB_STATE_CHANGED:
-			case FC_PORTDB_STATE_PENDING_VALID:
-			case FC_PORTDB_STATE_VALID:
-			case FC_PORTDB_STATE_PROBATIONAL:
-				fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
-				break;
-			case FC_PORTDB_STATE_ZOMBIE:
-				break;
-			case FC_PORTDB_STATE_NIL:
-			default:
-				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
-				fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
-				break;
+		lp = &fcp->portdb[i];
+		switch (lp->state) {
+		case FC_PORTDB_STATE_PROBATIONAL:
+		case FC_PORTDB_STATE_DEAD:
+		case FC_PORTDB_STATE_CHANGED:
+		case FC_PORTDB_STATE_PENDING_VALID:
+		case FC_PORTDB_STATE_VALID:
+			if (disposition > 0)
+				lp->state = FC_PORTDB_STATE_PROBATIONAL;
+			else {
+				lp->state = FC_PORTDB_STATE_NIL;
+				isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
 			}
+			break;
+		case FC_PORTDB_STATE_ZOMBIE:
+			break;
+		case FC_PORTDB_STATE_NIL:
+		case FC_PORTDB_STATE_NEW:
+		default:
+			ISP_MEMZERO(lp, sizeof(*lp));
+			lp->state = FC_PORTDB_STATE_NIL;
+			break;
 		}
 	}
 }
@@ -2473,7 +2445,7 @@ isp_port_login(ispsoftc_t *isp, uint16_t
 		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
 
 	case MBOX_LOOP_ID_USED:
-		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX", handle, mbs.param[1] & 0xff);
+		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: handle 0x%x in use for port id 0x%02xXXXX", handle, mbs.param[1] & 0xff);
 		return (MBOX_LOOP_ID_USED);
 
 	case MBOX_COMMAND_COMPLETE:
@@ -2559,7 +2531,7 @@ isp_getpdb(ispsoftc_t *isp, int chan, ui
 		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
 		ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
 		ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
-		isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x flags 0x%x curstate %x", chan, pdb->portid, un.bill.pdb_flags, un.bill.pdb_curstate);
+		isp_prt(isp, ISP_LOG_SANCFG, "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x", chan, id, pdb->portid, un.bill.pdb_flags, un.bill.pdb_curstate);
 		if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
 			mbs.param[0] = MBOX_NOT_LOGGED_IN;
 			if (dolock) {
@@ -2587,6 +2559,7 @@ isp_dump_chip_portdb(ispsoftc_t *isp, in
 	isp_pdb_t pdb;
 	int lim, loopid;
 
+	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
 	if (ISP_CAP_2KLOGIN(isp)) {
 		lim = NPH_MAX_2K;
 	} else {
@@ -2988,16 +2961,8 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 		lp = &fcp->portdb[dbidx];
 
-		if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
-			continue;
-		}
-
-		if (lp->state == FC_PORTDB_STATE_VALID) {
-			if (dbidx != FL_ID) {
-				isp_prt(isp,
-				    ISP_LOGERR, "portdb idx %d already valid",
-			    	    dbidx);
-			}
+		if (lp->state == FC_PORTDB_STATE_NIL ||
+		    lp->state == FC_PORTDB_STATE_VALID) {
 			continue;
 		}
 
@@ -3005,7 +2970,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
 		case FC_PORTDB_STATE_PROBATIONAL:
 		case FC_PORTDB_STATE_DEAD:
 			lp->state = FC_PORTDB_STATE_NIL;
-			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 0);
+			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
 			if (lp->autologin == 0) {
 				(void) isp_plogx(isp, chan, lp->handle,
 				    lp->portid,
@@ -3029,17 +2994,14 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
 			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
 			lp->new_prli_word3 = 0;
 			lp->new_portid = 0;
-			lp->announced = 0;
 			break;
 		case FC_PORTDB_STATE_CHANGED:
-/*
- * XXXX FIX THIS
- */
 			lp->state = FC_PORTDB_STATE_VALID;
 			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
+			lp->portid = lp->new_portid;
+			lp->prli_word3 = lp->new_prli_word3;
 			lp->new_prli_word3 = 0;
 			lp->new_portid = 0;
-			lp->announced = 0;
 			break;
 		case FC_PORTDB_STATE_PENDING_VALID:
 			lp->portid = lp->new_portid;
@@ -3050,13 +3012,12 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
 				lp->new_prli_word3 = 0;
 				lp->new_portid = 0;
 			}
-			lp->announced = 0;
 			break;
 		case FC_PORTDB_STATE_ZOMBIE:
 			break;
 		default:
 			isp_prt(isp, ISP_LOGWARN,
-			    "isp_scan_loop: state %d for idx %d",
+			    "isp_pdb_sync: state %d for idx %d",
 			    lp->state, dbidx);
 			isp_dump_portdb(isp, chan);
 		}
@@ -3127,7 +3088,6 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 
 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC scan loop 0..%d", chan, lim-1);
 
-
 	/*
 	 * Run through the list and get the port database info for each one.
 	 */
@@ -3211,6 +3171,9 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 		 */
 		if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
 			int a, b, c;
+			isp_prt(isp, ISP_LOGWARN,
+			    "Chan %d bad pdb (WWNN %016jx, WWPN %016jx, PortID %06x, W3 0x%x, H 0x%x) @ handle 0x%x",
+			    chan, tmp.node_wwn, tmp.port_wwn, tmp.portid, tmp.prli_word3, tmp.handle, handle);
 			a = (tmp.node_wwn == 0);
 			b = (tmp.port_wwn == 0);
 			c = (tmp.portid == 0);
@@ -3220,13 +3183,10 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 				tmp.port_wwn =
 				    isp_get_wwn(isp, chan, handle, 0);
 				if (tmp.node_wwn && tmp.port_wwn) {
-					isp_prt(isp, ISP_LOGINFO, "DODGED!");
+					isp_prt(isp, ISP_LOGWARN, "DODGED!");
 					goto cont;
 				}
 			}
-			isp_prt(isp, ISP_LOGWARN,
-			    "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
-			    a, b, c, handle);
 			isp_dump_portdb(isp, chan);
 			continue;
 		}
@@ -3234,30 +3194,19 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 
 		/*
 		 * Now search the entire port database
-		 * for the same Port and Node WWN.
+		 * for the same Port WWN.
 		 */
-		for (i = 0; i < MAX_FC_TARG; i++) {
-			lp = &fcp->portdb[i];
-
-			if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
-				continue;
-			}
-			if (lp->node_wwn != tmp.node_wwn) {
-				continue;
-			}
-			if (lp->port_wwn != tmp.port_wwn) {
-				continue;
-			}
-
+		if (isp_find_pdb_by_wwn(isp, chan, tmp.port_wwn, &lp)) {
 			/*
 			 * Okay- we've found a non-nil entry that matches.
 			 * Check to make sure it's probational or a zombie.
 			 */
 			if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
-			    lp->state != FC_PORTDB_STATE_ZOMBIE) {
+			    lp->state != FC_PORTDB_STATE_ZOMBIE &&
+			    lp->state != FC_PORTDB_STATE_VALID) {
 				isp_prt(isp, ISP_LOGERR,
 				    "Chan %d [%d] not probational/zombie (0x%x)",
-				    chan, i, lp->state);
+				    chan, FC_PORTDB_TGT(isp, chan, lp), lp->state);
 				isp_dump_portdb(isp, chan);
 				ISP_MARK_PORTDB(isp, chan, 1);
 				isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC scan loop DONE (bad)", chan);
@@ -3269,6 +3218,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 			 * automatically.
 			 */
 			lp->autologin = 1;
+			lp->node_wwn = tmp.node_wwn;
 
 			/*
 			 * Check to make see if really still the same
@@ -3279,7 +3229,7 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 				lp->new_prli_word3 = tmp.prli_word3;
 				lp->state = FC_PORTDB_STATE_PENDING_VALID;
 				isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Loop Port 0x%06x@0x%04x Pending Valid", chan, tmp.portid, tmp.handle);
-				break;
+				continue;
 			}
 
 			/*
@@ -3296,13 +3246,6 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 			lp->state = FC_PORTDB_STATE_CHANGED;
 			lp->new_portid = tmp.portid;
 			lp->new_prli_word3 = tmp.prli_word3;
-			break;
-		}
-
-		/*
-		 * Did we find and update an old entry?
-		 */
-		if (i < MAX_FC_TARG) {
 			continue;
 		}
 
@@ -3311,9 +3254,6 @@ isp_scan_loop(ispsoftc_t *isp, int chan)
 		 * for it and save info for later disposition.
 		 */
 		for (i = 0; i < MAX_FC_TARG; i++) {
-			if (fcp->portdb[i].target_mode) {
-				continue;
-			}
 			if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
 				break;
 			}
@@ -3739,7 +3679,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 			lp = &fcp->portdb[dbidx];
 
-			if (lp->state != FC_PORTDB_STATE_PROBATIONAL || lp->target_mode) {
+			if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
 				continue;
 			}
 			if (lp->portid == portid) {
@@ -3781,7 +3721,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 			if (r != 0) {
 				lp->new_portid = portid;
 				lp->state = FC_PORTDB_STATE_DEAD;
-				isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Fabric Port 0x%06x is dead", chan, portid);
+				isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Fabric PortID 0x%06x handle 0x%x is dead (%d)", chan, portid, lp->handle, r);
 				continue;
 			}
 
@@ -3797,7 +3737,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 			if (pdb.handle != lp->handle ||
 			    pdb.portid != portid ||
 			    wwpn != lp->port_wwn ||
-			    wwnn != lp->node_wwn) {
+			    (lp->node_wwn != 0 && wwnn != lp->node_wwn)) {
 				isp_prt(isp, ISP_LOG_SANCFG,
 				    fconf, chan, dbidx, pdb.handle, pdb.portid,
 				    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
@@ -3815,8 +3755,9 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 				 * portid consistency after re-login.
 				 *
 				 */
-				if (isp_login_device(isp, chan, portid, &pdb,
-				    &oldhandle)) {
+				if ((fcp->role & ISP_ROLE_INITIATOR) == 0 ||
+				    isp_login_device(isp, chan, portid, &pdb,
+				     &oldhandle)) {
 					lp->new_portid = portid;
 					lp->state = FC_PORTDB_STATE_DEAD;
 					if (fcp->isp_loopstate !=
@@ -3837,7 +3778,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 				MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
 				MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
 				if (wwpn != lp->port_wwn ||
-				    wwnn != lp->node_wwn) {
+				    (lp->node_wwn != 0 && wwnn != lp->node_wwn)) {
 					isp_prt(isp, ISP_LOGWARN, "changed WWN"
 					    " after relogin");
 					lp->new_portid = portid;
@@ -3875,6 +3816,9 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 			continue;
 		}
 
+		if ((fcp->role & ISP_ROLE_INITIATOR) == 0)
+			continue;
+
 		/*
 		 * Ah- a new entry. Search the database again for all non-NIL
 		 * entries to make sure we never ever make a new database entry
@@ -3888,12 +3832,6 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 			    lp <= &fcp->portdb[SNS_ID]) {
 				continue;
 			}
-			/*
-			 * Skip any target mode entries.
-			 */
-			if (lp->target_mode) {
-				continue;
-			}
 			if (lp->state == FC_PORTDB_STATE_NIL) {
 				if (dbidx == MAX_FC_TARG) {
 					dbidx = lp - fcp->portdb;
@@ -3966,10 +3904,9 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 			if (dbidx >= FL_ID && dbidx <= SNS_ID) {
 				continue;
 			}
-			if (fcp->portdb[dbidx].target_mode) {
-				continue;
-			}
-			if (fcp->portdb[dbidx].node_wwn == wwnn && fcp->portdb[dbidx].port_wwn == wwpn) {
+			if ((fcp->portdb[dbidx].node_wwn == wwnn ||
+			     fcp->portdb[dbidx].node_wwn == 0) &&
+			    fcp->portdb[dbidx].port_wwn == wwpn) {
 				break;
 			}
 		}
@@ -4007,6 +3944,7 @@ isp_scan_fabric(ispsoftc_t *isp, int cha
 		 */
 		lp = &fcp->portdb[dbidx];
 		lp->handle = handle;
+		lp->node_wwn = wwnn;
 		lp->new_portid = portid;
 		lp->new_prli_word3 = nr;
 		if (lp->portid != portid || lp->prli_word3 != nr) {
@@ -4393,7 +4331,7 @@ isp_start(XS_T *xs)
 		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
 		lp = &fcp->portdb[target];
 		if (target < 0 || target >= MAX_FC_TARG ||
-		    lp->dev_map_idx == 0) {
+		    lp->is_target == 0) {
 			XS_SETERR(xs, HBA_SELTIMEOUT);
 			return (CMD_COMPLETE);
 		}
@@ -4406,7 +4344,6 @@ isp_start(XS_T *xs)
 			XS_SETERR(xs, HBA_SELTIMEOUT);
 			return (CMD_COMPLETE);
 		}
-		lp->dirty = 1;
 	} else {
 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
 		if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
@@ -4417,6 +4354,7 @@ isp_start(XS_T *xs)
 		if (sdp->update) {
 			isp_spi_update(isp, XS_CHANNEL(xs));
 		}
+		lp = NULL;
 	}
 
  start_again:
@@ -4703,7 +4641,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
 				break;
 			}
 			lp = &fcp->portdb[tgt];
-			if (lp->dev_map_idx == 0 ||
+			if (lp->is_target == 0 ||
 			    lp->state != FC_PORTDB_STATE_VALID) {
 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
 				break;
@@ -4793,7 +4731,7 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
 				break;
 			}
 			lp = &fcp->portdb[tgt];
-			if (lp->dev_map_idx == 0 ||
+			if (lp->is_target == 0 ||
 			    lp->state != FC_PORTDB_STATE_VALID) {
 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
 				break;
@@ -5004,12 +4942,6 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
 		role = va_arg(ap, int);
 		va_end(ap);
 		if (IS_FC(isp)) {
-#ifdef	ISP_TARGET_MODE
-			if ((role & ISP_ROLE_TARGET) == 0)
-				isp_del_all_wwn_entries(isp, chan);
-#endif
-			if ((role & ISP_ROLE_INITIATOR) == 0)
-				isp_del_all_init_entries(isp, chan);
 			r = isp_fc_change_role(isp, chan, role);
 		} else {
 			SDPARAM(isp, chan)->role = role;
@@ -7887,26 +7819,26 @@ isp_setdfltfcparm(ispsoftc_t *isp, int c
  * not disturb an already active list of commands.
  */
 
-void
+int
 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
 {
-	int i;
+	int i, res = 0;
 
 	isp_reset(isp, do_load_defaults);
-
 	if (isp->isp_state != ISP_RESETSTATE) {
+		res = EIO;
 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
 		ISP_DISABLE_INTS(isp);
 		goto cleanup;
 	}
 
 	isp_init(isp);
-
 	if (isp->isp_state == ISP_INITSTATE) {
 		isp->isp_state = ISP_RUNSTATE;
 	}
 
 	if (isp->isp_state != ISP_RUNSTATE) {
+		res = EIO;
 #ifndef	ISP_TARGET_MODE
 		isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
 #endif
@@ -7923,18 +7855,16 @@ isp_reinit(ispsoftc_t *isp, int do_load_
 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
 			}
 		}
- 	}
+	}
 
  cleanup:
-
 	isp->isp_nactive = 0;
-
 	isp_clear_commands(isp);
 	if (IS_FC(isp)) {
-		for (i = 0; i < isp->isp_nchan; i++) {
+		for (i = 0; i < isp->isp_nchan; i++)
 			ISP_MARK_PORTDB(isp, i, -1);
-		}
 	}
+	return (res);
 }
 
 /*

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Mon Oct  5 08:30:49 2015	(r288713)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Mon Oct  5 08:31:48 2015	(r288714)
@@ -52,11 +52,10 @@ MODULE_DEPEND(isp, cam, 1, 1, 1);
 int isp_announced = 0;
 int isp_fabric_hysteresis = 5;
 int isp_loop_down_limit = 60;	/* default loop down limit */
-int isp_change_is_bad = 0;	/* "changed" devices are bad */
 int isp_quickboot_time = 7;	/* don't wait more than N secs for loop up */
 int isp_gone_device_time = 30;	/* grace time before reporting device lost */
 int isp_autoconfig = 1;		/* automatically attach/detach devices */
-static const char prom3[] = "Chan %d PortID 0x%06x Departed from Target %u because of %s";
+static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s";
 
 static void isp_freeze_loopdown(ispsoftc_t *, int, char *);
 static d_ioctl_t ispioctl;
@@ -474,9 +473,6 @@ ispioctl(struct cdev *dev, u_long c, cad
 
 	case ISP_RESETHBA:
 		ISP_LOCK(isp);
-#ifdef	ISP_TARGET_MODE
-		isp_del_all_wwn_entries(isp, ISP_NOCHAN);
-#endif
 		isp_reinit(isp, 0);
 		ISP_UNLOCK(isp);
 		retval = 0;
@@ -528,7 +524,7 @@ ispioctl(struct cdev *dev, u_long c, cad
 			break;
 		}
 		lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid];
-		if (lp->state == FC_PORTDB_STATE_VALID || lp->target_mode) {
+		if (lp->state != FC_PORTDB_STATE_NIL) {
 			ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
 			ifc->loopid = lp->handle;
 			ifc->portid = lp->portid;
@@ -1512,13 +1508,7 @@ isp_disable_lun(ispsoftc_t *isp, union c
 done:
 	if (status == CAM_REQ_CMP) {
 		tptr->enabled = 0;
-		/*
-		 * If we have no more luns enabled for this bus,
-		 * delete all tracked wwns for it (if we are FC), 
-		 * and disable target mode.
-		 */
 		if (is_any_lun_enabled(isp, bus) == 0) {
-			isp_del_all_wwn_entries(isp, bus);
 			if (isp_disable_target_mode(isp, bus)) {
 				status = CAM_REQ_CMP_ERR;
 			}
@@ -2467,7 +2457,9 @@ isp_handle_platform_atio2(ispsoftc_t *is
 	/*
 	 * If we're not in the port database, add ourselves.
 	 */
-	if (!IS_2100(isp) && isp_find_pdb_by_loopid(isp, 0, atiop->init_id, &lp) == 0) {
+	if (!IS_2100(isp) &&
+	    (isp_find_pdb_by_handle(isp, 0, atiop->init_id, &lp) == 0 ||
+	     lp->state == FC_PORTDB_STATE_ZOMBIE)) {
 		uint64_t iid =
 			(((uint64_t) aep->at_wwpn[0]) << 48) |
 			(((uint64_t) aep->at_wwpn[1]) << 32) |
@@ -2594,6 +2586,7 @@ isp_handle_platform_atio7(ispsoftc_t *is
 		 */
 		isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already",
 		    __func__, aep->at_rxid, did, chan, sid);
+		isp_dump_portdb(isp, chan);
 		isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0);
 		return;
 	}
@@ -3116,7 +3109,7 @@ isp_handle_platform_notify_fc(ispsoftc_t
 		} else {
 			loopid = inp->in_iid;
 		}
-		if (isp_find_pdb_by_loopid(isp, 0, loopid, &lp)) {
+		if (isp_find_pdb_by_handle(isp, 0, loopid, &lp)) {
 			wwn = lp->port_wwn;
 		} else {
 			wwn = INI_ANY;
@@ -3270,7 +3263,7 @@ isp_handle_platform_notify_24xx(ispsoftc
 
 	case IN24XX_PORT_LOGOUT:
 		ptr = "PORT LOGOUT";
-		if (isp_find_pdb_by_loopid(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) {
+		if (isp_find_pdb_by_handle(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) {
 			isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid);
 		}
 		/* FALLTHROUGH */
@@ -4606,13 +4599,6 @@ isp_make_here(ispsoftc_t *isp, fcportdb_
 		xpt_free_ccb(ccb);
 		return;
 	}
-
-	/*
-	 * Since we're about to issue a rescan, mark this device as not
-	 * reported gone.
-	 */
-	fcp->reported_gone = 0;
-
 	xpt_rescan(ccb);
 }
 
@@ -4626,11 +4612,6 @@ isp_make_gone(ispsoftc_t *isp, fcportdb_
 		return;
 	}
 	if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
-		/*
-		 * We're about to send out the lost device async
-		 * notification, so indicate that we have reported it gone.
-		 */
-		fcp->reported_gone = 1;
 		xpt_async(AC_LOST_DEVICE, tp, NULL);
 		xpt_free_path(tp);
 	}
@@ -4660,6 +4641,8 @@ isp_gdt_task(void *arg, int pending)
 	ispsoftc_t *isp = fc->isp;
 	int chan = fc - isp->isp_osinfo.pc.fc;
 	fcportdb_t *lp;
+	struct ac_contract ac;
+	struct ac_device_changed *adc;
 	int dbidx, more_to_do = 0;
 
 	ISP_LOCK(isp);
@@ -4670,19 +4653,27 @@ isp_gdt_task(void *arg, int pending)
 		if (lp->state != FC_PORTDB_STATE_ZOMBIE) {
 			continue;
 		}
-		if (lp->dev_map_idx == 0 || lp->target_mode) {
-			continue;
-		}
 		if (lp->gone_timer != 0) {
-			isp_prt(isp, ISP_LOG_SANCFG, "%s: Chan %d more to do for target %u (timer=%u)", __func__, chan, lp->dev_map_idx - 1, lp->gone_timer);
 			lp->gone_timer -= 1;
 			more_to_do++;
 			continue;
 		}
-		lp->dev_map_idx = 0;
+		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Gone Device Timeout");
+		if (lp->is_target) {
+			lp->is_target = 0;
+			isp_make_gone(isp, lp, chan, dbidx);
+		}
+		if (lp->is_initiator) {
+			lp->is_initiator = 0;
+			ac.contract_number = AC_CONTRACT_DEV_CHG;
+			adc = (struct ac_device_changed *) ac.contract_data;
+			adc->wwpn = lp->port_wwn;
+			adc->port = lp->portid;
+			adc->target = lp->handle;
+			adc->arrived = 0;
+			xpt_async(AC_CONTRACT, fc->path, &ac);
+		}
 		lp->state = FC_PORTDB_STATE_NIL;
-		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Gone Device Timeout");
-		isp_make_gone(isp, lp, chan, dbidx);
 	}
 	if (fc->ready) {
 		if (more_to_do) {
@@ -4718,6 +4709,8 @@ isp_ldt_task(void *arg, int pending)
 	ispsoftc_t *isp = fc->isp;
 	int chan = fc - isp->isp_osinfo.pc.fc;
 	fcportdb_t *lp;
+	struct ac_contract ac;
+	struct ac_device_changed *adc;
 	int dbidx, i;
 
 	ISP_LOCK(isp);
@@ -4730,18 +4723,12 @@ isp_ldt_task(void *arg, int pending)
 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
 		lp = &FCPARAM(isp, chan)->portdb[dbidx];
 
-		if (lp->state != FC_PORTDB_STATE_PROBATIONAL) {
-			continue;
-		}
-		if (lp->dev_map_idx == 0 || lp->target_mode) {
+		if (lp->state == FC_PORTDB_STATE_NIL)
 			continue;
-		}
 
 		/*
 		 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST!
 		 */
-
-
 		for (i = 0; i < isp->isp_maxcmds; i++) {
 			struct ccb_scsiio *xs;
 
@@ -4758,19 +4745,24 @@ isp_ldt_task(void *arg, int pending)
 			    isp->isp_xflist[i].handle, chan, XS_TGT(xs), XS_LUN(xs));
 		}
 
-		/*
-		 * Mark that we've announced that this device is gone....
-		 */
-		lp->announced = 1;
-		lp->dev_map_idx = 0;
-		lp->state = FC_PORTDB_STATE_NIL;
-		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Loop Down Timeout");
-		isp_make_gone(isp, lp, chan, dbidx);
+		isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Loop Down Timeout");
+		if (lp->is_target) {
+			lp->is_target = 0;
+			isp_make_gone(isp, lp, chan, dbidx);
+		}
+		if (lp->is_initiator) {
+			lp->is_initiator = 0;
+			ac.contract_number = AC_CONTRACT_DEV_CHG;
+			adc = (struct ac_device_changed *) ac.contract_data;
+			adc->wwpn = lp->port_wwn;
+			adc->port = lp->portid;
+			adc->target = lp->handle;
+			adc->arrived = 0;
+			xpt_async(AC_CONTRACT, fc->path, &ac);
+		}
 	}
 
-	if (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) {
-		isp_unfreeze_loopdown(isp, chan);
-	}
+	isp_unfreeze_loopdown(isp, chan);
 	/*
 	 * The loop down timer has expired. Wake up the kthread
 	 * to notice that fact (or make it false).
@@ -5585,7 +5577,7 @@ isp_done(XS_T *sccb)
 			fcparam *fcp;
 
 			fcp = FCPARAM(isp, XS_CHANNEL(sccb));
-			fcp->portdb[XS_TGT(sccb)].reported_gone = 1;
+			fcp->portdb[XS_TGT(sccb)].is_target = 0;
 		}
 		if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
 			sccb->ccb_h.status |= CAM_DEV_QFRZN;
@@ -5608,15 +5600,16 @@ isp_done(XS_T *sccb)
 void
 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
 {
-	int bus, now;
-	static const char prom0[] = "Chan %d PortID 0x%06x handle 0x%x %s %s WWPN 0x%08x%08x";
-	static const char prom2[] = "Chan %d PortID 0x%06x handle 0x%x %s %s tgt %u WWPN 0x%08x%08x";
+	int bus;
+	static const char prom[] = "Chan %d [%d] WWPN 0x%16jx PortID 0x%06x handle 0x%x %s %s";
 	char buf[64];
 	char *msg = NULL;
 	target_id_t tgt;
 	fcportdb_t *lp;
 	struct isp_fc *fc;
 	struct cam_path *tmppath;
+	struct ac_contract ac;
+	struct ac_device_changed *adc;
 	va_list ap;
 
 	switch (cmd) {
@@ -5718,10 +5711,10 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 				if (fc->path) {
 					isp_freeze_loopdown(isp, bus, msg);
 				}
-				if (!callout_active(&fc->ldt)) {
-					callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
-					isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
-				}
+			}
+			if (!callout_active(&fc->ldt)) {
+				callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
+				isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
 			}
 		}
 		isp_fcp_reset_crn(fc, /*tgt*/0, /*tgt_set*/ 0);
@@ -5751,19 +5744,25 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 		lp = va_arg(ap, fcportdb_t *);
 		va_end(ap);
 		fc = ISP_FC_PC(isp, bus);
-		lp->announced = 0;
-		lp->gone_timer = 0;
-		if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
-			lp->dev_map_idx = (lp - FCPARAM(isp, bus)->portdb) + 1;
-		}
+		tgt = FC_PORTDB_TGT(isp, bus, lp);
 		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-		if (lp->dev_map_idx) {
-			tgt = lp->dev_map_idx - 1;
-			isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "arrived at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
+		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "arrived");
+		if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
+		    (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
+			lp->is_target = 1;
 			isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
 			isp_make_here(isp, lp, bus, tgt);
-		} else {
-			isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "arrived", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
+		}
+		if ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
+		    (lp->prli_word3 & PRLI_WD3_INITIATOR_FUNCTION)) {
+			lp->is_initiator = 1;
+			ac.contract_number = AC_CONTRACT_DEV_CHG;
+			adc = (struct ac_device_changed *) ac.contract_data;
+			adc->wwpn = lp->port_wwn;
+			adc->port = lp->portid;
+			adc->target = lp->handle;
+			adc->arrived = 1;
+			xpt_async(AC_CONTRACT, fc->path, &ac);
 		}
 		break;
 	case ISPASYNC_DEV_CHANGED:
@@ -5772,97 +5771,68 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 		lp = va_arg(ap, fcportdb_t *);
 		va_end(ap);
 		fc = ISP_FC_PC(isp, bus);
-		lp->announced = 0;
-		lp->gone_timer = 0;
-		if (isp_change_is_bad) {
-			lp->state = FC_PORTDB_STATE_NIL;
-			if (lp->dev_map_idx) {
-				tgt = lp->dev_map_idx - 1;
-				lp->dev_map_idx = 0;
-				isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad");
-				isp_make_gone(isp, lp, bus, tgt);
-			} else {
-				isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-				isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed and departed",
-				    (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-			}
-		} else {
-			lp->portid = lp->new_portid;
-			lp->prli_word3 = lp->new_prli_word3;
-			isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-			if (lp->dev_map_idx) {
-				tgt = lp->dev_map_idx - 1;
-				isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "changed at", tgt,
-				    (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
+		tgt = FC_PORTDB_TGT(isp, bus, lp);
+		isp_gen_role_str(buf, sizeof (buf), lp->new_prli_word3);
+		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->new_portid, lp->handle, buf, "changed");
+changed:
+		if (lp->is_target !=
+		    ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
+		     (lp->new_prli_word3 & PRLI_WD3_TARGET_FUNCTION))) {
+			lp->is_target = !lp->is_target;
+			if (lp->is_target) {
 				isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
+				isp_make_here(isp, lp, bus, tgt);
 			} else {
-				isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
+				isp_make_gone(isp, lp, bus, tgt);
+				isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
 			}
 		}
+		if (lp->is_initiator !=
+		    ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
+		     (lp->new_prli_word3 & PRLI_WD3_INITIATOR_FUNCTION))) {
+			lp->is_initiator = !lp->is_initiator;
+			ac.contract_number = AC_CONTRACT_DEV_CHG;
+			adc = (struct ac_device_changed *) ac.contract_data;
+			adc->wwpn = lp->port_wwn;
+			adc->port = lp->portid;
+			adc->target = lp->handle;
+			adc->arrived = lp->is_initiator;
+			xpt_async(AC_CONTRACT, fc->path, &ac);
+		}
 		break;
 	case ISPASYNC_DEV_STAYED:
 		va_start(ap, cmd);
 		bus = va_arg(ap, int);
 		lp = va_arg(ap, fcportdb_t *);
 		va_end(ap);
+		fc = ISP_FC_PC(isp, bus);
+		tgt = FC_PORTDB_TGT(isp, bus, lp);
 		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-		if (lp->dev_map_idx) {
-			fc = ISP_FC_PC(isp, bus);
-			tgt = lp->dev_map_idx - 1;
-			isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "stayed at", tgt,
-		    	    (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-			/*
-			 * Only issue a rescan if we've actually reported
-			 * that this device is gone.
-			 */
-			if (lp->reported_gone != 0) {
-				isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "rescanned at", tgt, 
-				    (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-				isp_make_here(isp, lp, bus, tgt);
-			}
-		} else {
-			isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "stayed",
-		    	    (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-		}
-		break;
+		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "stayed");
+		goto changed;
 	case ISPASYNC_DEV_GONE:
 		va_start(ap, cmd);
 		bus = va_arg(ap, int);
 		lp = va_arg(ap, fcportdb_t *);
-		now = va_arg(ap, int);
 		va_end(ap);
 		fc = ISP_FC_PC(isp, bus);
+		tgt = FC_PORTDB_TGT(isp, bus, lp);
 		/*
-		 * If this has a virtual target and we haven't marked it
-		 * that we're going to have isp_gdt tell the OS it's gone,
-		 * set the isp_gdt timer running on it.
-		 *
-		 * If it isn't marked that isp_gdt is going to get rid of it,
-		 * announce that it's gone.
-		 *
+		 * If this has a virtual target or initiator set the isp_gdt
+		 * timer running on it to delay its departure.
 		 */
 		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-		if (lp->dev_map_idx && lp->announced == 0 && now) {
-			lp->announced = 1;
-			tgt = lp->dev_map_idx - 1;
-			lp->dev_map_idx = 0;
-			isp_make_gone(isp, lp, bus, tgt);
-			isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-			isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
-		} else if (lp->dev_map_idx && lp->announced == 0) {
-			lp->announced = 1;
+		if (lp->is_target || lp->is_initiator) {
 			lp->state = FC_PORTDB_STATE_ZOMBIE;
-			lp->gone_timer = ISP_FC_PC(isp, bus)->gone_device_time;
+			lp->gone_timer = fc->gone_device_time;
+			isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone zombie");
 			if (fc->ready && !callout_active(&fc->gdt)) {
 				isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Starting Gone Device Timer with %u seconds time now %lu", bus, lp->gone_timer, (unsigned long)time_uptime);
 				callout_reset(&fc->gdt, hz, isp_gdt, fc);
 			}
-			tgt = lp->dev_map_idx - 1;
-			isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone zombie at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
-			isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
-		} else if (lp->announced == 0) {
-			isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "departed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn);
+			break;
 		}
+		isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone");
 		break;
 	case ISPASYNC_CHANGE_NOTIFY:
 	{
@@ -5928,13 +5898,11 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 		case NT_LIP_RESET:
 		case NT_LINK_UP:
 		case NT_LINK_DOWN:
+		case NT_HBA_RESET:
 			/*
 			 * No action need be taken here.
 			 */
 			break;
-		case NT_HBA_RESET:
-			isp_del_all_wwn_entries(isp, ISP_NOCHAN);
-			break;
 		case NT_GLOBAL_LOGOUT:
 		case NT_LOGOUT:
 			/*
@@ -5942,34 +5910,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 			 */
 			isp_handle_platform_target_notify_ack(isp, notify);
 			break;
-		case NT_ARRIVED:
-		{
-			struct ac_contract ac;
-			struct ac_device_changed *fc;
-
-			ac.contract_number = AC_CONTRACT_DEV_CHG;
-			fc = (struct ac_device_changed *) ac.contract_data;
-			fc->wwpn = notify->nt_wwn;
-			fc->port = notify->nt_sid;
-			fc->target = notify->nt_nphdl;
-			fc->arrived = 1;
-			xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
-			break;
-		}
-		case NT_DEPARTED:
-		{
-			struct ac_contract ac;
-			struct ac_device_changed *fc;
-
-			ac.contract_number = AC_CONTRACT_DEV_CHG;
-			fc = (struct ac_device_changed *) ac.contract_data;
-			fc->wwpn = notify->nt_wwn;
-			fc->port = notify->nt_sid;
-			fc->target = notify->nt_nphdl;
-			fc->arrived = 0;
-			xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac);
-			break;
-		}
 		default:

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510050831.t958VnYU009266>