Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2015 08:16:11 +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: r288709 - stable/10/sys/dev/isp
Message-ID:  <201510050816.t958GBBH009745@repo.freebsd.org>

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

Log:
  MFC r285146: Drop discovered targets when initiator role is disabled.

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/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:14:27 2015	(r288708)
+++ stable/10/sys/dev/isp/isp.c	Mon Oct  5 08:16:10 2015	(r288709)
@@ -2223,6 +2223,36 @@ 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;
+		/*
+		 * It's up to the outer layers to clear isp_dev_map.
+		 */
+		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);
@@ -2981,7 +3011,7 @@ isp_pdb_sync(ispsoftc_t *isp, int chan)
 			 * It's up to the outer layers to clear isp_dev_map.
 			 */
 			lp->state = FC_PORTDB_STATE_NIL;
-			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
+			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp, 0);
 			if (lp->autologin == 0) {
 				(void) isp_plogx(isp, chan, lp->handle,
 				    lp->portid,
@@ -4990,6 +5020,28 @@ isp_control(ispsoftc_t *isp, ispctl_t ct
 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
 		return (r);
 	}
+	case ISPCTL_CHANGE_ROLE:
+	{
+		int role, r;
+
+		va_start(ap, ctl);
+		chan = va_arg(ap, int);
+		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;
+			r = 0;
+		}
+		return (r);
+	}
 	default:
 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
 		break;

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Mon Oct  5 08:14:27 2015	(r288708)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Mon Oct  5 08:16:10 2015	(r288709)
@@ -115,7 +115,7 @@ isp_role_sysctl(SYSCTL_HANDLER_ARGS)
 	}
 
 	/* Actually change the role. */
-	error = isp_fc_change_role(isp, chan, value);
+	error = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, value);
 	ISP_UNLOCK(isp);
 	return (error);
 }
@@ -474,18 +474,14 @@ ispioctl(struct cdev *dev, u_long c, cad
 				retval = EINVAL;
 				break;
 			}
-			*(int *)addr = FCPARAM(isp, chan)->role;
-#ifdef	ISP_INTERNAL_TARGET
 			ISP_LOCK(isp);
-			retval = isp_fc_change_role(isp, chan, nr);
-			ISP_UNLOCK(isp);
-#else
-			FCPARAM(isp, chan)->role = nr;
-#endif
+			*(int *)addr = FCPARAM(isp, chan)->role;
 		} else {
+			ISP_LOCK(isp);
 			*(int *)addr = SDPARAM(isp, chan)->role;
-			SDPARAM(isp, chan)->role = nr;
 		}
+		retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr);
+		ISP_UNLOCK(isp);
 		retval = 0;
 		break;
 
@@ -5478,7 +5474,8 @@ isp_action(struct cam_sim *sim, union cc
 				ISP_SET_PC(isp, bus, tm_enabled, 0);
 				ISP_SET_PC(isp, bus, tm_luns_enabled, 0);
 #endif
-				if (isp_fc_change_role(isp, bus, newrole) != 0) {
+				if (isp_control(isp, ISPCTL_CHANGE_ROLE,
+				    bus, newrole) != 0) {
 					ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 					xpt_done(ccb);
 					break;
@@ -5668,7 +5665,7 @@ isp_done(XS_T *sccb)
 void
 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
 {
-	int bus;
+	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";
 	char buf[64];
@@ -5909,6 +5906,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 		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);
 		/*
@@ -5921,7 +5919,15 @@ isp_async(ispsoftc_t *isp, ispasync_t cm
 		 *
 		 */
 		isp_gen_role_str(buf, sizeof (buf), lp->prli_word3);
-		if (lp->dev_map_idx && lp->announced == 0) {
+		if (lp->dev_map_idx && lp->announced == 0 && now) {
+			lp->announced = 1;
+			tgt = lp->dev_map_idx - 1;
+			FCPARAM(isp, bus)->isp_dev_map[tgt] = 0;
+			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;
 			lp->state = FC_PORTDB_STATE_ZOMBIE;
 			lp->gone_timer = ISP_FC_PC(isp, bus)->gone_device_time;

Modified: stable/10/sys/dev/isp/isp_library.c
==============================================================================
--- stable/10/sys/dev/isp/isp_library.c	Mon Oct  5 08:14:27 2015	(r288708)
+++ stable/10/sys/dev/isp/isp_library.c	Mon Oct  5 08:16:10 2015	(r288709)
@@ -603,9 +603,6 @@ isp_fc_change_role(ispsoftc_t *isp, int 
 		return (ENXIO);
 	}
 	if (chan == 0) {
-#ifdef	ISP_TARGET_MODE
-		isp_del_all_wwn_entries(isp, chan);
-#endif
 		isp_clear_commands(isp);
 		isp_reset(isp, 0);
 		if (isp->isp_state != ISP_RESETSTATE) {
@@ -626,8 +623,6 @@ isp_fc_change_role(ispsoftc_t *isp, int 
 		uint8_t qe[QENTRY_LEN], *scp;
 
 		ISP_MEMZERO(qe, QENTRY_LEN);
-		/* Acquire Scratch */
-
 		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
 			return (EBUSY);
 		}
@@ -671,12 +666,6 @@ isp_fc_change_role(ispsoftc_t *isp, int 
 		MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
 		isp_get_vp_modify(isp, (vp_modify_t *)&scp[QENTRY_LEN], vp);
 
-#ifdef	ISP_TARGET_MODE
-		isp_del_all_wwn_entries(isp, chan);
-#endif
-		/*
-		 * Release Scratch
-		 */
 		FC_SCRATCH_RELEASE(isp, chan);
 
 		if (vp->vp_mod_status != VP_STS_OK) {

Modified: stable/10/sys/dev/isp/ispvar.h
==============================================================================
--- stable/10/sys/dev/isp/ispvar.h	Mon Oct  5 08:14:27 2015	(r288708)
+++ stable/10/sys/dev/isp/ispvar.h	Mon Oct  5 08:16:10 2015	(r288709)
@@ -915,6 +915,8 @@ void isp_done(XS_T *);
  *        Get PDB on this channel for this N-port handle
  * ... ISPCTL_PLOGX, isp_plcmd_t *)
  *        Performa a port login/logout
+ * ... ISPCTL_CHANGE_ROLE, int channel, int role);
+ *        Change role of specified channel
  *
  * ISPCTL_PDB_SYNC is somewhat misnamed. It actually is the final step, in
  * order, of ISPCTL_FCLINK_TEST, ISPCTL_SCAN_FABRIC, and ISPCTL_SCAN_LOOP.
@@ -937,7 +939,8 @@ typedef enum {
 	ISPCTL_GET_NAMES,
 	ISPCTL_RUN_MBOXCMD,
 	ISPCTL_GET_PDB,
-	ISPCTL_PLOGX
+	ISPCTL_PLOGX,
+	ISPCTL_CHANGE_ROLE
 } ispctl_t;
 int isp_control(ispsoftc_t *, ispctl_t, ...);
 



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