Date: Sat, 26 Aug 2006 18:37:15 GMT From: Matt Jacob <mjacob@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 105125 for review Message-ID: <200608261837.k7QIbFO9099082@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=105125 Change 105125 by mjacob@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608261837.k7QIbFO9099082>