PERFORCE change 105125 for review

Matt Jacob mjacob at FreeBSD.org
Sat Aug 26 19:09:27 UTC 2006


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

Change 105125 by mjacob at newisp on 2006/08/26 18:37:07

	Synchronize tree with current private tree.

Affected files ...

.. //depot/projects/newisp/dev/isp/isp.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_freebsd.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_freebsd.h#2 edit
.. //depot/projects/newisp/dev/isp/isp_library.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_library.h#2 edit
.. //depot/projects/newisp/dev/isp/isp_pci.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_sbus.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_target.c#2 edit
.. //depot/projects/newisp/dev/isp/isp_target.h#2 edit
.. //depot/projects/newisp/dev/isp/ispmbox.h#2 edit
.. //depot/projects/newisp/dev/isp/ispreg.h#2 edit
.. //depot/projects/newisp/dev/isp/ispvar.h#2 edit

Differences ...

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

@@ -64,26 +64,12 @@
 /*
  * 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] confusion: 0x%x,0x%x 0x%x,0x%x, 0x%08x%08x/0x%08x%08x, "
+    "0x%08x%08x/0x%08x%08x";
+static const char dbe[] =
+    "% 4d: state %d al %d tgt %d role 0x%x PortID 0x%06x nr %x np 0x%06x "
+    "WWNN 0x%08x%08x WWPN 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,7 +81,8 @@
 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'";
+    "Our PortID 0x%06x N-Port Handle %d, Connection Topology '%s'\n"
+    "      WWNN 0x%08x%08x WWPN 0x%08x%08x";
 static const char swrej[] =
     "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x";
 static const char finmsg[] =
@@ -115,24 +102,31 @@
  */
 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 *);
+static void
+isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *);
 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 void isp_fibre_init_2400(ispsoftc_t *);
+static void isp_dump_portdb(ispsoftc_t *);
+static void isp_mark_portdb(ispsoftc_t *, int);
 static int isp_getmap(ispsoftc_t *, fcpos_map_t *);
-static int isp_getpdb(ispsoftc_t *, int, isp_pdb_t *);
+static void isp_plogx_24xx(ispsoftc_t *, uint16_t, uint32_t, int *);
+static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
+static void 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 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 int isp_gid_ft_sns(ispsoftc_t *);
+static int isp_scan_fabric(ispsoftc_t *);
 static void isp_register_fc4_type(ispsoftc_t *);
 static void isp_fw_state(ispsoftc_t *);
 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
@@ -142,11 +136,15 @@
 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 +158,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,7 +201,12 @@
 			/*
 			 * 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);
@@ -218,18 +222,46 @@
 	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;
+	} 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 +273,11 @@
 	 * 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_CMD_PAUSE);
+	} else {
+		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
+	}
 
 	if (IS_FC(isp)) {
 		switch (isp->isp_type) {
@@ -260,20 +296,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 +483,6 @@
 	 */
 	ISP_RESET0(isp);
 
-again:
-
 	/*
 	 * Hit the chip over the head with hammer,
 	 * and give the ISP a chance to recover.
@@ -466,6 +504,42 @@
 		    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_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_prt(isp, ISP_LOGERR, "Failed to come out of reset");
+			return;
+		}
 	} else {
 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
 		/*
@@ -490,8 +564,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;
@@ -510,24 +589,44 @@
 
 	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);
+		val = ISP_READ(isp, BIU2400_HCCR);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
+		val = ISP_READ(isp, BIU2400_HCCR);
+		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
+		val = ISP_READ(isp, BIU2400_HCCR);
+	} else {
+		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
+		USEC_DELAY(100);
+		/* Clear semaphore register (just to be sure) */
+		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_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.
@@ -541,14 +640,20 @@
 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
 		}
 		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,8 +666,8 @@
 	 * 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) {
@@ -591,7 +696,7 @@
 		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,6 +704,8 @@
 		mbs.param[3] = 0xffff;
 		mbs.param[4] = 0x1111;
 		mbs.param[5] = 0xa5a5;
+		mbs.param[6] = 0x0000;
+		mbs.param[7] = 0x0000;
 		isp_mboxcmd(isp, &mbs, MBLOGALL);
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 			return;
@@ -629,12 +736,167 @@
 		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;
+				isp_mboxcmd(isp, &mbs, MBLOGALL);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR,
+					    "F/W Risc Ram Load Failed");
+					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;
+				isp_mboxcmd(isp, &mbs, MBLOGALL);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR,
+					    "F/W Risc Ram Load Failed");
+					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;
+				isp_mboxcmd(isp, &mbs, MBLOGNONE);
+				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+					isp_prt(isp, ISP_LOGERR, dcrc);
+					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];
@@ -649,71 +911,18 @@
 			isp_prt(isp, ISP_LOGERR,
 			    "F/W download failed at word %d",
 			    isp->isp_mbxwrk1 - code_org);
-			dodnld = 0;
-			goto again;
+			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] & 0xff)) << 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] & 0xff)) << 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;
+		isp_mboxcmd(isp, &mbs, MBLOGNONE);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			isp_prt(isp, ISP_LOGERR, dcrc);
+			return;
 		}
 		isp->isp_loaded_fw = 1;
 	} else {
@@ -731,14 +940,25 @@
 
 	MEMZERO(&mbs, sizeof (mbs));
 	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);
 	if (IS_2322(isp) || IS_24XX(isp)) {
 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
@@ -749,7 +969,7 @@
 	}
 
 	/*
-	 * Give it a chance to start.
+	 * Give it a chance to start
 	 */
 	USEC_DELAY(500);
 
@@ -772,6 +992,11 @@
 		return;
 	}
 
+	if (IS_24XX(isp) && mbs.param[1] == 0xdead) {
+		isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
+		return;
+	}
+
 	/*
 	 * The SBus firmware that we are using apparently does not return
 	 * major, minor, micro revisions in the mailbox registers, which
@@ -805,9 +1030,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 +1043,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 +1074,21 @@
 		    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;
+		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			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 +1119,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;
@@ -903,7 +1144,20 @@
 		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);
 	}
@@ -1237,8 +1491,6 @@
 
 /*
  * Fibre Channel specific initialization.
- *
- * Locks are held before coming here.
  */
 static void
 isp_fibre_init(ispsoftc_t *isp)
@@ -1246,26 +1498,10 @@
 	fcparam *fcp;
 	isp_icb_t local, *icbp = &local;
 	mbreg_t mbs;
-	int loopid;
 	uint64_t nwwn, pwwn;
 
 	fcp = isp->isp_param;
 
-	/*
-	 * Do this *before* initializing the firmware.
-	 */
-	isp_mark_getpdb_all(isp);
-	fcp->isp_fwstate = FW_CONFIG_WAIT;
-	fcp->isp_loopstate = LOOP_NIL;
-
-	/*
-	 * If we have no role (neither target nor initiator), return.
-	 */
-	if (isp->isp_role == ISP_ROLE_NONE) {
-		return;
-	}
-
-	loopid = fcp->isp_loopid;
 	MEMZERO(icbp, sizeof (*icbp));
 	icbp->icb_version = ICB_VERSION1;
 
@@ -1280,6 +1516,9 @@
 	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
 	 */
 	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
 	}
 
@@ -1289,26 +1528,47 @@
 	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
 	 */
 	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
 	}
 
 	/*
 	 * Insist on Port Database Update Async notifications
 	 */
+	/*
+	 * XXX: This should be applied to icb- not fwoptions
+	 */
 	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
 
 	/*
 	 * Make sure that target role reflects into fwoptions.
 	 */
 	if (isp->isp_role & ISP_ROLE_TARGET) {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
 	} else {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
 	}
 
 	if (isp->isp_role & ISP_ROLE_INITIATOR) {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions &= ~ICBOPT_INI_DISABLE;
 	} else {
+		/*
+		 * XXX: This should be applied to icb- not fwoptions
+		 */
 		fcp->isp_fwoptions |= ICBOPT_INI_DISABLE;
 	}
 
@@ -1339,7 +1599,7 @@
 	}
 	icbp->icb_retry_delay = fcp->isp_retry_delay;
 	icbp->icb_retry_count = fcp->isp_retry_count;
-	icbp->icb_hardaddr = loopid;
+	icbp->icb_hardaddr = fcp->isp_loopid;
 	if (icbp->icb_hardaddr > 125) {
 		/*
 		 * We end up with these Loop IDs for F-Port topologies
@@ -1435,6 +1695,9 @@
 		mbs.param[2] = 0;
 		mbs.param[3] = 0;
 		isp_mboxcmd(isp, &mbs, MBLOGALL);
+		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+			return;
+		}
 	}
 	icbp->icb_logintime = ICB_LOGIN_TOV;
 	icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
@@ -1472,6 +1735,9 @@
 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
 
+	icbp->icb_rqstout = 0;
+	icbp->icb_rspnsin = 0;
+
 	isp_prt(isp, ISP_LOGDEBUG0,
 	    "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
 	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
@@ -1497,9 +1763,240 @@
 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
 		return;
 	}
-	isp->isp_reqidx = isp->isp_reqodx = 0;
+	isp->isp_reqidx = 0;
+	isp->isp_reqodx = 0;
+	isp->isp_residx = 0;
+
+	/*
+	 * Whatever happens, we're now committed to being here.
+	 */
+	isp->isp_state = ISP_INITSTATE;
+}
+
+static void
+isp_fibre_init_2400(ispsoftc_t *isp)
+{
+	fcparam *fcp;
+	isp_icb_2400_t local, *icbp = &local;
+	mbreg_t mbs;
+	uint64_t nwwn, pwwn;
+
+	fcp = isp->isp_param;
+
+	/*
+	 * Turn on LIP F8 async event (1)
+	 */
+	MEMZERO(&mbs, sizeof (mbs));
+	mbs.param[0] = MBOX_SET_FIRMWARE_OPTIONS;
+	mbs.param[1] = 1;
+	mbs.param[2] = 0;
+	mbs.param[3] = 0;
+	isp_mboxcmd(isp, &mbs, MBLOGALL);
+	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
+		return;
+	}
+
+	/*
+	 * XXX: This should be applied to icb- not fwoptions
+	 */
+	if (isp->isp_role & ISP_ROLE_TARGET) {
+		fcp->isp_fwoptions |= ICB2400_OPT1_TGT_ENABLE;
+	} else {
+		fcp->isp_fwoptions &= ~ICB2400_OPT1_TGT_ENABLE;
+	}
+
+	if (isp->isp_role & ISP_ROLE_INITIATOR) {
+		fcp->isp_fwoptions &= ~ICB2400_OPT1_INI_DISABLE;
+	} else {
+		fcp->isp_fwoptions |= ICB2400_OPT1_INI_DISABLE;
+	}

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


More information about the p4-projects mailing list