diff options
-rw-r--r-- | sys/dev/isp/isp.c | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 75abde4..64573d7 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -728,11 +728,17 @@ again: if (IS_FC(isp)) { /* * We do not believe firmware attributes for 2100 code less - * than 1.17.0. + * 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. */ - if (IS_2100(isp) && - (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0))) { + if (!(ISP_FW_NEWER_THAN(isp, 1, 17, 0))) { +#ifdef USE_SMALLER_2100_FIRMWARE + FCPARAM(isp)->isp_fwattr = ISP_FW_ATTR_SCCLUN; +#else FCPARAM(isp)->isp_fwattr = 0; +#endif } else { FCPARAM(isp)->isp_fwattr = mbs.param[6]; isp_prt(isp, ISP_LOGDEBUG0, @@ -1172,7 +1178,7 @@ isp_fibre_init(struct ispsoftc *isp) * because otherwise port database entries don't get updated after * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0. */ - if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) { + if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) { fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN; } @@ -1244,9 +1250,17 @@ isp_fibre_init(struct ispsoftc *isp) break; } if (IS_23XX(isp)) { - if (IS_2300(isp) && isp->isp_revision < 2) { - icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; - } + /* + * 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. + */ + icbp->icb_xfwoptions |= ICBXOPT_ZIO; + if (isp->isp_confopts & ISP_CFG_ONEGB) { icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB; } else if (isp->isp_confopts & ISP_CFG_TWOGB) { @@ -1265,21 +1279,24 @@ isp_fibre_init(struct ispsoftc *isp) * 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, but it seems safer to only support this on the - * 23XX cards. + * was. * - * I have it disabled if we support a target mode role for - * reasons I can't now remember. + * 23XX Cards do not support RIO. Instead they support ZIO. */ - if ((isp->isp_role & ISP_ROLE_TARGET) == 0 && IS_23XX(isp)) { +#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 - if ((IS_2200(isp) && ISP_FW_REVX(isp->isp_fwrev) >= - ISP_FW_REV(2, 1, 26)) || IS_23XX(isp)) { + /* + * For 22XX > 2.1.26 && 23XX, set someoptions. + * XXX: Probably okay for newer 2100 f/w too. + */ + if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) { /* * Turn on LIP F8 async event (1) * Turn on generate AE 8013 on all LIP Resets (2) @@ -1326,8 +1343,9 @@ isp_fibre_init(struct ispsoftc *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_LOGDEBUG1, - "isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions); + 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); FC_SCRATCH_ACQUIRE(isp); isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch); @@ -1585,11 +1603,20 @@ isp_fclink_test(struct ispsoftc *isp, int usdelay) */ fcp->isp_onfabric = 0; - if (IS_2100(isp)) - check_for_fabric = 1; - else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) + if (IS_2100(isp)) { + /* + * Don't bother with fabric if we are using really old + * 2100 firmware. It's just not worth it. + */ + if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) { + check_for_fabric = 1; + } else { + check_for_fabric = 0; + } + } else if (fcp->isp_topo == TOPO_FL_PORT || + fcp->isp_topo == TOPO_F_PORT) { check_for_fabric = 1; - else + } else check_for_fabric = 0; if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) { @@ -3458,7 +3485,8 @@ again: } else if (isp_parse_async(isp, mbox) < 0) { return; } - if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) { + if ((IS_FC(isp) && mbox != ASYNC_RIO_RESP) || + isp->isp_state != ISP_RUNSTATE) { ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); ISP_WRITE(isp, BIU_SEMA, 0); return; @@ -3882,9 +3910,20 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox) isp_async(isp, ISPASYNC_BUS_RESET, &bus); break; case ASYNC_SYSTEM_ERROR: +#ifdef ISP_FW_CRASH_DUMP + /* + * If we have crash dumps enabled, it's up to the handler + * for isp_async to reinit stuff and restart the firmware + * after performing the crash dump. The reason we do things + * this way is that we may need to activate a kernel thread + * to do all the crash dump goop. + */ + isp_async(isp, ISPASYNC_FW_CRASH, NULL); +#else isp_async(isp, ISPASYNC_FW_CRASH, NULL); isp_reinit(isp); isp_async(isp, ISPASYNC_FW_RESTARTED, NULL); +#endif rval = -1; break; @@ -4003,7 +4042,7 @@ isp_parse_async(struct ispsoftc *isp, u_int16_t mbox) break; case ASYNC_RIO_RESP: - break; + return (rval); case ASYNC_CTIO_DONE: { @@ -6458,6 +6497,7 @@ isp2200_fw_dump(struct ispsoftc *isp) *ptr++ = isp->isp_mboxtmp[2]; isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully"); FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */ + (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0); } static void @@ -6620,6 +6660,7 @@ isp2300_fw_dump(struct ispsoftc *isp) *ptr++ = mbs.param[2]; isp_prt(isp, ISP_LOGALL, "isp_fw_dump: SRAM dumped succesfully"); FCPARAM(isp)->isp_dump_data[0] = isp->isp_type; /* now used */ + (void) isp_async(isp, ISPASYNC_FW_DUMPED, 0); } void |