From ecc3a1ae5b17306720098f5064a98c7c04337dde Mon Sep 17 00:00:00 2001
From: mjacob <mjacob@cvs.openbsd.org>
Date: Mon, 3 Mar 2003 18:31:43 +0000
Subject: Add (untested, no h/w) 10160 support. Propagate some spelling fixes.
 Add back in merged 'mhz' change.

Use A64 variants to initialize ULTRA2 or better && 1240 cards. If PAE
is ever implemented for *BSD, we'll be closer to being ready to go.

Add in a commented out example for how to adjust idelaytimer on 2300s.

If we have ISP_FW_CRASH_DUMP defined, then don't reinit the isp in
ISP_CONN_FATAL case- that's up to the platform outer layer to do after
it finishes saving a f/w crashdump.

Replaces STRNCAT with SNPRINTF.
---
 sys/dev/ic/isp.c | 139 +++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 88 insertions(+), 51 deletions(-)

(limited to 'sys/dev/ic/isp.c')

diff --git a/sys/dev/ic/isp.c b/sys/dev/ic/isp.c
index 2f6390e8774..5130c8185f3 100644
--- a/sys/dev/ic/isp.c
+++ b/sys/dev/ic/isp.c
@@ -1,4 +1,4 @@
-/* 	$OpenBSD: isp.c,v 1.30 2003/02/28 20:31:34 mjacob Exp $ */
+/* 	$OpenBSD: isp.c,v 1.31 2003/03/03 18:31:42 mjacob Exp $ */
 /*
  * Machine and OS Independent (well, as best as possible)
  * code for the Qlogic ISP SCSI adapters.
@@ -284,6 +284,8 @@ isp_reset(struct ispsoftc *isp)
 			btype = "1280";
 		else if (IS_1080(isp))
 			btype = "1080";
+		else if (IS_10160(isp))
+			btype = "10160";
 		else if (IS_12160(isp))
 			btype = "12160";
 		else
@@ -788,14 +790,10 @@ again:
 	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
 	 * we do get a firmware attributes word returned in mailbox register 6.
 	 *
-	 * Because the lun is in a a different position in the Request Queue
+	 * Because the lun is in a different position in the Request Queue
 	 * Entry structure for Fibre Channel with expanded lun firmware, we
 	 * can only support one lun (lun zero) when we don't know what kind
 	 * of firmware we're running.
-	 *
-	 * Note that we only do this once (the first time thru isp_reset)
-	 * because we may be called again after firmware has been loaded once
-	 * and released.
 	 */
 	if (IS_SCSI(isp)) {
 		if (dodnld) {
@@ -950,28 +948,55 @@ isp_scsi_init(struct ispsoftc *isp)
 	 * Now enable request/response queues
 	 */
 
-	mbs.param[0] = MBOX_INIT_RES_QUEUE;
-	mbs.param[1] = RESULT_QUEUE_LEN(isp);
-	mbs.param[2] = DMA_WD1(isp->isp_result_dma);
-	mbs.param[3] = DMA_WD0(isp->isp_result_dma);
-	mbs.param[4] = 0;
-	mbs.param[5] = 0;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
-	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-		return;
-	}
-	isp->isp_residx = mbs.param[5];
+	if (IS_ULTRA2(isp) || IS_1240(isp)) {
+		mbs.param[0] = MBOX_INIT_RES_QUEUE_A64;
+		mbs.param[1] = RESULT_QUEUE_LEN(isp);
+		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
+		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
+		mbs.param[4] = 0;
+		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
+		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
+		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			return;
+		}
+		isp->isp_residx = mbs.param[5];
 
-	mbs.param[0] = MBOX_INIT_REQ_QUEUE;
-	mbs.param[1] = RQUEST_QUEUE_LEN(isp);
-	mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
-	mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
-	mbs.param[4] = 0;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
-	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-		return;
+		mbs.param[0] = MBOX_INIT_REQ_QUEUE_A64;
+		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
+		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+		mbs.param[5] = 0;
+		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
+		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
+		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			return;
+		}
+		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
+	} else {
+		mbs.param[0] = MBOX_INIT_RES_QUEUE;
+		mbs.param[1] = RESULT_QUEUE_LEN(isp);
+		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
+		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
+		mbs.param[4] = 0;
+		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			return;
+		}
+		isp->isp_residx = mbs.param[5];
+
+		mbs.param[0] = MBOX_INIT_REQ_QUEUE;
+		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
+		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+		mbs.param[5] = 0;
+		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			return;
+		}
+		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 	}
-	isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
 
 	/*
 	 * Turn on Fast Posting, LVD transitions
@@ -1260,6 +1285,14 @@ isp_fibre_init(struct ispsoftc *isp)
 			 * so we don't need to clear it in fwoptions.
 			 */
 			icbp->icb_xfwoptions |= ICBXOPT_ZIO;
+#if	0
+			/*
+			 * Values, in 100us increments. The default
+			 * is 2 (200us) if a value 0 (default) is
+			 * selected.
+			 */
+			icbp->icb_idelaytimer = 2;
+#endif
 
 			if (isp->isp_confopts & ISP_CFG_ONEGB) {
 				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
@@ -1599,7 +1632,7 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay)
 	 * Check to see if we're on a fabric by trying to see if we
 	 * can talk to the fabric name server. This can be a bit
 	 * tricky because if we're a 2100, we should check always
-	 * (in case we're connected to an server doing aliasing).
+	 * (in case we're connected to a server doing aliasing).
 	 */
 	fcp->isp_onfabric = 0;
 
@@ -3124,7 +3157,7 @@ isp_start(XS_T *xs)
 		isp_update(isp);
 	}
 
-	if (isp_getrqentry(isp, &nxti, &optr, (void **)&qep)) {
+	if (isp_getrqentry(isp, &nxti, &optr, (void *)&qep)) {
 		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
 		XS_SETERR(xs, HBA_BOTCH);
 		return (CMD_EAGAIN);
@@ -3153,7 +3186,7 @@ isp_start(XS_T *xs)
 			isp_put_request(isp, reqp, qep);
 			ISP_ADD_REQUEST(isp, nxti);
 			isp->isp_sendmarker &= ~(1 << i);
-			if (isp_getrqentry(isp, &nxti, &optr, (void **) &qep)) {
+			if (isp_getrqentry(isp, &nxti, &optr, (void *) &qep)) {
 				isp_prt(isp, ISP_LOGDEBUG0,
 				    "Request Queue Overflow+");
 				XS_SETERR(xs, HBA_BOTCH);
@@ -4183,9 +4216,13 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox)
 			break;
 		case ISP_CONN_FATAL:
 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
+#ifdef	ISP_FW_CRASH_DUMP
+			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
+#else
 			isp_async(isp, ISPASYNC_FW_CRASH, NULL);
 			isp_reinit(isp);
 			isp_async(isp, ISPASYNC_FW_RESTARTED, NULL);
+#endif
 			return (-1);
 		case ISP_CONN_LOOPBACK:
 			isp_prt(isp, ISP_LOGWARN,
@@ -4308,53 +4345,52 @@ isp_parse_status(struct ispsoftc *isp, ispstatusreq_t *sp, XS_T *xs)
 	case RQCS_TRANSPORT_ERROR:
 	{
 		char buf[172];
-		buf[0] = 0;
-		STRNCAT(buf, "states=>", sizeof buf);
+		SNPRINTF(buf, sizeof (buf), "states=>");
 		if (sp->req_state_flags & RQSF_GOT_BUS) {
-			STRNCAT(buf, " GOT_BUS", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
 		}
 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
-			STRNCAT(buf, " GOT_TGT", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
 		}
 		if (sp->req_state_flags & RQSF_SENT_CDB) {
-			STRNCAT(buf, " SENT_CDB", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
 		}
 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
-			STRNCAT(buf, " XFRD_DATA", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
 		}
 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
-			STRNCAT(buf, " GOT_STS", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
 		}
 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
-			STRNCAT(buf, " GOT_SNS", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
 		}
 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
-			STRNCAT(buf, " XFR_CMPLT", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
 		}
-		STRNCAT(buf, "\nstatus=>", sizeof buf);
+		SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
-			STRNCAT(buf, " Disconnect", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
 		}
 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
-			STRNCAT(buf, " Sync_xfr", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
 		}
 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
-			STRNCAT(buf, " Parity", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
 		}
 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
-			STRNCAT(buf, " Bus_Reset", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
 		}
 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
-			STRNCAT(buf, " Device_Reset", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
 		}
 		if (sp->req_status_flags & RQSTF_ABORTED) {
-			STRNCAT(buf, " Aborted", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
 		}
 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
-			STRNCAT(buf, " Timeout", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
 		}
 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
-			STRNCAT(buf, " Negotiation", sizeof buf);
+			SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
 		}
 		isp_prt(isp, ISP_LOGERR, "%s", buf);
 		isp_prt(isp, ISP_LOGERR, "transport error for %d.%d.%d:\n%s",
@@ -4826,8 +4862,8 @@ static u_int16_t mbpscsi[] = {
 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
-	ISPOPMAP(0xdf, 0xdf),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
-	ISPOPMAP(0xff, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
+	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
+	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
@@ -5169,7 +5205,7 @@ static char *fc_mbcmd_names[] = {
 	NULL,
 	NULL,
 	NULL,
-	NULL,
+	"DRIVER HEARTBEAT",
 	NULL,
 	"GET/SET DATA RATE",
 	NULL,
@@ -5869,7 +5905,8 @@ isp_read_nvram(struct ispsoftc *isp)
 
 	if (IS_ULTRA3(isp)) {
 		isp_parse_nvram_12160(isp, 0, nvram_data);
-		isp_parse_nvram_12160(isp, 1, nvram_data);
+		if (IS_12160(isp))
+			isp_parse_nvram_12160(isp, 1, nvram_data);
 	} else if (IS_1080(isp)) {
 		isp_parse_nvram_1080(isp, 0, nvram_data);
 	} else if (IS_1280(isp) || IS_1240(isp)) {
-- 
cgit v1.2.3