diff options
| author | Matt Jacob <mjacob@FreeBSD.org> | 2006-07-03 08:24:09 +0000 |
|---|---|---|
| committer | Matt Jacob <mjacob@FreeBSD.org> | 2006-07-03 08:24:09 +0000 |
| commit | 8a97c03a7a480077305129a8e1c0fcf004c28f92 (patch) | |
| tree | 58604d0a86cb16b7926e21a19d97952de8549f42 /sys | |
| parent | fb372900796f639bf269bf44651ef67f0eb17095 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/isp/isp.c | 351 | ||||
| -rw-r--r-- | sys/dev/isp/isp_pci.c | 24 | ||||
| -rw-r--r-- | sys/dev/isp/ispmbox.h | 4 | ||||
| -rw-r--r-- | sys/dev/isp/ispreg.h | 25 | ||||
| -rw-r--r-- | sys/dev/isp/ispvar.h | 18 |
5 files changed, 280 insertions, 142 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 8fcb134e57f51..99c52db1bb67e 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -100,7 +100,7 @@ static const char topology[] = static const char swrej[] = "Fabric Nameserver rejected %s (Reason=0x%x Expl=0x%x) for Port ID 0x%x"; static const char finmsg[] = - "(%d.%d.%d): FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; + "%d.%d.%d: FIN dl%d resid %d STS 0x%x SKEY %c XS_ERR=0x%x"; static const char sc0[] = "%s CHAN %d FTHRSH %d IID %d RESETD %d RETRYC %d RETRYD %d ASD 0x%x"; static const char sc1[] = @@ -129,7 +129,7 @@ static int isp_getmap(ispsoftc_t *, fcpos_map_t *); static int isp_getpdb(ispsoftc_t *, int, isp_pdb_t *); static uint64_t isp_get_portname(ispsoftc_t *, int, int); static int isp_fclink_test(ispsoftc_t *, int); -static char *isp2100_fw_statename(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 *); @@ -639,18 +639,20 @@ again: dodnld = 0; } - if (IS_23XX(isp)) + if (IS_23XX(isp)) { code_org = ISP_CODE_ORG_2300; - else + } else { code_org = ISP_CODE_ORG; - + } if (dodnld) { - isp->isp_mbxworkp = (void *) &isp->isp_mdvec->dv_ispfw[1]; - isp->isp_mbxwrk0 = isp->isp_mdvec->dv_ispfw[3] - 1; + uint16_t *ptr = isp->isp_mdvec->dv_ispfw; + + isp->isp_mbxworkp = &ptr[1]; + isp->isp_mbxwrk0 = ptr[3] - 1; isp->isp_mbxwrk1 = code_org + 1; mbs.param[0] = MBOX_WRITE_RAM_WORD; mbs.param[1] = code_org; - mbs.param[2] = isp->isp_mdvec->dv_ispfw[0]; + mbs.param[2] = ptr[0]; isp_mboxcmd(isp, &mbs, MBLOGNONE); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGERR, @@ -659,6 +661,7 @@ again: dodnld = 0; goto again; } + /* * Verify that it downloaded correctly. */ @@ -669,6 +672,49 @@ again: isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure"); return; } + + /* + * If we're a 2322 or 2422, 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. + */ + if (IS_2322(isp)) { + + ptr = &ptr[ptr[3]]; + isp->isp_mbxworkp = &ptr[1]; + isp->isp_mbxwrk0 = ptr[3] - 1; + isp->isp_mbxwrk1 = ptr[5] + 1; + isp->isp_mbxwrk8 = ptr[4]; + mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED; + mbs.param[8] = ptr[4]; + mbs.param[1] = ptr[5]; + mbs.param[2] = ptr[0]; + isp_mboxcmd(isp, &mbs, MBLOGNONE); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "Receive Sequencer F/W Load Failed"); + return; + } + + ptr = &ptr[ptr[3]]; + isp->isp_mbxworkp = &ptr[1]; + isp->isp_mbxwrk0 = ptr[3] - 1; + isp->isp_mbxwrk1 = ptr[5] + 1; + isp->isp_mbxwrk8 = ptr[4]; + mbs.param[0] = MBOX_WRITE_RAM_WORD_EXTENDED; + mbs.param[8] = ptr[4]; + mbs.param[1] = ptr[5]; + mbs.param[2] = ptr[0]; + isp_mboxcmd(isp, &mbs, MBLOGNONE); + if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + isp_prt(isp, ISP_LOGERR, + "Transmit Sequencer F/W Load Failed"); + return; + } + } + isp->isp_loaded_fw = 1; } else { isp->isp_loaded_fw = 0; @@ -687,9 +733,9 @@ again: mbs.param[1] = code_org; if (IS_2322(isp) || IS_24XX(isp)) { if (isp->isp_loaded_fw) { - mbs.param[2] = 1; - } else { mbs.param[2] = 0; + } else { + mbs.param[2] = 1; } mbs.obits |= 2; } @@ -1032,11 +1078,9 @@ isp_scsi_init(ispsoftc_t *isp) if (IS_ULTRA2(isp) || IS_1240(isp)) mbs.param[1] |= FW_FEATURE_RIO_16BIT; #else -#ifndef ISP_NO_FASTPOST if (IS_ULTRA2(isp) || IS_1240(isp)) mbs.param[1] |= FW_FEATURE_FAST_POST; #endif -#endif if (mbs.param[1] != 0) { uint16_t sfeat = mbs.param[1]; isp_mboxcmd(isp, &mbs, MBLOGALL); @@ -1273,7 +1317,7 @@ isp_fibre_init(ispsoftc_t *isp) icbp->icb_retry_delay = fcp->isp_retry_delay; icbp->icb_retry_count = fcp->isp_retry_count; icbp->icb_hardaddr = loopid; - if (icbp->icb_hardaddr >= 125) { + if (icbp->icb_hardaddr > 125) { /* * We end up with these Loop IDs for F-Port topologies */ @@ -1284,6 +1328,11 @@ isp_fibre_init(ispsoftc_t *isp) } icbp->icb_hardaddr = 0; } + + if (IS_2322(isp) || IS_24XX(isp)) { + icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS; + } + /* * Right now we just set extended options to prefer point-to-point * over loop based upon some soft config options. @@ -1309,38 +1358,26 @@ isp_fibre_init(ispsoftc_t *isp) icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP; break; } - if (IS_23XX(isp)) { + if (IS_2200(isp)) { + if (ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { + icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; + icbp->icb_racctimer = 4; + icbp->icb_idelaytimer = 8; + } + icbp->icb_fwoptions |= ICBOPT_FAST_POST; + } else { /* * QLogic recommends that FAST Posting be turned * off for 23XX cards and instead allow the HBA * to write response queue entries and interrupt * after a delay (ZIO). - * - * If we set ZIO, it will disable fast posting, - * so we don't need to clear it in fwoptions. - * - * Depending on the role we're selecting, we - * chose fast posting or not as it still is - * a win for target mode. */ -#ifndef ISP_NO_ZIO - if (isp->isp_role == ISP_ROLE_TARGET) { - icbp->icb_fwoptions |= ICBOPT_FAST_POST; - } else { + icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; + if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == + ICBXOPT_ZIO) { icbp->icb_xfwoptions |= ICBXOPT_ZIO; + icbp->icb_idelaytimer = 10; } -#else - icbp->icb_fwoptions |= ICBOPT_FAST_POST; -#endif -#if 0 - /* - * Values, in 100us increments. The default - * is 2 (200us) if a value 0 (default) is - * selected. - */ - icbp->icb_idelaytimer = 2; -#endif - if (isp->isp_confopts & ISP_CFG_ONEGB) { icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB; } else if (isp->isp_confopts & ISP_CFG_TWOGB) { @@ -1348,30 +1385,12 @@ isp_fibre_init(ispsoftc_t *isp) } else { icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO; } + if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) { + icbp->icb_zfwoptions |= ICBZOPT_50_OHM; + } } } -#ifndef ISP_NO_RIO_FC - /* - * RIO seems to be enabled in 2100s for fw >= 1.17.0. - * - * I've had some questionable problems with RIO on 2200. - * More specifically, on a 2204 I had problems with RIO - * on a Linux system where I was dropping commands right - * and left. It's not clear to me what the actual problem - * was. - * - * 23XX Cards do not support RIO. Instead they support ZIO. - */ -#if 0 - if (!IS_23XX(isp) && ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { - icbp->icb_xfwoptions |= ICBXOPT_RIO_16BIT; - icbp->icb_racctimer = 4; - icbp->icb_idelaytimer = 8; - } -#endif -#endif - MEMZERO(&mbs, sizeof (mbs)); /* @@ -1432,6 +1451,7 @@ isp_fibre_init(ispsoftc_t *isp) icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma); icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma); icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma); + 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); @@ -1560,18 +1580,20 @@ isp_get_portname(ispsoftc_t *isp, int loopid, int nodename) mbs.param[0] = MBOX_GET_PORT_NAME; if (IS_2KLOGIN(isp)) { mbs.param[1] = loopid; - if (nodename) - mbs.param[10] = 1; mbs.obits |= (1 << 10); + if (nodename) { + mbs.param[10] = 1; + } } else { mbs.param[1] = loopid << 8; - if (nodename) + if (nodename) { mbs.param[1] |= 1; + } } isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { wwn = - (((uint64_t)(mbs.param[2] & 0xff)) << 56) | + (((uint64_t)(mbs.param[2] & 0xff)) << 56) | (((uint64_t)(mbs.param[2] >> 8)) << 48) | (((uint64_t)(mbs.param[3] & 0xff)) << 40) | (((uint64_t)(mbs.param[3] >> 8)) << 32) | @@ -1606,6 +1628,8 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay) fcp = isp->isp_param; + isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Entry"); + /* * XXX: Here is where we would start a 'loop dead' timeout */ @@ -1689,7 +1713,11 @@ isp_fclink_test(ispsoftc_t *isp, int usdelay) if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return (-1); } - fcp->isp_loopid = mbs.param[1]; + if (IS_2KLOGIN(isp)) { + fcp->isp_loopid = mbs.param[1]; + } else { + fcp->isp_loopid = mbs.param[1] & 0xff; + } if (fcp->isp_loopid == 0xffff) { /* happens with 2k login f/w */ fcp->isp_loopid = MAX_FC_TARG-1; } else if (fcp->isp_loopid >= MAX_FC_TARG) { @@ -1840,10 +1868,11 @@ not_on_fabric: lp->loggedin = lp->valid = 1; count = fcp->isp_iid; (void) isp_async(isp, ISPASYNC_PROMENADE, &count); + isp_prt(isp, ISP_LOGDEBUG0, "FC Link Test Complete"); return (0); } -static char * +static const char * isp2100_fw_statename(int state) { switch(state) { @@ -2209,11 +2238,15 @@ isp_scan_loop(ispsoftc_t *isp) hival = FC_PORT_ID; break; default: + isp_prt(isp, ISP_LOGDEBUG0, "no loop scasn\n"); fcp->isp_loopstate = LOOP_LSCAN_DONE; return (0); } fcp->isp_loopstate = LOOP_SCANNING_LOOP; + isp_prt(isp, ISP_LOGDEBUG0, "scanning local loop 0..%d", hival); + + /* * make sure the temp port database is clean... */ @@ -2233,30 +2266,30 @@ isp_scan_loop(ispsoftc_t *isp) /* * Don't even try for ourselves... */ - if (loopid == fcp->isp_loopid) + if (loopid == fcp->isp_loopid) { continue; + } - lp->node_wwn = isp_get_portname(isp, loopid, 1); - if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) - return (-1); - if (lp->node_wwn == 0) - continue; - lp->port_wwn = isp_get_portname(isp, loopid, 0); - if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) - return (-1); - if (lp->port_wwn == 0) { - lp->node_wwn = 0; - continue; + if (IS_2100(isp) || IS_2200(isp)) { + lp->node_wwn = isp_get_portname(isp, loopid, 1); + if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { + return (-1); + } + if (lp->node_wwn == 0) { + continue; + } } /* * Get an entry.... */ if (isp_getpdb(isp, loopid, &pdb) != 0) { - if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) + if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { return (-1); + } continue; } + if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) { return (-1); } @@ -2523,6 +2556,8 @@ isp_scan_fabric(ispsoftc_t *isp, int ftype) return (0); } + isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GA_NXT)"); + FC_SCRATCH_ACQUIRE(isp); /* @@ -2689,6 +2724,8 @@ isp_scan_fabric(ispsoftc_t *isp, int ftype) return (0); } + isp_prt(isp, ISP_LOGDEBUG0, "scanning fabric (GID_FT)"); + FC_SCRATCH_ACQUIRE(isp); fcp->isp_loopstate = LOOP_SCANNING_FABRIC; @@ -3425,11 +3462,13 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg) if (IS_SCSI(isp)) { mbs.param[1] = ((sdparam *) isp->isp_param)->isp_bus_reset_delay; - if (mbs.param[1] < 2) + if (mbs.param[1] < 2) { mbs.param[1] = 2; + } bus = *((int *) arg); - if (IS_DUALBUS(isp)) + if (IS_DUALBUS(isp)) { mbs.param[2] = bus; + } } else { mbs.param[1] = 10; bus = 0; @@ -3549,6 +3588,9 @@ isp_control(ispsoftc_t *isp, ispctl_t ctl, void *arg) if (IS_FC(isp)) { mbs.param[0] = MBOX_INIT_LIP; + if (IS_2KLOGIN(isp)) { + mbs.obits |= (1 << 10); + } isp_mboxcmd(isp, &mbs, MBLOGALL); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { return (0); @@ -3966,8 +4008,9 @@ again: } } isp_prt(isp, ISP_LOGDEBUG2, - "asked for %ld got resid %ld", (long) XS_XFRLEN(xs), - (long) sp->req_resid); + "asked for %ld got raw resid %ld settled for %ld", + (long) XS_XFRLEN(xs), (long) sp->req_resid, + (long) XS_RESID(xs)); break; case RQSTYPE_REQUEST: if (sp->req_header.rqs_flags & RQSFLAG_FULL) { @@ -4085,6 +4128,20 @@ isp_parse_async(ispsoftc_t *isp, uint16_t mbox) isp_async(isp, ISPASYNC_BUS_RESET, &bus); break; case ASYNC_SYSTEM_ERROR: + isp->isp_state = ISP_CRASHED; + if (IS_FC(isp)) { + FCPARAM(isp)->isp_loopstate = LOOP_NIL; + FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT; + } + /* + * Were we waiting for a mailbox command to complete? + * If so, it's dead, so wake up the waiter. + */ + if (isp->isp_mboxbsy) { + isp->isp_obits = 1; + isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR; + MBOX_NOTIFY_COMPLETE(isp); + } #ifdef ISP_FW_CRASH_DUMP /* * If we have crash dumps enabled, it's up to the handler @@ -4810,6 +4867,9 @@ isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs) mbreg_t mbs; MEMZERO(&mbs, sizeof (mbs)); mbs.param[0] = MBOX_INIT_LIP; + if (IS_2KLOGIN(isp)) { + mbs.obits |= (1 << 10); + } isp_mboxcmd_qnw(isp, &mbs, 1); } @@ -4893,6 +4953,7 @@ isp_mbox_continue(ispsoftc_t *isp) switch (isp->isp_lastmbxcmd) { case MBOX_WRITE_RAM_WORD: case MBOX_READ_RAM_WORD: + case MBOX_WRITE_RAM_WORD_EXTENDED: case MBOX_READ_RAM_WORD_EXTENDED: break; default: @@ -4919,10 +4980,25 @@ isp_mbox_continue(ispsoftc_t *isp) mbs.param[2] = *ptr++; mbs.param[1] = isp->isp_mbxwrk1++; break; + case MBOX_WRITE_RAM_WORD_EXTENDED: + mbs.param[2] = *ptr++; + mbs.param[1] = isp->isp_mbxwrk1++; + if (isp->isp_mbxwrk1 == 0) { + isp->isp_mbxwrk8++; + } + mbs.param[8] = isp->isp_mbxwrk8; + break; case MBOX_READ_RAM_WORD: + *ptr++ = isp->isp_mboxtmp[2]; + mbs.param[1] = isp->isp_mbxwrk1++; + break; case MBOX_READ_RAM_WORD_EXTENDED: *ptr++ = isp->isp_mboxtmp[2]; mbs.param[1] = isp->isp_mbxwrk1++; + if (isp->isp_mbxwrk1 == 0) { + isp->isp_mbxwrk8++; + } + mbs.param[8] = isp->isp_mbxwrk8; break; } isp->isp_mbxworkp = ptr; @@ -5146,9 +5222,9 @@ static const uint32_t mbpfc[] = { ISPOPMAP(0xdf, 0x01), /* 0x0a: DUMP RAM */ ISPOPMAP(0x00, 0x00), /* 0x0b: */ ISPOPMAP(0x00, 0x00), /* 0x0c: */ - ISPOPMAP(0x00, 0x00), /* 0x0d: */ + ISPOPMAP(0x13, 0x01), /* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED) */ ISPOPMAP(0x01, 0x05), /* 0x0e: MBOX_CHECK_FIRMWARE */ - ISPOPMAP(0x03, 0x07), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED(1) */ + ISPOPMAP(0x13, 0x05), /* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */ ISPOPMAP(0x1f, 0x11), /* 0x10: MBOX_INIT_REQ_QUEUE */ ISPOPMAP(0x2f, 0x21), /* 0x11: MBOX_INIT_RES_QUEUE */ ISPOPMAP(0x0f, 0x01), /* 0x12: MBOX_EXECUTE_IOCB */ @@ -5266,7 +5342,8 @@ static const uint32_t mbpfc[] = { * * (1): this sets bits 21..16 in mailbox register #8, which we nominally * do not access at this time in the core driver. The caller is - * responsible for setting this register first (Gross!). + * responsible for setting this register first (Gross!). The assumption + * is that we won't overflow. */ #ifndef ISP_STRIPPED @@ -5282,7 +5359,7 @@ static char *fc_mbcmd_names[] = { "ABOUT FIRMWARE", "LOAD RAM", "DUMP RAM", - NULL, + "WRITE RAM WORD EXTENDED", NULL, "READ RAM WORD EXTENDED", "CHECK FIRMWARE", @@ -5342,7 +5419,7 @@ static char *fc_mbcmd_names[] = { NULL, NULL, NULL, - "GET PORT DATABASE,, ENHANCED", + "GET PORT DATABASE ENHANCED", NULL, NULL, NULL, @@ -5465,6 +5542,9 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp, int logmask) ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp); obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp); + /* + * Pick up any additional bits that the caller might have set. + */ ibits |= mbp->ibits; obits |= mbp->obits; @@ -5504,10 +5584,10 @@ isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp, int logmask) */ MBOX_WAIT_COMPLETE(isp); + /* + * Did the command time out? + */ if (isp->isp_mboxbsy) { - /* - * Command timed out. - */ isp->isp_mboxbsy = 0; MBOX_RELEASE(isp); return; @@ -5773,9 +5853,7 @@ isp_setdfltparm(ispsoftc_t *isp, int channel) fcp->isp_fwoptions |= ICBOPT_FAIRNESS; fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE; fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS; -#ifndef ISP_NO_FASTPOST_FC fcp->isp_fwoptions |= ICBOPT_FAST_POST; -#endif if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX; @@ -5791,8 +5869,9 @@ isp_setdfltparm(ispsoftc_t *isp, int channel) */ if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) { nvfail = isp_read_nvram(isp); - if (nvfail) + if (nvfail) { isp->isp_confopts |= ISP_CFG_NONVRAM; + } } else { nvfail = 1; } @@ -5816,6 +5895,11 @@ isp_setdfltparm(ispsoftc_t *isp, int channel) * from NVRAM or our platform default. */ ISP_NODEWWN(isp) = fcp->isp_nodewwn; + if (fcp->isp_nodewwn == 0) { + isp_prt(isp, ISP_LOGCONFIG, + "bad WWNN- using default\n"); + ISP_NODEWWN(isp) = DEFAULT_NODEWWN(isp); + } } if (isp->isp_confopts & ISP_CFG_OWNWWPN) { isp_prt(isp, ISP_LOGCONFIG, "Using Port WWN 0x%08x%08x", @@ -5828,6 +5912,11 @@ isp_setdfltparm(ispsoftc_t *isp, int channel) * from NVRAM or our platform default. */ ISP_PORTWWN(isp) = fcp->isp_portwwn; + if (fcp->isp_portwwn == 0) { + isp_prt(isp, ISP_LOGCONFIG, + "bad WWPN- using default\n"); + ISP_PORTWWN(isp) = DEFAULT_PORTWWN(isp); + } } return; } @@ -6019,7 +6108,7 @@ isp_reinit(ispsoftc_t *isp) static int isp_read_nvram(ispsoftc_t *isp) { - int i, amt; + int i, amt, retval; uint8_t csum, minversion; union { uint8_t _x[ISP2100_NVRAM_SIZE]; @@ -6053,7 +6142,8 @@ isp_read_nvram(ispsoftc_t *isp) isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]); } - return (-1); + retval = -1; + goto out; } for (i = 2; i < amt>>1; i++) { isp_rdnvram_word(isp, i, &nvram_words[i]); @@ -6063,12 +6153,14 @@ isp_read_nvram(ispsoftc_t *isp) } if (csum != 0) { isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); - return (-1); + retval = -1; + goto out; } if (ISP_NVRAM_VERSION(nvram_data) < minversion) { isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood", ISP_NVRAM_VERSION(nvram_data)); - return (-1); + retval = -1; + goto out; } if (IS_ULTRA3(isp)) { @@ -6085,7 +6177,9 @@ isp_read_nvram(ispsoftc_t *isp) } else { isp_parse_nvram_2100(isp, nvram_data); } - return (0); + retval = 0; +out: + return (retval); #undef nvram_data #undef nvram_words } @@ -6094,15 +6188,15 @@ static void isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) { int i, cbits; - uint16_t bit, rqst; + uint16_t bit, rqst, junk; ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); - USEC_DELAY(2); + USEC_DELAY(10); ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK); - USEC_DELAY(2); + USEC_DELAY(10); if (IS_FC(isp)) { - wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1); + wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1); if (IS_2312(isp) && isp->isp_port) { wo += 128; } @@ -6128,11 +6222,14 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) bit = BIU_NVRAM_SELECT; } ISP_WRITE(isp, BIU_NVRAM, bit); - USEC_DELAY(2); + USEC_DELAY(10); + junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK); - USEC_DELAY(2); + USEC_DELAY(10); + junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_WRITE(isp, BIU_NVRAM, bit); - USEC_DELAY(2); + USEC_DELAY(10); + junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ } /* * Now read the result back in (bits come back in MSB format). @@ -6142,17 +6239,19 @@ isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp) uint16_t rv; *rp <<= 1; ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK); - USEC_DELAY(2); + USEC_DELAY(10); rv = ISP_READ(isp, BIU_NVRAM); if (rv & BIU_NVRAM_DATAIN) { *rp |= 1; } - USEC_DELAY(2); + USEC_DELAY(10); ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT); - USEC_DELAY(2); + USEC_DELAY(10); + junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ } ISP_WRITE(isp, BIU_NVRAM, 0); - USEC_DELAY(2); + USEC_DELAY(10); + junk = ISP_READ(isp, BIU_NVRAM); /* force PCI flush */ ISP_SWIZZLE_NVRAM_WORD(isp, rp); } @@ -6492,7 +6591,7 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) } fcp->isp_portwwn = wwn; if (IS_2200(isp) || IS_23XX(isp)) { - wwn = ISP2200_NVRAM_NODE_NAME(nvram_data); + wwn = ISP2100_NVRAM_NODE_NAME(nvram_data); if (wwn) { isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x", (uint32_t) (wwn >> 32), @@ -6532,13 +6631,6 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) } } - isp_prt(isp, ISP_LOGDEBUG0, - "NVRAM: maxfrmlen %d execthrottle %d fwoptions 0x%x loopid %x", - ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data), - ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data), - ISP2100_NVRAM_OPTIONS(nvram_data), - ISP2100_NVRAM_HARDLOOPID(nvram_data)); - fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data); if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) @@ -6555,6 +6647,23 @@ isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data) fcp->isp_execthrottle = ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data); fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data); + isp_prt(isp, ISP_LOGDEBUG0, + "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d", + (uint32_t) (fcp->isp_nodewwn >> 32), (uint32_t) fcp->isp_nodewwn, + (uint32_t) (fcp->isp_portwwn >> 32), (uint32_t) fcp->isp_portwwn, + ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data), + ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data)); + isp_prt(isp, ISP_LOGDEBUG0, + "execthrottle %d fwoptions 0x%x hardloop %d tov %d", + ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data), + ISP2100_NVRAM_OPTIONS(nvram_data), + ISP2100_NVRAM_HARDLOOPID(nvram_data), + ISP2100_NVRAM_TOV(nvram_data)); + fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data); + fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data); + isp_prt(isp, ISP_LOGDEBUG0, + "xfwoptions 0x%x zfw options 0x%x", + ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data)); } #ifdef ISP_FW_CRASH_DUMP @@ -6844,19 +6953,13 @@ isp2300_fw_dump(ispsoftc_t *isp) } ptr = isp->isp_mbxworkp; /* finish fetch of final word */ *ptr++ = isp->isp_mboxtmp[2]; - - /* - * We don't have access to mailbox registers 8.. onward - * in our 'common' device model- so we have to set it - * here and hope it stays the same! - */ - ISP_WRITE(isp, PCI_MBOX_REGS2300_OFF + (8 << 1), 0x1); - mbs.param[0] = MBOX_READ_RAM_WORD_EXTENDED; mbs.param[1] = 0; + mbs.param[8] = 1; isp->isp_mbxworkp = (void *) ptr; isp->isp_mbxwrk0 = 0xffff; /* continuation count */ isp->isp_mbxwrk1 = 0x1; /* next SRAM address */ + isp->isp_mbxwrk8 = 0x1; isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGWARN, diff --git a/sys/dev/isp/isp_pci.c b/sys/dev/isp/isp_pci.c index 09e05bb1d94f8..1186cced37a6c 100644 --- a/sys/dev/isp/isp_pci.c +++ b/sys/dev/isp/isp_pci.c @@ -165,6 +165,9 @@ static struct ispmdvec mdvec_2300 = { #ifndef PCIM_CMD_SEREN #define PCIM_CMD_SEREN 0x0100 #endif +#ifndef PCIM_CMD_INTX_DISABLE +#define PCIM_CMD_INTX_DISABLE 0x0400 +#endif #ifndef PCIR_COMMAND #define PCIR_COMMAND 0x04 @@ -874,10 +877,7 @@ isp_pci_attach(device_t dev) * Try and find firmware for this device. */ - /* - * Don't even attempt to get firmware for the 2322/2422 (yet) - */ - if (IS_2322(isp) == 0 && IS_24XX(isp) == 0 && isp_get_firmware_p) { + if (isp_get_firmware_p) { int device = (int) pci_get_device(dev); #ifdef ISP_TARGET_MODE (*isp_get_firmware_p)(0, 1, device, &mdvp->dv_ispfw); @@ -902,6 +902,11 @@ isp_pci_attach(device_t dev) isp->isp_touched = 1; } + + if (IS_2322(isp) || pci_get_devid(dev) == PCI_QLOGIC_ISP6312) { + cmd &= ~PCIM_CMD_INTX_DISABLE; + } + pci_write_config(dev, PCIR_COMMAND, cmd, 2); /* @@ -1114,6 +1119,7 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp, uint16_t *semap, uint16_t *mbox0p) { struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; + uint16_t hccr; uint32_t r2hisr; if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR) & BIU2100_ISR_RISC_INT))) { @@ -1158,6 +1164,16 @@ isp_pci_rd_isr_2300(ispsoftc_t *isp, uint16_t *isrp, *semap = 0; return (1); default: + hccr = ISP_READ(isp, HCCR); + if (hccr & HCCR_PAUSE) { + ISP_WRITE(isp, HCCR, HCCR_RESET); + isp_prt(isp, ISP_LOGERR, + "RISC paused at interrupt (%x->%x\n", hccr, + ISP_READ(isp, HCCR)); + } else { + isp_prt(isp, ISP_LOGERR, "unknown interrerupt 0x%x\n", + r2hisr); + } return (0); } } diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index e79efa232ca7d..2ef8d51e42d7b 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -46,7 +46,7 @@ /* a */ /* b */ /* c */ - /* d */ +#define MBOX_WRITE_RAM_WORD_EXTENDED 0x000d #define MBOX_CHECK_FIRMWARE 0x000e #define MBOX_READ_RAM_WORD_EXTENDED 0x000f #define MBOX_INIT_REQ_QUEUE 0x0010 @@ -691,9 +691,11 @@ typedef struct isp_icb { #define ICBXOPT_RIO_16BIT_IOCB 3 #define ICBXOPT_RIO_32BIT_IOCB 4 #define ICBXOPT_ZIO 5 +#define ICBXOPT_TIMER_MASK 0x7 #define ICBZOPT_ENA_RDXFR_RDY 0x01 #define ICBZOPT_ENA_OOF (1 << 6) /* out of order frame handling */ +#define ICBZOPT_50_OHM 0x0200 /* These 3 only apply to the 2300 */ #define ICBZOPT_RATE_ONEGB (MBGSD_ONEGB << 14) #define ICBZOPT_RATE_TWOGB (MBGSD_TWOGB << 14) diff --git a/sys/dev/isp/ispreg.h b/sys/dev/isp/ispreg.h index a53751fc57b98..8c5e5d413ee28 100644 --- a/sys/dev/isp/ispreg.h +++ b/sys/dev/isp/ispreg.h @@ -204,7 +204,8 @@ #define BIU2100_FB_REGS (1 << 4) /* FrameBuffer Regs */ #define BIU2100_FPM0_REGS (2 << 4) /* FPM 0 Regs */ #define BIU2100_FPM1_REGS (3 << 4) /* FPM 1 Regs */ -#define BIU2100_PCI64 0x04 /* R: 64 Bit PCI slot */ +#define BIU2100_NVRAM_OFFSET (1 << 14) +#define BIU2100_FLASH_UPPER_64K 0x04 /* RW: Upper 64K Bank Select */ #define BIU2100_FLASH_ENABLE 0x02 /* RW: Enable Flash RAM */ #define BIU2100_SOFT_RESET 0x01 /* SOFT RESET FOR ISP2100 is same bit, but in this register, not ICR */ @@ -268,6 +269,7 @@ #define BIU_NVRAM_SELECT 0x0002 #define BIU_NVRAM_DATAOUT 0x0004 #define BIU_NVRAM_DATAIN 0x0008 +#define BIU_NVRAM_BUSY 0x0080 /* 2322/24xx only */ #define ISP_NVRAM_READ 6 /* COMNMAND && DATA DMA CONFIGURATION REGISTER */ @@ -947,7 +949,7 @@ typedef struct { #define ISP2100_NVRAM_SIZE 256 /* ISP_NVRAM_VERSION is in same overall place */ #define ISP2100_NVRAM_RISCVER(c) (c)[6] -#define ISP2100_NVRAM_OPTIONS(c) (c)[8] +#define ISP2100_NVRAM_OPTIONS(c) ((c)[8] | ((c)[9] << 8)) #define ISP2100_NVRAM_MAXFRAMELENGTH(c) (((c)[10]) | ((c)[11] << 8)) #define ISP2100_NVRAM_MAXIOCBALLOCATION(c) (((c)[12]) | ((c)[13] << 8)) #define ISP2100_NVRAM_EXECUTION_THROTTLE(c) (((c)[14]) | ((c)[15] << 8)) @@ -964,9 +966,10 @@ typedef struct { (((uint64_t)(c)[24]) << 8) | \ (((uint64_t)(c)[25]) << 0)) -#define ISP2100_NVRAM_HARDLOOPID(c) (c)[26] +#define ISP2100_NVRAM_HARDLOOPID(c) ((c)[26] | ((c)[27] << 8)) +#define ISP2100_NVRAM_TOV(c) ((c)[29]) -#define ISP2200_NVRAM_NODE_NAME(c) (\ +#define ISP2100_NVRAM_NODE_NAME(c) (\ (((uint64_t)(c)[30]) << 56) | \ (((uint64_t)(c)[31]) << 48) | \ (((uint64_t)(c)[32]) << 40) | \ @@ -976,7 +979,16 @@ typedef struct { (((uint64_t)(c)[36]) << 8) | \ (((uint64_t)(c)[37]) << 0)) -#define ISP2100_NVRAM_HBA_OPTIONS(c) (c)[70] +#define ISP2100_XFW_OPTIONS(c) ((c)[38] | ((c)[39] << 8)) + +#define ISP2100_RACC_TIMER(c) (c)[40] +#define ISP2100_IDELAY_TIMER(c) (c)[41] + +#define ISP2100_ZFW_OPTIONS(c) ((c)[42] | ((c)[43] << 8)) + +#define ISP2100_SERIAL_LINK(c) ((c)[68] | ((c)[69] << 8)) + +#define ISP2100_NVRAM_HBA_OPTIONS(c) ((c)[70] | ((c)[71] << 8)) #define ISP2100_NVRAM_HBA_DISABLE(c) ISPBSMX(c, 70, 0, 0x01) #define ISP2100_NVRAM_BIOS_DISABLE(c) ISPBSMX(c, 70, 1, 0x01) #define ISP2100_NVRAM_LUN_DISABLE(c) ISPBSMX(c, 70, 2, 0x01) @@ -995,8 +1007,9 @@ typedef struct { (((uint64_t)(c)[79]) << 0)) #define ISP2100_NVRAM_BOOT_LUN(c) (c)[80] +#define ISP2100_RESET_DELAY(c) (c)[81] -#define ISP2200_HBA_FEATURES(c) (c)[232] | ((c)[233] << 8) +#define ISP2100_HBA_FEATURES(c) ((c)[232] | ((c)[233] << 8)) /* * Firmware Crash Dump diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index 3b0ef8dabeef8..59a7cd0d670c4 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -234,17 +234,19 @@ typedef struct { typedef struct { uint32_t : 13, isp_gbspeed : 3, - : 2, + : 1, isp_iid_set : 1, loop_seen_once : 1, isp_loopstate : 4, /* Current Loop State */ - isp_fwstate : 3, /* ISP F/W state */ + isp_fwstate : 4, /* ISP F/W state */ isp_gotdparms : 1, isp_topo : 3, isp_onfabric : 1; uint32_t : 8, isp_portid : 24; /* S_ID */ uint16_t isp_fwoptions; + uint16_t isp_xfwoptions; + uint16_t isp_zfwoptions; uint16_t isp_iid; /* 'initiator' id */ uint16_t isp_loopid; /* hard loop id */ uint16_t isp_fwattr; /* firmware attributes */ @@ -380,8 +382,7 @@ struct ispsoftc { * Volatile state */ - volatile uint32_t - isp_obits : 8, /* mailbox command output */ + volatile uint32_t : 8, isp_mboxbsy : 1, /* mailbox command active */ isp_state : 3, isp_sendmarker : 2, /* send a marker entry */ @@ -393,11 +394,13 @@ struct ispsoftc { volatile uint16_t isp_resodx; /* index of next result */ volatile uint16_t isp_rspbsy; volatile uint16_t isp_lasthdls; /* last handle seed */ + volatile uint16_t isp_obits; /* mailbox command output */ volatile uint16_t isp_mboxtmp[MAILBOX_STORAGE]; volatile uint16_t isp_lastmbxcmd; /* last mbox command sent */ volatile uint16_t isp_mbxwrk0; volatile uint16_t isp_mbxwrk1; volatile uint16_t isp_mbxwrk2; + volatile uint16_t isp_mbxwrk8; void * isp_mbxworkp; /* @@ -428,9 +431,10 @@ struct ispsoftc { * ISP Driver Run States */ #define ISP_NILSTATE 0 -#define ISP_RESETSTATE 1 -#define ISP_INITSTATE 2 -#define ISP_RUNSTATE 3 +#define ISP_CRASHED 1 +#define ISP_RESETSTATE 2 +#define ISP_INITSTATE 3 +#define ISP_RUNSTATE 4 /* * ISP Configuration Options |
