PERFORCE change 111920 for review

Matt Jacob mjacob at FreeBSD.org
Mon Dec 18 20:11:27 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=111920

Change 111920 by mjacob at mjexp_6 on 2006/12/19 04:10:55

	Wankatootl Fruitl! Pull the -current isp && mpt driver bundles into
	a RELENG_6 tree for integration testing.

Affected files ...

.. //depot/projects/mjexp_6/sys/dev/isp/isp.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_freebsd.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_freebsd.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_ioctl.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_library.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_library.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_pci.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_sbus.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_stds.h#1 add
.. //depot/projects/mjexp_6/sys/dev/isp/isp_target.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_target.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/isp_tpublic.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/ispmbox.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/ispreg.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/isp/ispvar.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/ispfw/asm_2400.h#1 add
.. //depot/projects/mjexp_6/sys/dev/ispfw/ispfw.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/mpt/mpt.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/mpt/mpt.h#2 edit
.. //depot/projects/mjexp_6/sys/dev/mpt/mpt_cam.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/mpt/mpt_debug.c#2 edit
.. //depot/projects/mjexp_6/sys/dev/mpt/mpt_raid.c#2 edit

Differences ...

==== //depot/projects/mjexp_6/sys/dev/isp/isp.c#2 (text+ko) ====

@@ -26,8 +26,9 @@
 
 /*
  * Machine and OS Independent (well, as best as possible)
- * code for the Qlogic ISP SCSI adapters.
+ * code for the Qlogic ISP SCSI and FC-SCSI adapters.
  */
+
 /*
  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
@@ -60,30 +61,16 @@
  */
 
 #define	MBOX_DELAY_COUNT	1000000 / 100
+#define	ISP_MARK_PORTDB(a, b)	\
+    isp_prt(isp, ISP_LOGSANCFG, "line %d: markportdb", __LINE__); \
+    isp_mark_portdb(a, b)
 
 /*
  * Local static data
  */
-static const char portshift[] =
-    "Target %d Loop ID 0x%x (Port 0x%x) => Loop 0x%x (Port 0x%x)";
-static const char portdup[] =
-    "Target %d duplicates Target %d- killing off both";
-static const char retained[] =
-    "Retaining Loop ID 0x%x for Target %d (Port 0x%x)";
-static const char lretained[] =
-    "Retained login of Target %d (Loop ID 0x%x) Port 0x%x";
-static const char plogout[] =
-    "Logging out Target %d at Loop ID 0x%x (Port 0x%x)";
-static const char plogierr[] =
-    "Command Error in PLOGI for Port 0x%x (0x%x)";
-static const char nopdb[] =
-    "Could not get PDB for Device @ Port 0x%x";
-static const char pdbmfail1[] =
-    "PDB Loop ID info for Device @ Port 0x%x does not match up (0x%x)";
-static const char pdbmfail2[] =
-    "PDB Port info for Device @ Port 0x%x does not match up (0x%x)";
-static const char ldumped[] =
-    "Target %d (Loop ID 0x%x) Port 0x%x dumped after login info mismatch";
+static const char fconf[] =
+    "PortDB[%d] changed:\n current =(0x%x at 0x%06x 0x%08x%08x 0x%08x%08x)\n"
+    " database=(0x%x at 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 xact1[] =
@@ -95,9 +82,9 @@
 static const char pskip[] =
     "SCSI phase skipped for target %d.%d.%d";
 static const char topology[] =
-    "Loop ID %d, Port ID 0x%x, Loop State 0x%x, Topology '%s'";
-static const char swrej[] =
-    "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
+    "HBA PortID 0x%06x N-Port Handle %d, Connection Topology '%s'";
+static const char ourwwn[] =
+    "HBA WWNN 0x%08x%08x HBA WWPN 0x%08x%08x";
 static const char finmsg[] =
     "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x";
 static const char sc0[] =
@@ -115,38 +102,51 @@
  */
 static int isp_parse_async(ispsoftc_t *, uint16_t);
 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *,
-    uint16_t *);
+    uint32_t *);
+static void
+isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *);
 static void
-isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *);
+isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
 static void isp_fastpost_complete(ispsoftc_t *, uint16_t);
 static int isp_mbox_continue(ispsoftc_t *);
 static void isp_scsi_init(ispsoftc_t *);
 static void isp_scsi_channel_init(ispsoftc_t *, int);
 static void isp_fibre_init(ispsoftc_t *);
-static void isp_mark_getpdb_all(ispsoftc_t *);
-static int isp_getmap(ispsoftc_t *, fcpos_map_t *);
-static int isp_getpdb(ispsoftc_t *, int, isp_pdb_t *);
+static void isp_fibre_init_2400(ispsoftc_t *);
+static void isp_mark_portdb(ispsoftc_t *, int);
+static int isp_plogx(ispsoftc_t *, uint16_t, uint32_t, int, int);
+static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
+static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
+static int isp_getpdb(ispsoftc_t *, uint16_t, isp_pdb_t *, int);
 static uint64_t isp_get_portname(ispsoftc_t *, int, int);
 static int isp_fclink_test(ispsoftc_t *, int);
-static const char *isp2100_fw_statename(int);
+static const char *ispfc_fw_statename(int);
 static int isp_pdb_sync(ispsoftc_t *);
 static int isp_scan_loop(ispsoftc_t *);
-static int isp_fabric_mbox_cmd(ispsoftc_t *, mbreg_t *);
-static int isp_scan_fabric(ispsoftc_t *, int);
-static void isp_register_fc4_type(ispsoftc_t *);
+static int isp_gid_ft_sns(ispsoftc_t *);
+static int isp_gid_ft_ct_passthru(ispsoftc_t *);
+static int isp_scan_fabric(ispsoftc_t *);
+static int isp_login_device(ispsoftc_t *, uint32_t, isp_pdb_t *, uint16_t *);
+static int isp_register_fc4_type(ispsoftc_t *);
+static int isp_register_fc4_type_24xx(ispsoftc_t *);
+static uint16_t isp_nxt_handle(ispsoftc_t *, uint16_t);
 static void isp_fw_state(ispsoftc_t *);
 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
-static void isp_mboxcmd(ispsoftc_t *, mbreg_t *, int);
+static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
 
 static void isp_update(ispsoftc_t *);
 static void isp_update_bus(ispsoftc_t *, int);
 static void isp_setdfltparm(ispsoftc_t *, int);
 static int isp_read_nvram(ispsoftc_t *);
+static int isp_read_nvram_2400(ispsoftc_t *);
 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
+static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
+static void isp_fix_nvram_wwns(ispsoftc_t *);
 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
+static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
 
 /*
  * Reset Hardware.
@@ -160,9 +160,10 @@
 isp_reset(ispsoftc_t *isp)
 {
 	mbreg_t mbs;
-	uint32_t code_org;
+	uint32_t code_org, val;
 	int loops, i, dodnld = 1;
-	char *btype = "????";
+	static const char *btype = "????";
+	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
 
 	isp->isp_state = ISP_NILSTATE;
 
@@ -202,10 +203,16 @@
 			/*
 			 * Just in case it was paused...
 			 */
-			ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
+			if (IS_24XX(isp)) {
+				ISP_WRITE(isp, BIU2400_HCCR,
+				    HCCR_2400_CMD_RELEASE);
+			} else {
+				ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
+			}
 			MEMZERO(&mbs, sizeof (mbs));
 			mbs.param[0] = MBOX_ABOUT_FIRMWARE;
-			isp_mboxcmd(isp, &mbs, MBLOGNONE);
+			mbs.logval = MBLOGNONE;
+			isp_mboxcmd(isp, &mbs);
 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
 				isp->isp_romfw_rev[0] = mbs.param[1];
 				isp->isp_romfw_rev[1] = mbs.param[2];
@@ -215,21 +222,51 @@
 		isp->isp_touched = 1;
 	}
 
-	DISABLE_INTS(isp);
+	ISP_DISABLE_INTS(isp);
+
+	/*
+	 * Pick an initial maxcmds value which will be used
+	 * to allocate xflist pointer space. It may be changed
+	 * later by the firmware.
+	 */
+	if (IS_24XX(isp)) {
+		isp->isp_maxcmds = 4096;
+	} else if (IS_2322(isp)) {
+		isp->isp_maxcmds = 2048;
+	} else if (IS_23XX(isp) || IS_2200(isp)) {
+		isp->isp_maxcmds = 1024;
+ 	} else {
+		isp->isp_maxcmds = 512;
+	}
+
+	/*
+	 * Set up DMA for the request and result queues.
+	 *
+	 * We do this now so we can use the request queue
+	 * for a dma
+	 */
+	if (ISP_MBOXDMASETUP(isp) != 0) {
+		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
+		return;
+	}
+
 
 	/*
 	 * Set up default request/response queue in-pointer/out-pointer
 	 * register indices.
 	 */
-	if (IS_23XX(isp)) {
+	if (IS_24XX(isp)) {
+		isp->isp_rqstinrp = BIU2400_REQINP;
+		isp->isp_rqstoutrp = BIU2400_REQOUTP;
+		isp->isp_respinrp = BIU2400_RSPINP;
+		isp->isp_respoutrp = BIU2400_RSPOUTP;
+		isp->isp_atioinrp = BIU2400_ATIO_RSPINP;
+		isp->isp_atiooutrp = BIU2400_ATIO_REQINP;
+	} else if (IS_23XX(isp)) {
 		isp->isp_rqstinrp = BIU_REQINP;
 		isp->isp_rqstoutrp = BIU_REQOUTP;
 		isp->isp_respinrp = BIU_RSPINP;
 		isp->isp_respoutrp = BIU_RSPOUTP;
-		ISP_WRITE(isp, isp->isp_rqstinrp, 0);
-        	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
-        	ISP_WRITE(isp, isp->isp_respinrp, 0);
-		ISP_WRITE(isp, isp->isp_respoutrp, 0);
 	} else {
 		isp->isp_rqstinrp = INMAILBOX4;
 		isp->isp_rqstoutrp = OUTMAILBOX4;
@@ -241,7 +278,13 @@
 	 * Put the board into PAUSE mode (so we can read the SXP registers
 	 * or write FPM/FBM registers).
 	 */
-	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+	if (IS_24XX(isp)) {
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
+	} else {
+		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+	}
 
 	if (IS_FC(isp)) {
 		switch (isp->isp_type) {
@@ -260,20 +303,24 @@
 		case ISP_HA_FC_2322:
 			btype = "2322";
 			break;
-		case ISP_HA_FC_2422:
+		case ISP_HA_FC_2400:
 			btype = "2422";
 			break;
 		default:
 			break;
 		}
-		/*
-		 * While we're paused, reset the FPM module and FBM fifos.
-		 */
-		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
-		ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
-		ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
-		ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
-		ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+
+		if (!IS_24XX(isp)) {
+			/*
+			 * While we're paused, reset the FPM module and FBM
+			 * fifos.
+			 */
+			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
+			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
+			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
+			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
+			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
+		}
 	} else if (IS_1240(isp)) {
 		sdparam *sdp = isp->isp_param;
 		btype = "1240";
@@ -443,8 +490,6 @@
 	 */
 	ISP_RESET0(isp);
 
-again:
-
 	/*
 	 * Hit the chip over the head with hammer,
 	 * and give the ISP a chance to recover.
@@ -466,6 +511,44 @@
 		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
 
 
+	} else if (IS_24XX(isp)) {
+		/*
+		 * Stop DMA and wait for it to stop.
+		 */
+		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
+		for (val = loops = 0; loops < 30000; loops++) {
+			USEC_DELAY(10);
+			val = ISP_READ(isp, BIU2400_CSR);
+			if ((val & BIU2400_DMA_ACTIVE) == 0) {
+				break;
+			}
+		} 
+		if (val & BIU2400_DMA_ACTIVE) {
+			ISP_RESET0(isp);
+			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
+			return;
+		}
+		/*
+		 * Hold it in SOFT_RESET and STOP state for 100us.
+		 */
+		ISP_WRITE(isp, BIU2400_CSR,
+		    BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
+		USEC_DELAY(100);
+		for (loops = 0; loops < 10000; loops++) {
+			USEC_DELAY(5);
+			val = ISP_READ(isp, OUTMAILBOX0);
+		}
+		for (val = loops = 0; loops < 500000; loops ++) {
+			val = ISP_READ(isp, BIU2400_CSR);
+			if ((val & BIU2400_SOFT_RESET) == 0) {
+				break;
+			}
+		}
+		if (val & BIU2400_SOFT_RESET) {
+			ISP_RESET0(isp);
+			isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
+			return;
+		}
 	} else {
 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
 		/*
@@ -490,8 +573,13 @@
 	loops = MBOX_DELAY_COUNT;
 	for (;;) {
 		if (IS_SCSI(isp)) {
-			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
+			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
+				break;
+			}
+		} else if (IS_24XX(isp)) {
+			if (ISP_READ(isp, OUTMAILBOX0) == 0) {
 				break;
+			}
 		} else {
 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
 				break;
@@ -499,6 +587,7 @@
 		USEC_DELAY(100);
 		if (--loops < 0) {
 			ISP_DUMPREGS(isp, "chip reset timed out");
+			ISP_RESET0(isp);
 			return;
 		}
 	}
@@ -510,24 +599,41 @@
 
 	if (IS_SCSI(isp)) {
 		ISP_WRITE(isp, BIU_CONF1, 0);
-	} else {
+	} else if (!IS_24XX(isp)) {
 		ISP_WRITE(isp, BIU2100_CSR, 0);
 	}
 
 	/*
 	 * Reset RISC Processor
 	 */
-	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
-	USEC_DELAY(100);
-	/* Clear semaphore register (just to be sure) */
-	ISP_WRITE(isp, BIU_SEMA, 0);
+	if (IS_24XX(isp)) {
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
+	} else {
+		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
+		USEC_DELAY(100);
+		ISP_WRITE(isp, BIU_SEMA, 0);
+	}
 
+	
 	/*
-	 * Establish some initial burst rate stuff.
-	 * (only for the 1XX0 boards). This really should
-	 * be done later after fetching from NVRAM.
+	 * Post-RISC Reset stuff.
 	 */
-	if (IS_SCSI(isp)) {
+	if (IS_24XX(isp)) {
+		for (val = loops = 0; loops < 5000000; loops++) {
+			USEC_DELAY(5);
+			val = ISP_READ(isp, OUTMAILBOX0);
+			if (val == 0) {
+				break;
+			}
+		}
+		if (val != 0) {
+			ISP_RESET0(isp);
+			isp_prt(isp, ISP_LOGERR, "reset didn't clear");
+			return;
+		}
+	} else if (IS_SCSI(isp)) {
 		uint16_t tmp = isp->isp_mdvec->dv_conf1;
 		/*
 		 * Busted FIFO. Turn off all but burst enables.
@@ -540,15 +646,36 @@
 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
 		}
-		ISP_WRITE(isp, RISC_MTR, 0x1212);
+		if (SDPARAM(isp)->isp_ptisp) {
+			if (SDPARAM(isp)->isp_ultramode) {
+				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
+					ISP_WRITE(isp, RISC_MTR, 0x1313);
+					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
+				}
+			} else {
+				ISP_WRITE(isp, RISC_MTR, 0x1212);
+			}
+			/*
+			 * PTI specific register
+			 */
+			ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
+		} else {
+			ISP_WRITE(isp, RISC_MTR, 0x1212);
+		}
+		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
 	} else {
 		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
 		if (IS_2200(isp) || IS_23XX(isp)) {
 			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
 		}
+		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
 	}
 
-	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
+	ISP_WRITE(isp, isp->isp_rqstinrp, 0);
+	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
+	ISP_WRITE(isp, isp->isp_respinrp, 0);
+	ISP_WRITE(isp, isp->isp_respoutrp, 0);
+
 
 	/*
 	 * Do MD specific post initialization
@@ -561,13 +688,14 @@
 	 * Avoid doing this on the 2312 because you can generate a PCI
 	 * parity error (chip breakage).
 	 */
-	if (IS_23XX(isp)) {
-		USEC_DELAY(5);
+	if (IS_2312(isp)) {
+		USEC_DELAY(100);
 	} else {
 		loops = MBOX_DELAY_COUNT;
 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
 			USEC_DELAY(100);
 			if (--loops < 0) {
+				ISP_RESET0(isp);
 				isp_prt(isp, ISP_LOGERR,
 				    "MBOX_BUSY never cleared on reset");
 				return;
@@ -586,12 +714,14 @@
 	 */
 	MEMZERO(&mbs, sizeof (mbs));
 	mbs.param[0] = MBOX_NO_OP;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
+	mbs.logval = MBLOGALL;
+	isp_mboxcmd(isp, &mbs);
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+		ISP_RESET0(isp);
 		return;
 	}
 
-	if (IS_SCSI(isp)) {
+	if (IS_SCSI(isp) || IS_24XX(isp)) {
 		MEMZERO(&mbs, sizeof (mbs));
 		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
 		mbs.param[1] = 0xdead;
@@ -599,13 +729,18 @@
 		mbs.param[3] = 0xffff;
 		mbs.param[4] = 0x1111;
 		mbs.param[5] = 0xa5a5;
-		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		mbs.param[6] = 0x0000;
+		mbs.param[7] = 0x0000;
+		mbs.logval = MBLOGALL;
+		isp_mboxcmd(isp, &mbs);
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			ISP_RESET0(isp);
 			return;
 		}
 		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
 		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
 		    mbs.param[5] != 0xa5a5) {
+			ISP_RESET0(isp);
 			isp_prt(isp, ISP_LOGERR,
 			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",
 			    mbs.param[1], mbs.param[2], mbs.param[3],
@@ -629,12 +764,173 @@
 		dodnld = 0;
 	}
 
-	if (IS_23XX(isp)) {
+	if (IS_24XX(isp)) {
+		code_org = ISP_CODE_ORG_2400;
+	} else if (IS_23XX(isp)) {
 		code_org = ISP_CODE_ORG_2300;
 	} else {
 		code_org = ISP_CODE_ORG;
 	}
-	if (dodnld) {
+
+	if (dodnld && IS_24XX(isp)) {
+		uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
+
+		/*
+		 * NB: Whatever you do do, do *not* issue the VERIFY FIRMWARE
+		 * NB: command to the 2400 while loading new firmware. This
+		 * NB: causes the new f/w to start and immediately crash back
+		 * NB: to the ROM.
+		 */
+
+		/*
+		 * Keep loading until we run out of f/w.
+		 */
+		code_org = ptr[2];	/* 1st load address is our start addr */
+
+		for (;;) {
+			uint32_t la, wi, wl;
+
+			isp_prt(isp, ISP_LOGDEBUG0,
+			    "load 0x%x words of code at load address 0x%x",
+			    ptr[3], ptr[2]);
+
+			wi = 0;
+			la = ptr[2];
+			wl = ptr[3];
+
+			while (wi < ptr[3]) {
+				uint32_t *cp;
+				uint32_t nw;
+
+				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
+				if (nw > wl) {
+					nw = wl;
+				}
+				cp = isp->isp_rquest;
+				for (i = 0; i < nw; i++) {
+					cp[i] = ptr[wi++];
+					wl--;
+				}
+				MEMORYBARRIER(isp, SYNC_REQUEST,
+				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+				MEMZERO(&mbs, sizeof (mbs));
+				mbs.param[0] = MBOX_LOAD_RISC_RAM;
+				mbs.param[1] = la;
+				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+				mbs.param[4] = nw >> 16;
+				mbs.param[5] = nw;
+				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+				mbs.param[8] = la >> 16;
+				mbs.logval = MBLOGALL;
+				isp_mboxcmd(isp, &mbs);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR,
+					    "F/W Risc Ram Load Failed");
+					ISP_RESET0(isp);
+					return;
+				}
+				la += nw;
+			}
+
+			if (ptr[1] == 0) {
+				break;
+			}
+			ptr += ptr[3];
+		} 
+		isp->isp_loaded_fw = 1;
+	} else if (dodnld && IS_23XX(isp)) {
+		uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
+		uint16_t wi, wl, segno;
+		uint32_t la;
+
+		la = code_org;
+		segno = 0;
+
+		for (;;) {
+			uint32_t nxtaddr;
+
+			isp_prt(isp, ISP_LOGDEBUG0,
+			    "load 0x%x words of code at load address 0x%x",
+			    ptr[3], la);
+
+			wi = 0;
+			wl = ptr[3];
+
+			while (wi < ptr[3]) {
+				uint16_t *cp;
+				uint32_t nw;
+				
+				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
+				if (nw > wl) {
+					nw = wl;
+				}
+				if (nw > (1 << 15)) {
+					nw = 1 << 15;
+				}
+				cp = isp->isp_rquest;
+				for (i = 0; i < nw; i++) {
+					cp[i] = ptr[wi++];
+					wl--;
+				}
+				MEMORYBARRIER(isp, SYNC_REQUEST,
+				    0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)));
+				MEMZERO(&mbs, sizeof (mbs));
+				mbs.param[0] = MBOX_LOAD_RISC_RAM;
+				mbs.param[1] = la;
+				mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
+				mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
+				mbs.param[4] = nw;
+				mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
+				mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
+				mbs.param[8] = la >> 16;
+				mbs.logval = MBLOGALL;
+				isp_mboxcmd(isp, &mbs);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR,
+					    "F/W Risc Ram Load Failed");
+					ISP_RESET0(isp);
+					return;
+				}
+				la += nw;
+			}
+
+			if (!IS_2322(isp)) {
+				/*
+				 * Verify that it downloaded correctly.
+				 */
+				MEMZERO(&mbs, sizeof (mbs));
+				mbs.param[0] = MBOX_VERIFY_CHECKSUM;
+				mbs.param[1] = code_org;
+				mbs.logval = MBLOGNONE;
+				isp_mboxcmd(isp, &mbs);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR, dcrc);
+					ISP_RESET0(isp);
+					return;
+				}
+				break;
+			}
+
+			if (++segno == 3) {
+				break;
+			}
+
+			/*
+			 * If we're a 2322, the firmware actually comes in
+			 * three chunks. We loaded the first at the code_org
+			 * address. The other two chunks, which follow right
+			 * after each other in memory here, get loaded at
+			 * addresses specfied at offset 0x9..0xB.
+			 */
+
+			nxtaddr = ptr[3];
+			ptr = &ptr[nxtaddr];
+			la = ptr[5] | ((ptr[4] & 0x3f) << 16);
+		}
+		isp->isp_loaded_fw = 1;
+	} else if (dodnld) {
 		uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
 
 		isp->isp_mbxworkp = &ptr[1];
@@ -644,76 +940,27 @@
 		mbs.param[0] = MBOX_WRITE_RAM_WORD;
 		mbs.param[1] = code_org;
 		mbs.param[2] = ptr[0];
-		isp_mboxcmd(isp, &mbs, MBLOGNONE);
+		mbs.logval = MBLOGNONE;
+		isp_mboxcmd(isp, &mbs);
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 			isp_prt(isp, ISP_LOGERR,
 			    "F/W download failed at word %d",
 			    isp->isp_mbxwrk1 - code_org);
-			dodnld = 0;
-			goto again;
+			ISP_RESET0(isp);
+			return;
 		}
-
 		/*
-		 * If we're a 2322, the firmware actually comes in three chunks.
-		 * We loaded the first at the code_org address. The other two
-		 * chunks, which follow right after each other in memory here,
-		 * get loaded at addresses specfied at offset 0x9..0xB.
+		 * Verify that it downloaded correctly.
 		 */
-		if (IS_2322(isp)) {
-			uint32_t nxtaddr;
-			uint32_t offset;
-
-			nxtaddr = ptr[3];
-			ptr = &ptr[nxtaddr];
-			offset = ptr[5] | (((uint32_t)(ptr[4] & 0x3f)) << 16);
-			isp->isp_mbxworkp = &ptr[1];
-			isp->isp_mbxwrk0 = ptr[3] - 1;
-			isp->isp_mbxwrk1 = offset + 1;
-			isp->isp_mbxwrk8 = (offset + 1) >> 16;
-			MEMZERO(&mbs, sizeof (mbs));
-			mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
-			mbs.param[1] = offset;
-			mbs.param[2] = ptr[0];
-			mbs.param[8] = offset >> 16;
-			isp_mboxcmd(isp, &mbs, MBLOGNONE);
-			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-				isp_prt(isp, ISP_LOGERR,
-				    "Receive Sequencer F/W Load Failed");
-				return;
-			}
-
-			nxtaddr = ptr[3];
-			ptr = &ptr[nxtaddr];
-			offset = ptr[5] | (((uint32_t)(ptr[4] & 0x3f)) << 16);
-			isp->isp_mbxworkp = &ptr[1];
-			isp->isp_mbxwrk0 = ptr[3] - 1;
-			isp->isp_mbxwrk1 = (offset + 1);
-			isp->isp_mbxwrk8 = (offset + 1) >> 16;
-			MEMZERO(&mbs, sizeof (mbs));
-			mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED;
-			mbs.param[1] = offset;
-			mbs.param[2] = ptr[0];
-			mbs.param[8] = offset >> 16;
-			isp_mboxcmd(isp, &mbs, MBLOGNONE);
-			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-				isp_prt(isp, ISP_LOGERR,
-				    "Transmit Sequencer F/W Load Failed");
-				return;
-			}
-		} else {
-			/*
-			 * Verify that it downloaded correctly.
-			 */
-			MEMZERO(&mbs, sizeof (mbs));
-			mbs.param[0] = MBOX_VERIFY_CHECKSUM;
-			mbs.param[1] = code_org;
-			isp_mboxcmd(isp, &mbs, MBLOGNONE);
-			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-				isp_prt(isp, ISP_LOGERR,
-				    "Downloaded RISC Code Checksum Failure");
-				return;
-			}
-
+		MEMZERO(&mbs, sizeof (mbs));
+		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
+		mbs.param[1] = code_org;
+		mbs.logval = MBLOGNONE;
+		isp_mboxcmd(isp, &mbs);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			isp_prt(isp, ISP_LOGERR, dcrc);
+			ISP_RESET0(isp);
+			return;
 		}
 		isp->isp_loaded_fw = 1;
 	} else {
@@ -730,28 +977,40 @@
 
 
 	MEMZERO(&mbs, sizeof (mbs));
+	mbs.timeout = 1000000;
 	mbs.param[0] = MBOX_EXEC_FIRMWARE;
-	mbs.param[1] = code_org;
-	if (IS_2322(isp) || IS_24XX(isp)) {
+	if (IS_24XX(isp)) {
+		mbs.param[1] = code_org >> 16;
+		mbs.param[2] = code_org;
+		if (isp->isp_loaded_fw) {
+			mbs.param[3] = 0;
+		} else {
+			mbs.param[3] = 1;
+		}
+	} else if (IS_2322(isp)) {
+		mbs.param[1] = code_org;
 		if (isp->isp_loaded_fw) {
 			mbs.param[2] = 0;
 		} else {
 			mbs.param[2] = 1;
 		}
+	} else {
+		mbs.param[1] = code_org;
 	}
-	isp_mboxcmd(isp, &mbs, MBLOGNONE);
+
+	mbs.logval = MBLOGALL;
+	isp_mboxcmd(isp, &mbs);
 	if (IS_2322(isp) || IS_24XX(isp)) {
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-			isp_prt(isp, ISP_LOGERR, "EXEC F/W failed: 0x%x",
-			    mbs.param[0]);
+			ISP_RESET0(isp);
 			return;
 		}
 	}
 
 	/*
-	 * Give it a chance to start.
+	 * Give it a chance to finish starting up.
 	 */
-	USEC_DELAY(500);
+	USEC_DELAY(250000);
 
 	if (IS_SCSI(isp)) {
 		/*
@@ -760,15 +1019,24 @@
 		if (isp->isp_clock) {
 			mbs.param[0] = MBOX_SET_CLOCK_RATE;
 			mbs.param[1] = isp->isp_clock;
-			isp_mboxcmd(isp, &mbs, MBLOGALL);
+			mbs.logval = MBLOGNONE;
+			isp_mboxcmd(isp, &mbs);
 			/* we will try not to care if this fails */
 		}
 	}
 
 	MEMZERO(&mbs, sizeof (mbs));
 	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
+	mbs.logval = MBLOGALL;
+	isp_mboxcmd(isp, &mbs);
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+		ISP_RESET0(isp);
+		return;
+	}
+
+	if (IS_24XX(isp) && mbs.param[1] == 0xdead) {
+		isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
+		ISP_RESET0(isp);
 		return;
 	}
 
@@ -794,7 +1062,7 @@
 		isp->isp_fwrev[2] = mbs.param[3];
 	}
 
-	isp_prt(isp, ISP_LOGCONFIG,
+	isp_prt(isp, ISP_LOGALL,
 	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
 	    btype, isp->isp_revision, dodnld? "loaded" : "resident",
 	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
@@ -805,9 +1073,9 @@
 		 * than 1.17.0, unless it's the firmware we specifically
 		 * are loading.
 		 *
-		 * Note that all 22XX and 23XX f/w is greater than 1.X.0.
+		 * Note that all 22XX and later f/w is greater than 1.X.0.
 		 */
-		if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) {
+		if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
 #ifdef	USE_SMALLER_2100_FIRMWARE
 			FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN;
 #else
@@ -818,7 +1086,26 @@
 			isp_prt(isp, ISP_LOGDEBUG0,
 			    "Firmware Attributes = 0x%x", mbs.param[6]);
 		}
-		if (IS_2KLOGIN(isp)) {
+		FCPARAM(isp)->isp_2klogin = 0;
+		FCPARAM(isp)->isp_sccfw = 0;
+		FCPARAM(isp)->isp_tmode = 0;
+		if (IS_24XX(isp)) {
+			FCPARAM(isp)->isp_2klogin = 1;
+			FCPARAM(isp)->isp_sccfw = 1;
+			FCPARAM(isp)->isp_tmode = 1;
+		} else {
+			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+				FCPARAM(isp)->isp_sccfw = 1;
+			}
+			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_2KLOGINS) {
+				FCPARAM(isp)->isp_2klogin = 1;
+				FCPARAM(isp)->isp_sccfw = 1;
+			}
+			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_TMODE) {
+				FCPARAM(isp)->isp_tmode = 1;
+			}
+		}
+		if (FCPARAM(isp)->isp_2klogin) {
 			isp_prt(isp, ISP_LOGCONFIG, "2K Logins Supported");
 		}
 	}
@@ -830,24 +1117,23 @@
 		    isp->isp_romfw_rev[2]);
 	}
 
-	MEMZERO(&mbs, sizeof (mbs));
-	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
-	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
-		return;
+	if (!IS_24XX(isp)) {
+		MEMZERO(&mbs, sizeof (mbs));
+		mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
+		mbs.logval = MBLOGALL;
+		isp_mboxcmd(isp, &mbs);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			ISP_RESET0(isp);
+			return;
+		}
+		if (isp->isp_maxcmds >= mbs.param[2]) {
+			isp->isp_maxcmds = mbs.param[2];
+		}
 	}
-	isp->isp_maxcmds = mbs.param[2];
-	isp_prt(isp, ISP_LOGINFO,
-	    "%d max I/O commands supported", mbs.param[2]);
+	isp_prt(isp, ISP_LOGCONFIG,
+	    "%d max I/O command limit set", isp->isp_maxcmds);
 	isp_fw_state(isp);
 
-	/*
-	 * Set up DMA for the request and result mailboxes.
-	 */
-	if (ISP_MBOXDMASETUP(isp) != 0) {
-		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
-		return;
-	}
 	isp->isp_state = ISP_RESETSTATE;
 
 	/*
@@ -878,7 +1164,7 @@
 			isp->isp_maxluns = 8;
 		}
 	} else {
-		if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {
+		if (FCPARAM(isp)->isp_sccfw) {
 			isp->isp_maxluns = 16384;
 		} else {
 			isp->isp_maxluns = 16;
@@ -902,8 +1188,22 @@
 	if (IS_DUALBUS(isp)) {
 		isp_setdfltparm(isp, 1);
 	}
+
 	if (IS_FC(isp)) {
-		isp_fibre_init(isp);
+		/*
+		 * Do this *before* initializing the firmware.
+		 */
+		ISP_MARK_PORTDB(isp, 0);
+		FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
+		FCPARAM(isp)->isp_loopstate = LOOP_NIL;
+
+		if (isp->isp_role != ISP_ROLE_NONE) {
+			if (IS_24XX(isp)) {
+				isp_fibre_init_2400(isp);
+			} else {
+				isp_fibre_init(isp);
+			}
+		}
 	} else {
 		isp_scsi_init(isp);
 	}
@@ -947,8 +1247,8 @@
 	mbs.param[2] = sdp_chan0->isp_retry_delay;
 	mbs.param[6] = sdp_chan1->isp_retry_count;
 	mbs.param[7] = sdp_chan1->isp_retry_delay;
-
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
+	mbs.logval = MBLOGALL;
+	isp_mboxcmd(isp, &mbs);
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 		return;
 	}
@@ -960,7 +1260,8 @@
 	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
 	mbs.param[1] = sdp_chan0->isp_async_data_setup;
 	mbs.param[2] = sdp_chan1->isp_async_data_setup;
-	isp_mboxcmd(isp, &mbs, MBLOGALL);
+	mbs.logval = MBLOGALL;
+	isp_mboxcmd(isp, &mbs);
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 		return;

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list