📄 isp.c
字号:
"Mailbox Register test didn't complete"); return; } if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef || mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 || mbs.param[5] != 0xa5a5) { isp_dumpregs(isp, "Register Test Failed"); return; } } /* * Download new Firmware, unless requested not to do so. * This is made slightly trickier in some cases where the * firmware of the ROM revision is newer than the revision * compiled into the driver. So, where we used to compare * versions of our f/w and the ROM f/w, now we just see * whether we have f/w at all and whether a config flag * has disabled our download. */ if ((isp->isp_mdvec->dv_fwlen == 0) || (isp->isp_confopts & ISP_CFG_NORELOAD)) { dodnld = 0; } if (dodnld && isp->isp_mdvec->dv_fwlen) { for (i = 0; i < isp->isp_mdvec->dv_fwlen; i++) { mbs.param[0] = MBOX_WRITE_RAM_WORD; mbs.param[1] = isp->isp_mdvec->dv_codeorg + i; mbs.param[2] = isp->isp_mdvec->dv_ispfw[i]; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: F/W download failed at word %d\n", isp->isp_name, i); dodnld = 0; goto again; } } /* * Verify that it downloaded correctly. */ mbs.param[0] = MBOX_VERIFY_CHECKSUM; mbs.param[1] = isp->isp_mdvec->dv_codeorg; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_dumpregs(isp, "ram checksum failure"); return; } } else { IDPRINTF(3, ("%s: skipping f/w download\n", isp->isp_name)); } /* * Now start it rolling. * * If we didn't actually download f/w, * we still need to (re)start it. */ mbs.param[0] = MBOX_EXEC_FIRMWARE; if (isp->isp_mdvec->dv_codeorg) mbs.param[1] = isp->isp_mdvec->dv_codeorg; else mbs.param[1] = 0x1000; isp_mboxcmd(isp, &mbs); if (isp->isp_type & ISP_HA_SCSI) { /* * Set CLOCK RATE, but only if asked to. */ if (isp->isp_clock) { mbs.param[0] = MBOX_SET_CLOCK_RATE; mbs.param[1] = isp->isp_clock; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_dumpregs(isp, "failed to set CLOCKRATE"); /* but continue */ } else { IDPRINTF(3, ("%s: setting input clock to %d\n", isp->isp_name, isp->isp_clock)); } } } mbs.param[0] = MBOX_ABOUT_FIRMWARE; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_dumpregs(isp, "ABOUT FIRMWARE command failed"); return; } PRINTF("%s: Board Revision %s, %s F/W Revision %d.%d.%d\n", isp->isp_name, revname, dodnld? "loaded" : "resident", mbs.param[1], mbs.param[2], mbs.param[3]); if (IS_FC(isp)) { if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) { PRINTF("%s: in 64-Bit PCI slot\n", isp->isp_name); } } isp->isp_fwrev[0] = mbs.param[1]; isp->isp_fwrev[1] = mbs.param[2]; isp->isp_fwrev[2] = mbs.param[3]; if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] || isp->isp_romfw_rev[2]) { PRINTF("%s: Last F/W revision was %d.%d.%d\n", isp->isp_name, isp->isp_romfw_rev[0], isp->isp_romfw_rev[1], isp->isp_romfw_rev[2]); } isp_fw_state(isp); /* * Set up DMA for the request and result mailboxes. */ if (ISP_MBOXDMASETUP(isp) != 0) { PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name); return; } isp->isp_state = ISP_RESETSTATE;}/* * Initialize Parameters of Hardware to a known state. * * Locks are held before coming here. */voidisp_init(isp) struct ispsoftc *isp;{ /* * Must do this first to get defaults established. */ isp_setdfltparm(isp, 0); if (IS_12X0(isp)) { isp_setdfltparm(isp, 1); } if (IS_FC(isp)) { isp_fibre_init(isp); } else { isp_scsi_init(isp); }}static voidisp_scsi_init(isp) struct ispsoftc *isp;{ sdparam *sdp_chan0, *sdp_chan1; mbreg_t mbs; sdp_chan0 = isp->isp_param; sdp_chan1 = sdp_chan0; if (IS_12X0(isp)) { sdp_chan1++; } /* First do overall per-card settings. */ /* * If we have fast memory timing enabled, turn it on. */ if (isp->isp_fast_mttr) { ISP_WRITE(isp, RISC_MTR, 0x1313); } /* * Set Retry Delay and Count. * You set both channels at the same time. */ mbs.param[0] = MBOX_SET_RETRY_COUNT; mbs.param[1] = sdp_chan0->isp_retry_count; mbs.param[2] = sdp_chan0->isp_retry_delay; mbs.param[6] = sdp_chan1->isp_retry_count; mbs.param[7] = sdp_chan1->isp_retry_delay; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set retry count and retry delay\n", isp->isp_name); return; } /* * Set ASYNC DATA SETUP time. This is very important. */ mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; mbs.param[1] = sdp_chan0->isp_async_data_setup; mbs.param[2] = sdp_chan1->isp_async_data_setup; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set asynchronous data setup time\n", isp->isp_name); return; } /* * Set ACTIVE Negation State. */ mbs.param[0] = MBOX_SET_ACT_NEG_STATE; mbs.param[1] = (sdp_chan0->isp_req_ack_active_neg << 4) | (sdp_chan0->isp_data_line_active_neg << 5); mbs.param[2] = (sdp_chan1->isp_req_ack_active_neg << 4) | (sdp_chan1->isp_data_line_active_neg << 5); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set active negation state " "(%d,%d),(%d,%d)\n", isp->isp_name, sdp_chan0->isp_req_ack_active_neg, sdp_chan0->isp_data_line_active_neg, sdp_chan1->isp_req_ack_active_neg, sdp_chan1->isp_data_line_active_neg); /* * But don't return. */ } /* * Set the Tag Aging limit */ mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT; mbs.param[1] = sdp_chan0->isp_tag_aging; mbs.param[2] = sdp_chan1->isp_tag_aging; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set tag age limit (%d,%d)\n", isp->isp_name, sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging); return; } /* * Set selection timeout. */ mbs.param[0] = MBOX_SET_SELECT_TIMEOUT; mbs.param[1] = sdp_chan0->isp_selection_timeout; mbs.param[2] = sdp_chan1->isp_selection_timeout; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set selection timeout\n", isp->isp_name); return; } /* now do per-channel settings */ isp_scsi_channel_init(isp, 0); if (IS_12X0(isp)) isp_scsi_channel_init(isp, 1); /* * Now enable request/response queues */ mbs.param[0] = MBOX_INIT_RES_QUEUE; mbs.param[1] = RESULT_QUEUE_LEN; mbs.param[2] = DMA_MSW(isp->isp_result_dma); mbs.param[3] = DMA_LSW(isp->isp_result_dma); mbs.param[4] = 0; mbs.param[5] = 0; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: set of response queue failed\n", isp->isp_name); return; } isp->isp_residx = 0; mbs.param[0] = MBOX_INIT_REQ_QUEUE; mbs.param[1] = RQUEST_QUEUE_LEN; mbs.param[2] = DMA_MSW(isp->isp_rquest_dma); mbs.param[3] = DMA_LSW(isp->isp_rquest_dma); mbs.param[4] = 0; mbs.param[5] = 0; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: set of request queue failed\n", isp->isp_name); return; } isp->isp_reqidx = isp->isp_reqodx = 0; /* * Turn on Fast Posting, LVD transitions */ if (IS_1080(isp) || ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0)) { mbs.param[0] = MBOX_SET_FW_FEATURES;#ifndef ISP_NO_FASTPOST_SCSI mbs.param[1] |= FW_FEATURE_FAST_POST;#else mbs.param[1] = 0;#endif if (IS_1080(isp)) mbs.param[1] |= FW_FEATURE_LVD_NOTIFY; if (mbs.param[1] != 0) { isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: unable enable FW features\n", isp->isp_name); } } } /* * Let the outer layers decide whether to issue a SCSI bus reset. */ isp->isp_state = ISP_INITSTATE;}static voidisp_scsi_channel_init(isp, channel) struct ispsoftc *isp; int channel;{ sdparam *sdp; mbreg_t mbs; int tgt; sdp = isp->isp_param; sdp += channel; /* * Set (possibly new) Initiator ID. */ mbs.param[0] = MBOX_SET_INIT_SCSI_ID; mbs.param[1] = (channel << 7) | sdp->isp_initiator_id; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: cannot set initiator id on bus %d to %d\n", isp->isp_name, channel, sdp->isp_initiator_id); return; } /* * Set current per-target parameters to a safe minimum. */ for (tgt = 0; tgt < MAX_TARGETS; tgt++) { int maxlun, lun; u_int16_t sdf; if (sdp->isp_devparam[tgt].dev_enable == 0) { PRINTF("%s: skipping settings for target %d bus %d\n", isp->isp_name, tgt, channel); continue; } /* * If we're in LVD mode, then we pretty much should * only disable tagged queuing. */ if (IS_1080(isp) && sdp->isp_lvdmode) { sdf = DPARM_DEFAULT & ~DPARM_TQING; } else { sdf = DPARM_SAFE_DFLT; /* * It is not quite clear when this changed over so that * we could force narrow and async, so assume >= 7.55. */ if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0)) { sdf |= DPARM_NARROW | DPARM_ASYNC; } } mbs.param[0] = MBOX_SET_TARGET_PARAMS; mbs.param[1] = (tgt << 8) | (channel << 15); mbs.param[2] = sdf; mbs.param[3] = (sdp->isp_devparam[tgt].sync_offset << 8) | (sdp->isp_devparam[tgt].sync_period); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { sdf = DPARM_SAFE_DFLT; mbs.param[0] = MBOX_SET_TARGET_PARAMS; mbs.param[1] = (tgt << 8) | (channel << 15); mbs.param[2] = sdf; mbs.param[3] = (sdp->isp_devparam[tgt].sync_offset << 8) | (sdp->isp_devparam[tgt].sync_period); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed even to set defaults for " "target %d\n", isp->isp_name, tgt); continue; } }#if 0 /* * We don't update dev_flags with what we've set * because that's not the ultimate goal setting. * If we succeed with the command, we *do* update * cur_dflags by getting target parameters. */ mbs.param[0] = MBOX_GET_TARGET_PARAMS; mbs.param[1] = (tgt << 8) | (channel << 15); isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { /* * Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so * we don't try and do tags if tags aren't enabled. */ sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT; } else { sdp->isp_devparam[tgt].cur_dflags = mbs.param[2]; sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8; sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff; } IDPRINTF(3, ("%s: set flags 0x%x got 0x%x back for target %d\n", isp->isp_name, sdf, mbs.param[2], tgt));#else /* * We don't update any information because we need to run * at least one command per target to cause a new state * to be latched. */#endif /* * Ensure that we don't believe tagged queuing is enabled yet. * It turns out that sometimes the ISP just ignores our * attempts to set parameters for devices that it hasn't * seen yet. */ sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING; if (ISP_FW_REVX(isp->isp_fwrev) >= ISP_FW_REV(7, 55, 0)) maxlun = 32; else maxlun = 8; for (lun = 0; lun < maxlun; lun++) { mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS; mbs.param[1] = (channel << 15) | (tgt << 8) | lun; mbs.param[2] = sdp->isp_max_queue_depth; mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle; isp_mboxcmd(isp, &mbs); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { PRINTF("%s: failed to set device queue " "parameters for target %d, lun %d\n", isp->isp_name, tgt, lun); break; } } }}/* * Fibre Channel specific initialization. * * Locks are held before coming here. */static voidisp_fibre_init(isp) struct ispsoftc *isp;{ fcparam *fcp; isp_icb_t *icbp; mbreg_t mbs; int count, loopid; fcp = isp->isp_param; /* * For systems that don't have BIOS methods for which * we can easily change the NVRAM based loopid, we'll * override that here. Note that when we initialize * the firmware we may get back a different loopid than * we asked for anyway. XXX This is probably not the * best way to figure this out XXX */#ifndef __i386__ loopid = DEFAULT_LOOPID;#else loopid = fcp->isp_loopid;#endif#if defined(ISP2100_FABRIC) && defined(ISP2100_SCCLUN) PRINTF("%s: Fabric Support, Expanded Lun Support\n", isp->isp_name);#endif#if defined(ISP2100_FABRIC) && !defined(ISP2100_SCCLUN) PRINTF("%s: Fabric Support\n", isp->isp_name);#endif#if !defined(ISP2100_FABRIC) && defined(ISP2100_SCCLUN) PRINTF("%s: Expanded Lun Support\n", isp->isp_name);#endif icbp = (isp_icb_t *) fcp->isp_scratch; MEMZERO(icbp, sizeof (*icbp)); icbp->icb_version = ICB_VERSION1;#ifdef ISP_TARGET_MODE fcp->isp_fwoptions = ICBOPT_TGT_ENABLE|ICBOPT_INI_TGTTYPE;#else fcp->isp_fwoptions = 0;#endif fcp->isp_fwoptions |= ICBOPT_INI_ADISC|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#ifdef CHECKME fcp->isp_fwoptions |= ICBOPT_USE_PORTNAME;#endif#ifdef ISP2100_FABRIC fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;#endif icbp->icb_fwoptions = fcp->isp_fwoptions; icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -