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