Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Oct 2006 20:50:41 GMT
From:      Matt Jacob <mjacob@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 108071 for review
Message-ID:  <200610182050.k9IKofcJ011804@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=108071

Change 108071 by mjacob@newisp on 2006/10/18 20:50:11

	The latest/greatest for target mode for 24XX.

Affected files ...

.. //depot/projects/newisp/dev/isp/isp_target.c#8 edit
.. //depot/projects/newisp/dev/isp/isp_target.h#10 edit

Differences ...

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

@@ -58,6 +58,7 @@
 
 static void isp_got_msg(ispsoftc_t *, in_entry_t *);
 static void isp_got_msg_fc(ispsoftc_t *, in_fcentry_t *);
+static void isp_got_tmf_24xx(ispsoftc_t *, at7_entry_t *);
 static void isp_handle_atio(ispsoftc_t *, at_entry_t *);
 static void isp_handle_atio2(ispsoftc_t *, at2_entry_t *);
 static void isp_handle_ctio(ispsoftc_t *, ct_entry_t *);
@@ -191,6 +192,13 @@
 				}
 			}
 			/*
+			 * Check for a task management function
+			 */
+			if (at7iop->at_cmnd.fcp_cmnd_task_management) {
+				isp_got_tmf_24xx(isp, at7iop);
+				break;
+			}
+			/*
 			 * Just go straight to outer layer for this one.
 			 */
 			(void) isp_async(isp, ISPASYNC_TARGET_ACTION, local);
@@ -311,16 +319,29 @@
 			isp_prt(isp, ISP_LOGWARN, "Firmware out of ATIOs");
 			isp_notify_ack(isp, local);
 			break;
-		case IN_RESET:	/* same as IN24XX_LIP_RESET */
-		case IN24XX_LINK_RESET:
-			(void) isp_target_async(isp, 0, ASYNC_BUS_RESET);
+		case IN_RESET:
+		{
+			/*
+			 * We form the notify structure here because we need
+			 * to mark it as needing a NOTIFY ACK on return.
+			 */
+			tmd_notify_t notify;
+
+			MEMZERO(&notify, sizeof (tmd_notify_t));
+			notify.nt_hba = isp;
+			notify.nt_iid = INI_ANY;
+			/* nt_tgt set in outer layers */
+			notify.nt_lun = LUN_ANY;
+			notify.nt_tagval = TAG_ANY;
+			notify.nt_ncode = NT_BUS_RESET;
+			notify.nt_need_ack = 1;
+			(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &notify);
 			break;
-		case IN_PORT_LOGOUT:	/* same as IN24XX_PORT_LOGOUT */
+		}
+		case IN_PORT_LOGOUT:
 		case IN_ABORT_TASK:
-		case IN_PORT_CHANGED:	/* same as IN24XX_PORT_CHANGED */
-		case IN_GLOBAL_LOGO:	/* same as IN24XX_LINK_FAILED */
-		case IN24XX_SRR_RCVD:
-		case IN24XX_ELS_RCVD:
+		case IN_PORT_CHANGED:
+		case IN_GLOBAL_LOGO:
 			(void) isp_async(isp, ISPASYNC_TARGET_ACTION, &local);
 			break;
 		default:
@@ -528,12 +549,14 @@
 			    (ct2_entry_t *) outp);
 		}
 		break;
+	case RQSTYPE_CTIO7:
+		isp_put_ctio7(isp, (ct7_entry_t *) ap, (ct7_entry_t *) outp);
+		break;
 	default:
 		isp_prt(isp, ISP_LOGERR,
 		    "Unknown type 0x%x in isp_put_entry", etype);
 		return (-1);
 	}
-
 	ISP_TDQE(isp, "isp_target_put_entry", (int) optr, ap);
 	ISP_ADD_REQUEST(isp, nxti);
 	return (0);
@@ -600,21 +623,42 @@
  */
 
 int
-isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint16_t hdl)
+isp_endcmd(ispsoftc_t *isp, void *arg, uint32_t code, uint32_t hdl)
 {
 	int sts;
 	union {
 		ct_entry_t _ctio;
 		ct2_entry_t _ctio2;
 		ct2e_entry_t _ctio2e;
+		ct7_entry_t _ctio7;
 	} un;
 
 	MEMZERO(&un, sizeof un);
 	sts = code & 0xff;
 
 	if (IS_24XX(isp)) {
-		isp_prt(isp, ISP_LOGERR, "XXX ISP_ENDCMD NOT DONE YET FOR 24XX");
-		return (0);
+		at7_entry_t *aep = arg;
+		ct7_entry_t *cto = &un._ctio7;
+
+		cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+		cto->ct_header.rqs_entry_count = 1;
+/* XXXX */	cto->ct_nphdl = aep->at_hdr.seq_id;
+		cto->ct_rxid = aep->at_rxid;
+		cto->ct_iid_lo = (aep->at_hdr.s_id[1] << 8) |
+		    aep->at_hdr.s_id[2];
+		cto->ct_iid_hi = aep->at_hdr.s_id[0];
+		cto->ct_oxid = aep->at_hdr.ox_id;
+		cto->ct_scsi_status = sts;
+		cto->ct_flags = CT7_FLAG_MODE1 | CT7_NO_DATA | CT7_SENDSTATUS;
+		if (sts == SCSI_CHECK && (code & ECMD_SVALID)) {
+			cto->rsp.m1.ct_resplen = 16;
+			cto->rsp.m1.ct_resp[0] = 0xf0;
+			cto->rsp.m1.ct_resp[2] = (code >> 12) & 0xf;
+			cto->rsp.m1.ct_resp[7] = 8;
+			cto->rsp.m1.ct_resp[12] = (code >> 24) & 0xff;
+			cto->rsp.m1.ct_resp[13] = (code >> 16) & 0xff;
+		}
+		cto->ct_syshandle = hdl;
 	} else if (IS_FC(isp)) {
 		at2_entry_t *aep = arg;
 		ct2_entry_t *cto = &un._ctio2;
@@ -675,6 +719,35 @@
 }
 
 /*
+ * Terminate a command
+ */
+int
+isp_terminate_cmd(ispsoftc_t *isp, void *arg)
+{
+	tmd_cmd_t *tmd = arg;
+	ct7_entry_t local, *cto = &local;;
+
+	if (!IS_24XX(isp)) {
+		return (-1);
+	}
+	isp_prt(isp, ISP_LOGTDEBUG0,
+	    "isp_terminate_cmd: tag 0x%0x is being terminated",
+	    tmd->cd_tagval);
+	MEMZERO(&local, sizeof (local));
+	cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+	cto->ct_header.rqs_entry_count = 1;
+	cto->ct_nphdl = tmd->cd_nphdl;
+	cto->ct_rxid = tmd->cd_tagval;
+	cto->ct_iid_lo = tmd->cd_portid;
+	cto->ct_iid_hi = tmd->cd_portid >> 16;
+	cto->ct_oxid = tmd->cd_oxid;
+	cto->ct_flags = CT7_TERMINATE;
+	cto->ct_syshandle = 0;
+	return (isp_target_put_entry(isp, &local));
+}
+
+
+/*
  * These are either broadcast events or specifically CTIO fast completion
  */
 int
@@ -723,7 +796,13 @@
 	{
 		uint8_t storage[QENTRY_LEN];
 		memset(storage, 0, QENTRY_LEN);
-		if (IS_FC(isp)) {
+		if (IS_24XX(isp)) {
+			ct7_entry_t *ct = (ct7_entry_t *) storage;
+			ct->ct_header.rqs_entry_type = RQSTYPE_CTIO7;
+			ct->ct_nphdl = CT7_OK;
+			ct->ct_syshandle = bus;
+			ct->ct_flags = CT7_SENDSTATUS|CT7_FASTPOST;
+		} else if (IS_FC(isp)) {
             		/* This should also suffice for 2K login code */
 			ct2_entry_t *ct = (ct2_entry_t *) storage;
 			ct->ct_header.rqs_entry_type = RQSTYPE_CTIO2;
@@ -738,7 +817,7 @@
 			ct->ct_flags = CT_SENDSTATUS;
 		}
 		(void) isp_async(isp, ISPASYNC_TARGET_ACTION, storage);
-		return (0);
+		break;
 	}
 	default:
 		isp_prt(isp, ISP_LOGERR,
@@ -818,9 +897,9 @@
 isp_got_msg_fc(ispsoftc_t *isp, in_fcentry_t *inp)
 {
 	tmd_notify_t nt;
-	static const char f1[] = "%s from loop id %d lun %d seq 0x%x";
+	static const char f1[] = "%s from N-port handle 0x%x lun %d seq 0x%x";
 	static const char f2[] = 
-	    "unknown %s 0x%x lun %d loop id %d task flags 0x%x seq 0x%x\n";
+	    "unknown %s 0x%x lun %d N-Port handle 0x%x task flags 0x%x seq 0x%x\n";
 	uint16_t seqid, loopid;
 
 	MEMZERO(&nt, sizeof (tmd_notify_t));
@@ -841,6 +920,7 @@
 		nt.nt_lun = inp->in_lun;
 	}
 	IN_FC_MAKE_TAGID(nt.nt_tagval, 0, seqid);
+	nt.nt_need_ack = 1;
 	nt.nt_lreserved = inp;
 
 	if (inp->in_status != IN_MSG_RECEIVED) {
@@ -880,6 +960,64 @@
 	(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
 }
 
+static void
+isp_got_tmf_24xx(ispsoftc_t *isp, at7_entry_t *aep)
+{
+	tmd_notify_t nt;
+	static const char f1[] = "%s from PortID 0x%06x lun %d seq 0x%x";
+	static const char f2[] = 
+	    "unknown Task Flag 0x%x lun %d PortID 0x%x tag 0x%x\n";
+	uint32_t sid;
+
+	MEMZERO(&nt, sizeof (tmd_notify_t));
+	nt.nt_hba = isp;
+	nt.nt_iid = INI_ANY;
+	nt.nt_lun =
+	    (aep->at_cmnd.fcp_cmnd_lun[0] << 8) |
+	    (aep->at_cmnd.fcp_cmnd_lun[1]);
+	nt.nt_tagval = aep->at_rxid;
+	nt.nt_lreserved = aep;
+	sid =
+	    (aep->at_hdr.s_id[0] << 16) |
+	    (aep->at_hdr.s_id[1] <<  8) |
+	    (aep->at_hdr.s_id[2]);
+
+	if (aep->at_cmnd.fcp_cmnd_task_management &
+	    FCP_CMND_TMF_ABORT_TASK_SET) {
+		isp_prt(isp, ISP_LOGINFO, f1, "ABORT TASK SET",
+		    sid, nt.nt_lun, nt.nt_tagval);
+		nt.nt_ncode = NT_ABORT_TASK_SET;
+	} else if (aep->at_cmnd.fcp_cmnd_task_management &
+	    FCP_CMND_TMF_CLEAR_TASK_SET) {
+		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR TASK SET",
+		    sid, nt.nt_lun, nt.nt_tagval);
+		nt.nt_ncode = NT_CLEAR_TASK_SET;
+	} else if (aep->at_cmnd.fcp_cmnd_task_management &
+	    FCP_CMND_TMF_LUN_RESET) {
+		isp_prt(isp, ISP_LOGINFO, f1, "LUN RESET",
+		    sid, nt.nt_lun, nt.nt_tagval);
+		nt.nt_ncode = NT_LUN_RESET;
+	} else if (aep->at_cmnd.fcp_cmnd_task_management &
+	    FCP_CMND_TMF_TGT_RESET) {
+		isp_prt(isp, ISP_LOGINFO, f1, "TARGET RESET",
+		    sid, nt.nt_lun, nt.nt_tagval);
+		nt.nt_ncode = NT_TARGET_RESET;
+		nt.nt_lun = LUN_ANY;
+	} else if (aep->at_cmnd.fcp_cmnd_task_management &
+	    FCP_CMND_TMF_CLEAR_ACA) {
+		isp_prt(isp, ISP_LOGINFO, f1, "CLEAR ACA",
+		    sid, nt.nt_lun, nt.nt_tagval);
+		nt.nt_ncode = NT_CLEAR_ACA;
+	} else {
+		isp_prt(isp, ISP_LOGWARN, f2,
+		    aep->at_cmnd.fcp_cmnd_task_management,
+		    nt.nt_lun, sid, nt.nt_tagval);
+		isp_endcmd(isp, aep, 0, 0);
+		return;
+	}
+	(void) isp_async(isp, ISPASYNC_TARGET_NOTIFY, &nt);
+}
+
 void
 isp_notify_ack(ispsoftc_t *isp, void *arg)
 {
@@ -895,7 +1033,11 @@
 
 	MEMZERO(storage, QENTRY_LEN);
 
-	if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
+	if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ATIO)) {
+		at7_entry_t *aep = arg;
+		isp_endcmd(isp, aep, 0, 0);
+		return;
+	} else if (IS_24XX(isp) && arg != NULL && (((isphdr_t *)arg)->rqs_entry_type == RQSTYPE_ABTS_RSP)) {
 		abts_rsp_t *abts_rsp = (abts_rsp_t *) storage;
 		/*
 		 * The caller will have set response values as appropriate
@@ -1519,8 +1661,9 @@
 		break;
 
 	case CT7_RESET:
-		if (fmsg == NULL)
+		if (fmsg == NULL) {
 			fmsg = "LIP Reset";
+		}
 		/*FALLTHROUGH*/
 	case CT7_ABORTED:
 		/*
@@ -1531,14 +1674,14 @@
 		if (fmsg == NULL) {
 			fmsg = "ABORT";
 		}
-
 		isp_prt(isp, ISP_LOGTDEBUG0,
-		    "CTIO2 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
+		    "CTIO7 destroyed by %s: RX_ID=0x%x", fmsg, ct->ct_rxid);
 		break;
 
 	case CT7_TIMEOUT:
-		if (fmsg == NULL)
+		if (fmsg == NULL) {
 			fmsg = "command";
+		}
 		isp_prt(isp, ISP_LOGERR, "Firmware timed out on %s", fmsg);
 		break;
 
@@ -1546,16 +1689,19 @@
 		fmsg = "Completed with Error";
 		/*FALLTHROUGH*/
 	case CT7_LOGOUT:
-		if (fmsg == NULL)
+		if (fmsg == NULL) {
 			fmsg = "Port Logout";
+		}
 		/*FALLTHROUGH*/
 	case CT7_PORTUNAVAIL:
-		if (fmsg == NULL)
+		if (fmsg == NULL) {
 			fmsg = "Port not available";
+		}
 		/*FALLTHROUGH*/
 	case CT7_PORTCHANGED:
-		if (fmsg == NULL)
+		if (fmsg == NULL) {
 			fmsg = "Port Changed";
+		}
 		isp_prt(isp, ISP_LOGWARN, "CTIO returned by f/w- %s", fmsg);
 		break;
 
@@ -1565,7 +1711,7 @@
 		 * Just print a message.
 		 */
 		isp_prt(isp, ISP_LOGWARN,
-		    "CTIO2 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
+		    "CTIO7 completed with Invalid RX_ID 0x%x", ct->ct_rxid);
 		break;
 
 	case CT7_REASSY_ERR:
@@ -1577,7 +1723,7 @@
 		break;
 
 	default:
-		isp_prt(isp, ISP_LOGERR, "Unknown CTIO2 status 0x%x",
+		isp_prt(isp, ISP_LOGERR, "Unknown CTIO7 status 0x%x",
 		    ct->ct_nphdl);
 		break;
 	}
@@ -1591,7 +1737,11 @@
 		 * order we got them.
 		 */
 		if (ct->ct_syshandle == 0) {
-			if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
+			if (ct->ct_flags & CT7_TERMINATE) {
+				isp_prt(isp, ISP_LOGALL,
+				    "termination of 0x%x complete",
+				    ct->ct_rxid);
+			} else if ((ct->ct_flags & CT7_SENDSTATUS) == 0) {
 				isp_prt(isp, pl,
 				    "intermediate CTIO completed ok");
 			} else {

==== //depot/projects/newisp/dev/isp/isp_target.h#10 (text+ko) ====

@@ -932,10 +932,15 @@
  * General routine to send a final CTIO for a command- used mostly for
  * local responses.
  */
-int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint16_t);
+int isp_endcmd(ispsoftc_t *, void *, uint32_t, uint32_t);
 #define	ECMD_SVALID	0x100
 
 /*
+ * General routine to terminate an active command
+ */
+int isp_terminate_cmd(ispsoftc_t *, void *);
+
+/*
  * Handle an asynchronous event
  *
  * Return nonzero if the interrupt that generated this event has been dismissed.



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