⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isp.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
		USEC_DELAY(100);		if (--loops < 0) {			ISP_DUMPREGS(isp, "chip reset timed out");			return;		}	}	/*	 * After we've fired this chip up, zero out the conf1 register	 * for SCSI adapters and other settings for the 2100.	 */	if (IS_SCSI(isp)) {		ISP_WRITE(isp, BIU_CONF1, 0);	} else {		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);	/*	 * Establish some initial burst rate stuff.	 * (only for the 1XX0 boards). This really should	 * be done later after fetching from NVRAM.	 */	if (IS_SCSI(isp)) {		u_int16_t tmp = isp->isp_mdvec->dv_conf1;		/*		 * Busted FIFO. Turn off all but burst enables.		 */		if (isp->isp_type == ISP_HA_SCSI_1040A) {			tmp &= BIU_BURST_ENABLE;		}		ISP_SETBITS(isp, BIU_CONF1, tmp);		if (tmp & BIU_BURST_ENABLE) {			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);		}#ifdef	PTI_CARDS		if (((sdparam *) isp->isp_param)->isp_ultramode) {			while (ISP_READ(isp, RISC_MTR) != 0x1313) {				ISP_WRITE(isp, RISC_MTR, 0x1313);				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);			}		} else {			ISP_WRITE(isp, RISC_MTR, 0x1212);		}		/*		 * PTI specific register		 */		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)#else		ISP_WRITE(isp, RISC_MTR, 0x1212);#endif	} 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); /* release paused processor */	/*	 * Do MD specific post initialization	 */	ISP_RESET1(isp);	/*	 * Wait for everything to finish firing up.	 *	 * Avoid doing this on the 2312 because you can generate a PCI	 * parity error (chip breakage).	 */	if (IS_23XX(isp)) {		USEC_DELAY(5);	} else {		loops = MBOX_DELAY_COUNT;		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {			USEC_DELAY(100);			if (--loops < 0) {				isp_prt(isp, ISP_LOGERR,				    "MBOX_BUSY never cleared on reset");				return;			}		}	}	/*	 * Up until this point we've done everything by just reading or	 * setting registers. From this point on we rely on at least *some*	 * kind of firmware running in the card.	 */	/*	 * Do some sanity checking.	 */	mbs.param[0] = MBOX_NO_OP;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	if (IS_SCSI(isp)) {		mbs.param[0] = MBOX_MAILBOX_REG_TEST;		mbs.param[1] = 0xdead;		mbs.param[2] = 0xbeef;		mbs.param[3] = 0xffff;		mbs.param[4] = 0x1111;		mbs.param[5] = 0xa5a5;		isp_mboxcmd(isp, &mbs, MBLOGALL);		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {			return;		}		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||		    mbs.param[5] != 0xa5a5) {			isp_prt(isp, ISP_LOGERR,			    "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)",			    mbs.param[1], mbs.param[2], mbs.param[3],			    mbs.param[4], mbs.param[5]);			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_ispfw == NULL) ||	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {		dodnld = 0;	}	if (IS_23XX(isp))		code_org = ISP_CODE_ORG_2300;	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;		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];		isp_mboxcmd(isp, &mbs, MBLOGNONE);		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {			isp_prt(isp, ISP_LOGERR,			    "F/W download failed at word %d",			    isp->isp_mbxwrk1 - code_org);			dodnld = 0;			goto again;		}		/*		 * Verify that it downloaded correctly.		 */		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, "Ram Checksum Failure");			return;		}		isp->isp_loaded_fw = 1;	} else {		isp->isp_loaded_fw = 0;		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");	}	/*	 * 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;	mbs.param[1] = code_org;	isp_mboxcmd(isp, &mbs, MBLOGNONE);	/* give it a chance to start */	USEC_SLEEP(isp, 500);	if (IS_SCSI(isp)) {		/*		 * 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, MBLOGALL);			/* we will try not to care if this fails */		}	}	mbs.param[0] = MBOX_ABOUT_FIRMWARE;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	/*	 * The SBus firmware that we are using apparently does not return	 * major, minor, micro revisions in the mailbox registers, which	 * is really, really, annoying.	 */	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {		if (dodnld) {#ifdef	ISP_TARGET_MODE			isp->isp_fwrev[0] = 7;			isp->isp_fwrev[1] = 55;#else			isp->isp_fwrev[0] = 1;			isp->isp_fwrev[1] = 37;#endif			isp->isp_fwrev[2] = 0;		} 	} else {		isp->isp_fwrev[0] = mbs.param[1];		isp->isp_fwrev[1] = mbs.param[2];		isp->isp_fwrev[2] = mbs.param[3];	}	isp_prt(isp, ISP_LOGCONFIG,	    "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",	    btype, isp->isp_revision, dodnld? "loaded" : "resident",	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);	if (IS_FC(isp)) {		/*		 * We do not believe firmware attributes for 2100 code less		 * than 1.17.0.		 */		if (IS_2100(isp) && 		   (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0))) {			FCPARAM(isp)->isp_fwattr = 0;		} else {			FCPARAM(isp)->isp_fwattr = mbs.param[6];			isp_prt(isp, ISP_LOGDEBUG0,			    "Firmware Attributes = 0x%x", mbs.param[6]);		}		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {			isp_prt(isp, ISP_LOGCONFIG,			    "Installed in 64-Bit PCI slot");		}	}	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||	    isp->isp_romfw_rev[2]) {		isp_prt(isp, ISP_LOGCONFIG, "Last F/W revision was %d.%d.%d",		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],		    isp->isp_romfw_rev[2]);	}	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	isp->isp_maxcmds = mbs.param[2];	isp_prt(isp, ISP_LOGINFO,	    "%d max I/O commands supported", mbs.param[2]);	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;	/*	 * Okay- now that we have new firmware running, we now (re)set our	 * notion of how many luns we support. This is somewhat tricky because	 * if we haven't loaded firmware, we sometimes do not have an easy way	 * of knowing how many luns we support.	 *	 * Expanded lun firmware gives you 32 luns for SCSI cards and	 * 65536 luns for Fibre Channel cards.	 *	 * It turns out that even for QLogic 2100s with ROM 1.10 and above	 * we do get a firmware attributes word returned in mailbox register 6.	 *	 * Because the lun is in a a different position in the Request Queue	 * Entry structure for Fibre Channel with expanded lun firmware, we	 * can only support one lun (lun zero) when we don't know what kind	 * of firmware we're running.	 *	 * Note that we only do this once (the first time thru isp_reset)	 * because we may be called again after firmware has been loaded once	 * and released.	 */	if (touched == 0) {		if (IS_SCSI(isp)) {			if (dodnld) {				isp->isp_maxluns = 32;			} else {				isp->isp_maxluns = 8;			}		} else {			if (FCPARAM(isp)->isp_fwattr & ISP_FW_ATTR_SCCLUN) {				isp->isp_maxluns = 65536;			} else {				isp->isp_maxluns = 16;			}		}	}}/* * Initialize Parameters of Hardware to a known state. * * Locks are held before coming here. */voidisp_init(struct ispsoftc *isp){	/*	 * Must do this first to get defaults established.	 */	isp_setdfltparm(isp, 0);	if (IS_DUALBUS(isp)) {		isp_setdfltparm(isp, 1);	}	if (IS_FC(isp)) {		isp_fibre_init(isp);	} else {		isp_scsi_init(isp);	}}static voidisp_scsi_init(struct ispsoftc *isp){	sdparam *sdp_chan0, *sdp_chan1;	mbreg_t mbs;	sdp_chan0 = isp->isp_param;	sdp_chan1 = sdp_chan0;	if (IS_DUALBUS(isp)) {		sdp_chan1++;	}	/*	 * If we have no role (neither target nor initiator), return.	 */	if (isp->isp_role == ISP_ROLE_NONE) {		return;	}	/* First do overall per-card settings. */	/*	 * If we have fast memory timing enabled, turn it on.	 */	if (sdp_chan0->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, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		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, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		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, MBLOGNONE);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		isp_prt(isp, ISP_LOGERR,		    "failed to set active negation state (%d,%d), (%d,%d)",		    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, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",		    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, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	/* now do per-channel settings */	isp_scsi_channel_init(isp, 0);	if (IS_DUALBUS(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(isp);	mbs.param[2] = DMA_WD1(isp->isp_result_dma);	mbs.param[3] = DMA_WD0(isp->isp_result_dma);	mbs.param[4] = 0;	mbs.param[5] = 0;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	isp->isp_residx = mbs.param[5];	mbs.param[0] = MBOX_INIT_REQ_QUEUE;	mbs.param[1] = RQUEST_QUEUE_LEN(isp);	mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);	mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);	mbs.param[4] = 0;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return;	}	isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];	/*	 * Turn on Fast Posting, LVD transitions	 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -