Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 19 Mar 2017 09:30:03 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r315533 - head/sys/dev/isp
Message-ID:  <201703190930.v2J9U3Xl040656@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sun Mar 19 09:30:03 2017
New Revision: 315533
URL: https://svnweb.freebsd.org/changeset/base/315533

Log:
  Move 24xx RQSTYPE_NOTIFY handling to generic code.
  
  This code has nothing to do with specific platform.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/isp/isp_freebsd.c
  head/sys/dev/isp/isp_target.c
  head/sys/dev/isp/isp_target.h

Modified: head/sys/dev/isp/isp_freebsd.c
==============================================================================
--- head/sys/dev/isp/isp_freebsd.c	Sun Mar 19 07:34:19 2017	(r315532)
+++ head/sys/dev/isp/isp_freebsd.c	Sun Mar 19 09:30:03 2017	(r315533)
@@ -788,7 +788,6 @@ static void isp_target_start_ctio(ispsof
 static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
 static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
 static void isp_handle_platform_ctio(ispsoftc_t *, void *);
-static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *, uint32_t rsp);
 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
 static void isp_target_mark_aborted_early(ispsoftc_t *, int chan, tstate_t *, uint32_t);
@@ -2108,28 +2107,24 @@ mdp:
 
 
 static void
-isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw)
+isp_handle_platform_srr(ispsoftc_t *isp, isp_notify_t *notify)
 {
-	in_fcentry_24xx_t *inot = inot_raw;
+	in_fcentry_24xx_t *inot = notify->nt_lreserved;
 	atio_private_data_t *atp;
-	uint32_t tag = inot->in_rxid;
-	uint32_t bus = inot->in_vpidx;
+	uint32_t tag = notify->nt_tagval & 0xffffffff;
 
-	if (!IS_24XX(isp)) {
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_raw);
-		return;
-	}
-
-	atp = isp_find_atpd(isp, bus, tag);
+	atp = isp_find_atpd(isp, notify->nt_channel, tag);
 	if (atp == NULL) {
-		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag);
+		isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify",
+		    __func__, tag);
 		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
 		return;
 	}
 	atp->srr_notify_rcvd = 1;
 	memcpy(atp->srr, inot, sizeof (atp->srr));
-	isp_prt(isp, ISP_LOGTINFO /* ISP_LOGTDEBUG0 */, "SRR[0x%x] inot->in_rxid flags 0x%x srr_iu=%x reloff 0x%x", inot->in_rxid, inot->in_flags, inot->in_srr_iu,
-	    inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16));
+	isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] flags 0x%x srr_iu %x reloff 0x%x",
+	    inot->in_rxid, inot->in_flags, inot->in_srr_iu,
+	    ((uint32_t)inot->in_srr_reloff_hi << 16) | inot->in_srr_reloff_lo);
 	if (atp->srr_ccb)
 		isp_handle_srr_start(isp, atp);
 }
@@ -2281,127 +2276,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp
 	}
 }
 
-static void
-isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
-{
-	uint16_t nphdl;
-	uint16_t prli_options = 0;
-	uint32_t portid;
-	fcportdb_t *lp;
-	char *msg = NULL;
-	uint8_t *ptr = (uint8_t *)inot;
-	uint64_t wwpn = INI_NONE, wwnn = INI_NONE;
-
-	nphdl = inot->in_nphdl;
-	if (nphdl != NIL_HANDLE) {
-		portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
-	} else {
-		portid = PORT_ANY;
-	}
-
-	switch (inot->in_status) {
-	case IN24XX_ELS_RCVD:
-	{
-		char buf[16];
-		int chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
-
-		/*
-		 * Note that we're just getting notification that an ELS was received
-		 * (possibly with some associated information sent upstream). This is
-		 * *not* the same as being given the ELS frame to accept or reject.
-		 */
-		switch (inot->in_status_subcode) {
-		case LOGO:
-			msg = "LOGO";
-			wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
-			isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid);
-			break;
-		case PRLO:
-			msg = "PRLO";
-			break;
-		case PLOGI:
-			msg = "PLOGI";
-			wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]);
-			wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
-			isp_add_wwn_entry(isp, chan, wwpn, wwnn,
-			    nphdl, portid, prli_options);
-			break;
-		case PRLI:
-			msg = "PRLI";
-			prli_options = inot->in_prli_options;
-			if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID)
-				wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]);
-			wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]);
-			isp_add_wwn_entry(isp, chan, wwpn, wwnn,
-			    nphdl, portid, prli_options);
-			break;
-		case PDISC:
-			msg = "PDISC";
-			break;
-		case ADISC:
-			msg = "ADISC";
-			break;
-		default:
-			ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode);
-			msg = buf;
-			break;
-		}
-		if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
-			isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x PortID 0x%06x marked as needing a PUREX response", msg, chan, nphdl, portid);
-			break;
-		}
-		isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl, portid,
-		    inot->in_rxid, inot->in_oxid);
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
-		break;
-	}
-
-	case IN24XX_PORT_LOGOUT:
-		msg = "PORT LOGOUT";
-		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 */
-	case IN24XX_PORT_CHANGED:
-		if (msg == NULL)
-			msg = "PORT CHANGED";
-		/* FALLTHROUGH */
-	case IN24XX_LIP_RESET:
-		if (msg == NULL)
-			msg = "LIP RESET";
-		isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), msg, inot->in_status_subcode, nphdl);
-
-		/*
-		 * All subcodes here are irrelevant. What is relevant
-		 * is that we need to terminate all active commands from
-		 * this initiator (known by N-port handle).
-		 */
-		/* XXX IMPLEMENT XXX */
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
-		break;
-
-	case IN24XX_SRR_RCVD:
-#ifdef	ISP_TARGET_MODE
-		isp_handle_srr_notify(isp, inot);
-		break;
-#else
-		if (msg == NULL)
-			msg = "SRR RCVD";
-		/* FALLTHROUGH */
-#endif
-	case IN24XX_LINK_RESET:
-		if (msg == NULL)
-			msg = "LINK RESET";
-	case IN24XX_LINK_FAILED:
-		if (msg == NULL)
-			msg = "LINK FAILED";
-	default:
-		isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), msg);
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
-		break;
-	}
-}
-
 static int
 isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp, uint32_t rsp)
 {
@@ -4044,6 +3918,9 @@ changed:
 			 */
 			isp_handle_platform_target_notify_ack(isp, notify, 0);
 			break;
+		case NT_SRR:
+			isp_handle_platform_srr(isp, notify);
+			break;
 		default:
 			isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode);
 			isp_handle_platform_target_notify_ack(isp, notify, 0);
@@ -4080,12 +3957,6 @@ changed:
 		hp = va_arg(ap, isphdr_t *);
 		va_end(ap);
 		switch (hp->rqs_entry_type) {
-		default:
-			isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
-			break;
-		case RQSTYPE_NOTIFY:
-			isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
-			break;
 		case RQSTYPE_ATIO:
 			isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
 			break;
@@ -4098,6 +3969,10 @@ changed:
 		case RQSTYPE_CTIO:
 			isp_handle_platform_ctio(isp, hp);
 			break;
+		default:
+			isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x",
+			    __func__, hp->rqs_entry_type);
+			break;
 		}
 		break;
 	}

Modified: head/sys/dev/isp/isp_target.c
==============================================================================
--- head/sys/dev/isp/isp_target.c	Sun Mar 19 07:34:19 2017	(r315532)
+++ head/sys/dev/isp/isp_target.c	Sun Mar 19 09:30:03 2017	(r315533)
@@ -152,7 +152,7 @@ isp_target_notify(ispsoftc_t *isp, void 
 #define	hdrp		unp.hp
 	} unp;
 	uint8_t local[QENTRY_LEN];
-	int bus, type, len, level, rval = 1;
+	int type, len, level, rval = 1;
 
 	type = isp_get_response_type(isp, (isphdr_t *)vptr);
 	unp.vp = vptr;
@@ -214,11 +214,9 @@ isp_target_notify(ispsoftc_t *isp, void 
 		break;
 
 	case RQSTYPE_NOTIFY:
-		bus = 0;
 		if (IS_24XX(isp)) {
 			isp_get_notify_24xx(isp, inot_24xx, (in_fcentry_24xx_t *)local);
-			inot_24xx = (in_fcentry_24xx_t *) local;
-			isp_handle_notify_24xx(isp, inot_24xx);
+			isp_handle_notify_24xx(isp, (in_fcentry_24xx_t *)local);
 			break;
 		}
 		if (ISP_CAP_2KLOGIN(isp))
@@ -1380,51 +1378,152 @@ isp_handle_notify(ispsoftc_t *isp, in_fc
 }
 
 static void
-isp_handle_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot_24xx)
+isp_handle_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot)
 {
-	uint8_t ochan, chan, lochan, hichan;
+	uint8_t chan;
+	uint16_t nphdl, prli_options = 0;
+	uint32_t portid;
+	fcportdb_t *lp;
+	char *msg = NULL;
+	uint8_t *ptr = (uint8_t *)inot;
+	uint64_t wwpn = INI_NONE, wwnn = INI_NONE;
+	isp_notify_t notify;
+	char buf[16];
 
-	/*
-	 * Check to see whether we got a wildcard channel.
-	 * If so, we have to iterate over all channels.
-	 */
-	ochan = chan = ISP_GET_VPIDX(isp, inot_24xx->in_vpidx);
-	if (chan == 0xff) {
-		lochan = 0;
-		hichan = isp->isp_nchan;
+	nphdl = inot->in_nphdl;
+	if (nphdl != NIL_HANDLE) {
+		portid = inot->in_portid_hi << 16 | inot->in_portid_lo;
 	} else {
-		if (chan >= isp->isp_nchan) {
-			char buf[64];
-			ISP_SNPRINTF(buf, sizeof buf, "%s: bad channel %d for status 0x%x", __func__, chan, inot_24xx->in_status);
-			isp_print_bytes(isp, buf, QENTRY_LEN, inot_24xx);
-			isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
-			return;
+		portid = PORT_ANY;
+	}
+
+	chan = ISP_GET_VPIDX(isp, inot->in_vpidx);
+	if (chan >= isp->isp_nchan &&
+	    inot->in_status != IN24XX_LIP_RESET &&
+	    inot->in_status != IN24XX_LINK_RESET &&
+	    inot->in_status != IN24XX_LINK_FAILED) {
+		isp_prt(isp, ISP_LOGWARN, "%s: Received INOT with status %x on VP %x",
+		    __func__, inot->in_status, chan);
+		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
+		return;
+	}
+
+	switch (inot->in_status) {
+	case IN24XX_ELS_RCVD:
+	{
+		/*
+		 * Note that we're just getting notification that an ELS was
+		 * received (possibly with some associated information sent
+		 * upstream).  This is *not* the same as being given the ELS
+		 * frame to accept or reject.
+		 */
+		switch (inot->in_status_subcode) {
+		case LOGO:
+			msg = "LOGO";
+			wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
+			isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid);
+			break;
+		case PRLO:
+			msg = "PRLO";
+			break;
+		case PLOGI:
+			msg = "PLOGI";
+			wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]);
+			wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]);
+			isp_add_wwn_entry(isp, chan, wwpn, wwnn,
+			    nphdl, portid, prli_options);
+			break;
+		case PRLI:
+			msg = "PRLI";
+			prli_options = inot->in_prli_options;
+			if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID)
+				wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]);
+			wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]);
+			isp_add_wwn_entry(isp, chan, wwpn, wwnn,
+			    nphdl, portid, prli_options);
+			break;
+		case PDISC:
+			msg = "PDISC";
+			break;
+		case ADISC:
+			msg = "ADISC";
+			break;
+		default:
+			ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x",
+			    inot->in_status_subcode);
+			msg = buf;
+			break;
+		}
+		if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) {
+			isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x"
+			    " PortID 0x%06x marked as needing a PUREX response",
+			    msg, chan, nphdl, portid);
+			break;
 		}
-		lochan = chan;
-		hichan = chan + 1;
+		isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x"
+		    " PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl,
+		    portid, inot->in_rxid, inot->in_oxid);
+		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
+		break;
 	}
-	isp_prt(isp, ISP_LOGTDEBUG1, "%s: Immediate Notify Channels %d..%d status=0x%x seqid=0x%x", __func__, lochan, hichan-1, inot_24xx->in_status, inot_24xx->in_rxid);
-	switch (inot_24xx->in_status) {
-	case IN24XX_LIP_RESET:
-	case IN24XX_LINK_RESET:
+
 	case IN24XX_PORT_LOGOUT:
+		msg = "PORT LOGOUT";
+		if (isp_find_pdb_by_handle(isp, chan, nphdl, &lp))
+			isp_del_wwn_entry(isp, chan, lp->port_wwn, nphdl, lp->portid);
+		/* FALLTHROUGH */
 	case IN24XX_PORT_CHANGED:
-	case IN24XX_LINK_FAILED:
+		if (msg == NULL)
+			msg = "PORT CHANGED";
+		/* FALLTHROUGH */
+	case IN24XX_LIP_RESET:
+		if (msg == NULL)
+			msg = "LIP RESET";
+		isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for "
+		    "N-port handle 0x%x",
+		    chan, msg, inot->in_status_subcode, nphdl);
+
+		/*
+		 * All subcodes here are irrelevant. What is relevant
+		 * is that we need to terminate all active commands from
+		 * this initiator (known by N-port handle).
+		 */
+		/* XXX IMPLEMENT XXX */
+		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
+		break;
+
 	case IN24XX_SRR_RCVD:
-	case IN24XX_ELS_RCVD:
-		for (chan = lochan; chan < hichan; chan++) {
-			if (FCPARAM(isp, chan)->role == ISP_ROLE_NONE)
-				continue;
-			inot_24xx->in_reserved = 0; /* clear this for later usage */
-			inot_24xx->in_vpidx = chan;
-			isp_async(isp, ISPASYNC_TARGET_ACTION, inot_24xx);
-		}
-		inot_24xx->in_vpidx = ochan;
+#ifdef	ISP_TARGET_MODE
+		ISP_MEMZERO(&notify, sizeof (isp_notify_t));
+		notify.nt_hba = isp;
+		notify.nt_wwn = INI_ANY;
+		notify.nt_tgt = FCPARAM(isp, chan)->isp_wwpn;
+		notify.nt_nphdl = nphdl;
+		notify.nt_sid = portid;
+		notify.nt_did = PORT_ANY;
+		notify.nt_lun = LUN_ANY;
+		notify.nt_tagval = inot->in_rxid;
+		notify.nt_tagval |= ((uint64_t)inot->in_srr_rxid << 32);
+		notify.nt_need_ack = 1;
+		notify.nt_channel = chan;
+		notify.nt_lreserved = inot;
+		notify.nt_ncode = NT_SRR;
+		isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
 		break;
+#else
+		if (msg == NULL)
+			msg = "SRR RCVD";
+		/* FALLTHROUGH */
+#endif
+	case IN24XX_LINK_RESET:
+		if (msg == NULL)
+			msg = "LINK RESET";
+	case IN24XX_LINK_FAILED:
+		if (msg == NULL)
+			msg = "LINK FAILED";
 	default:
-		isp_prt(isp, ISP_LOGINFO, "%s: unhandled status (0x%x) for chan %d",
-		    __func__, inot_24xx->in_status, chan);
-		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_24xx);
+		isp_prt(isp, ISP_LOGWARN, "Chan %d %s", chan, msg);
+		isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
 		break;
 	}
 }

Modified: head/sys/dev/isp/isp_target.h
==============================================================================
--- head/sys/dev/isp/isp_target.h	Sun Mar 19 07:34:19 2017	(r315532)
+++ head/sys/dev/isp/isp_target.h	Sun Mar 19 09:30:03 2017	(r315533)
@@ -53,7 +53,8 @@ typedef enum {
 	NT_CHANGED,
 	NT_HBA_RESET,
 	NT_QUERY_TASK_SET,
-	NT_QUERY_ASYNC_EVENT
+	NT_QUERY_ASYNC_EVENT,
+	NT_SRR			/* Sequence Retransmission Request */
 } isp_ncode_t;
 
 typedef struct isp_notify {



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