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

📄 isp.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |		    (((u_int64_t)(mbs.param[7] >> 8)));	}	return (wwn);}/* * Make sure we have good FC link and know our Loop ID. */static intisp_fclink_test(struct ispsoftc *isp, int usdelay){	static char *toponames[] = {		"Private Loop",		"FL Port",		"N-Port to N-Port",		"F Port",		"F Port (no FLOGI_ACC response)"	};	mbreg_t mbs;	int count, check_for_fabric;	u_int8_t lwfs;	fcparam *fcp;	struct lportdb *lp;	isp_pdb_t pdb;	fcp = isp->isp_param;	/*	 * XXX: Here is where we would start a 'loop dead' timeout	 */	/*	 * Wait up to N microseconds for F/W to go to a ready state.	 */	lwfs = FW_CONFIG_WAIT;	count = 0;	while (count < usdelay) {		u_int64_t enano;		u_int32_t wrk;		NANOTIME_T hra, hrb;		GET_NANOTIME(&hra);		isp_fw_state(isp);		if (lwfs != fcp->isp_fwstate) {			isp_prt(isp, ISP_LOGINFO, "Firmware State <%s->%s>",			    isp2100_fw_statename((int)lwfs),			    isp2100_fw_statename((int)fcp->isp_fwstate));			lwfs = fcp->isp_fwstate;		}		if (fcp->isp_fwstate == FW_READY) {			break;		}		GET_NANOTIME(&hrb);		/*		 * Get the elapsed time in nanoseconds.		 * Always guaranteed to be non-zero.		 */		enano = NANOTIME_SUB(&hrb, &hra);		isp_prt(isp, ISP_LOGDEBUG1,		    "usec%d: 0x%lx->0x%lx enano 0x%x%08x",		    count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),		    (u_int32_t)(enano >> 32), (u_int32_t)(enano & 0xffffffff));		/*		 * If the elapsed time is less than 1 millisecond,		 * delay a period of time up to that millisecond of		 * waiting.		 *		 * This peculiar code is an attempt to try and avoid		 * invoking u_int64_t math support functions for some		 * platforms where linkage is a problem.		 */		if (enano < (1000 * 1000)) {			count += 1000;			enano = (1000 * 1000) - enano;			while (enano > (u_int64_t) 4000000000U) {				USEC_SLEEP(isp, 4000000);				enano -= (u_int64_t) 4000000000U;			}			wrk = enano;			wrk /= 1000;			USEC_SLEEP(isp, wrk);		} else {			while (enano > (u_int64_t) 4000000000U) {				count += 4000000;				enano -= (u_int64_t) 4000000000U;			}			wrk = enano;			count += (wrk / 1000);		}	}	/*	 * If we haven't gone to 'ready' state, return.	 */	if (fcp->isp_fwstate != FW_READY) {		return (-1);	}	/*	 * Get our Loop ID (if possible). We really need to have it.	 */	mbs.param[0] = MBOX_GET_LOOP_ID;	isp_mboxcmd(isp, &mbs, MBLOGALL);	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {		return (-1);	}	fcp->isp_loopid = mbs.param[1];	if (IS_2200(isp) || IS_23XX(isp)) {		int topo = (int) mbs.param[6];		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)			topo = TOPO_PTP_STUB;		fcp->isp_topo = topo;	} else {		fcp->isp_topo = TOPO_NL_PORT;	}	fcp->isp_portid = fcp->isp_alpa = mbs.param[2] & 0xff;	/*	 * Check to see if we're on a fabric by trying to see if we	 * can talk to the fabric name server. This can be a bit	 * tricky because if we're a 2100, we should check always	 * (in case we're connected to an server doing aliasing).	 */	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)		check_for_fabric = 1;	else		check_for_fabric = 0;	if (check_for_fabric && isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {		int loopid = FL_PORT_ID;		if (IS_2100(isp)) {			fcp->isp_topo = TOPO_FL_PORT;		}		if (BITS2WORD(pdb.pdb_portid_bits) == 0) {			/*			 * Crock.			 */			fcp->isp_topo = TOPO_NL_PORT;			goto not_on_fabric;		}		fcp->isp_portid = mbs.param[2] | ((int) mbs.param[3] << 16);		/*		 * Save the Fabric controller's port database entry.		 */		lp = &fcp->portdb[loopid];		lp->node_wwn =		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |		    (((u_int64_t)pdb.pdb_nodename[7]));		lp->port_wwn =		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |		    (((u_int64_t)pdb.pdb_portname[7]));		lp->roles =		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;		lp->portid = BITS2WORD(pdb.pdb_portid_bits);		lp->loopid = pdb.pdb_loopid;		lp->loggedin = lp->valid = 1;		fcp->isp_onfabric = 1;		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);		isp_register_fc4_type(isp);	} else {not_on_fabric:		fcp->isp_onfabric = 0;		fcp->portdb[FL_PORT_ID].valid = 0;	}	fcp->isp_gbspeed = 1;	if (IS_23XX(isp)) {		mbs.param[0] = MBOX_GET_SET_DATA_RATE;		mbs.param[1] = MBGSD_GET_RATE;		/* mbs.param[2] undefined if we're just getting rate */		isp_mboxcmd(isp, &mbs, MBLOGALL);		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {			if (mbs.param[1] == MBGSD_TWOGB) {				isp_prt(isp, ISP_LOGINFO, "2Gb link speed/s");				fcp->isp_gbspeed = 2;			}		}	}	isp_prt(isp, ISP_LOGCONFIG, topology, fcp->isp_loopid, fcp->isp_alpa,	    fcp->isp_portid, fcp->isp_loopstate, toponames[fcp->isp_topo]);	/*	 * Announce ourselves, too. This involves synthesizing an entry.	 */	if (fcp->isp_iid_set == 0) {		fcp->isp_iid_set = 1;		fcp->isp_iid = fcp->isp_loopid;		lp = &fcp->portdb[fcp->isp_iid];	} else {		lp = &fcp->portdb[fcp->isp_iid];		if (fcp->isp_portid != lp->portid ||		    fcp->isp_loopid != lp->loopid ||		    fcp->isp_nodewwn != ISP_NODEWWN(isp) ||		    fcp->isp_portwwn != ISP_PORTWWN(isp)) {			lp->valid = 0;			count = fcp->isp_iid;			(void) isp_async(isp, ISPASYNC_PROMENADE, &count);		}	}	lp->loopid = fcp->isp_loopid;	lp->portid = fcp->isp_portid;	lp->node_wwn = ISP_NODEWWN(isp);	lp->port_wwn = ISP_PORTWWN(isp);	switch (isp->isp_role) {	case ISP_ROLE_NONE:		lp->roles = 0;		break;	case ISP_ROLE_TARGET:		lp->roles = SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT;		break;	case ISP_ROLE_INITIATOR:		lp->roles = SVC3_INI_ROLE >> SVC3_ROLE_SHIFT;		break;	case ISP_ROLE_BOTH:		lp->roles = (SVC3_INI_ROLE|SVC3_TGT_ROLE) >> SVC3_ROLE_SHIFT;		break;	}	lp->loggedin = lp->valid = 1;	count = fcp->isp_iid;	(void) isp_async(isp, ISPASYNC_PROMENADE, &count);	return (0);}static char *isp2100_fw_statename(int state){	switch(state) {	case FW_CONFIG_WAIT:	return "Config Wait";	case FW_WAIT_AL_PA:	return "Waiting for AL_PA";	case FW_WAIT_LOGIN:	return "Wait Login";	case FW_READY:		return "Ready";	case FW_LOSS_OF_SYNC:	return "Loss Of Sync";	case FW_ERROR:		return "Error";	case FW_REINIT:		return "Re-Init";	case FW_NON_PART:	return "Nonparticipating";	default:		return "?????";	}}/* * Synchronize our soft copy of the port database with what the f/w thinks * (with a view toward possibly for a specific target....) */static intisp_pdb_sync(struct ispsoftc *isp){	struct lportdb *lp;	fcparam *fcp = isp->isp_param;	isp_pdb_t pdb;	int loopid, base, lim;	/*	 * Make sure we're okay for doing this right now.	 */	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {		return (-1);	}	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT ||	    fcp->isp_topo == TOPO_N_PORT) {		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {			if (isp_scan_loop(isp) != 0) {				return (-1);			}		}	}	fcp->isp_loopstate = LOOP_SYNCING_PDB;	/*	 * If we get this far, we've settled our differences with the f/w	 * (for local loop device) and we can say that the loop state is ready.	 */	if (fcp->isp_topo == TOPO_NL_PORT) {		fcp->loop_seen_once = 1;		fcp->isp_loopstate = LOOP_READY;		return (0);	}	/*	 * Find all Fabric Entities that didn't make it from one scan to the	 * next and let the world know they went away. Scan the whole database.	 */	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {		if (lp->was_fabric_dev && lp->fabric_dev == 0) {			loopid = lp - fcp->portdb;			lp->valid = 0;	/* should already be set */			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);			MEMZERO((void *) lp, sizeof (*lp));			continue;		}		lp->was_fabric_dev = lp->fabric_dev;	}	if (fcp->isp_topo == TOPO_FL_PORT)		base = FC_SNS_ID+1;	else		base = 0;	if (fcp->isp_topo == TOPO_N_PORT)		lim = 1;	else		lim = MAX_FC_TARG;	/*	 * Now log in any fabric devices that the outer layer has	 * left for us to see. This seems the most sane policy	 * for the moment.	 */	for (lp = &fcp->portdb[base]; lp < &fcp->portdb[lim]; lp++) {		u_int32_t portid;		mbreg_t mbs;		loopid = lp - fcp->portdb;		if (loopid >= FL_PORT_ID && loopid <= FC_SNS_ID) {			continue;		}		/*		 * Anything here?		 */		if (lp->port_wwn == 0) {			continue;		}		/*		 * Don't try to log into yourself.		 */		if ((portid = lp->portid) == fcp->isp_portid) {			continue;		}		/*		 * If we'd been logged in- see if we still are and we haven't		 * changed. If so, no need to log ourselves out, etc..		 *		 * Unfortunately, our charming Qlogic f/w has decided to		 * return a valid port database entry for a fabric device		 * that has, in fact, gone away. And it hangs trying to		 * log it out.		 */		if (lp->loggedin &&		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {			int nrole;			u_int64_t nwwnn, nwwpn;			nwwnn =			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |			    (((u_int64_t)pdb.pdb_nodename[7]));			nwwpn =			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |			    (((u_int64_t)pdb.pdb_portname[7]));			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>			    SVC3_ROLE_SHIFT;			if (pdb.pdb_loopid == lp->loopid && lp->portid ==			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&			    lp->roles == nrole && lp->force_logout == 0) {				lp->loggedin = lp->valid = 1;				isp_prt(isp, ISP_LOGCONFIG, lretained,				    (int) (lp - fcp->portdb),				    (int) lp->loopid, lp->portid);				continue;			}		}		lp->force_logout = 0;		if (fcp->isp_fwstate != FW_READY ||		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {			return (-1);		}		/*		 * Force a logout if we were logged in.		 */		if (lp->loggedin) {			if (isp_getpdb(isp, lp->loopid, &pdb) == 0) {				mbs.param[0] = MBOX_FABRIC_LOGOUT;				mbs.param[1] = lp->loopid << 8;				mbs.param[2] = 0;				mbs.param[3] = 0;				isp_mboxcmd(isp, &mbs, MBLOGNONE);				lp->loggedin = 0;				isp_prt(isp, ISP_LOGINFO, plogout,				    (int) (lp - fcp->portdb), lp->loopid,				    lp->portid);			}			lp->loggedin = 0;			if (fcp->isp_fwstate != FW_READY ||			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {				return (-1);			}		}		/*		 * And log in....		 */		loopid = lp - fcp->portdb;		lp->loopid = FL_PORT_ID;		do {			mbs.param[0] = MBOX_FABRIC_LOGIN;			mbs.param[1] = loopid << 8;			mbs.param[2] = portid >> 16;			mbs.param[3] = portid & 0xffff;			if (IS_2200(isp) || IS_23XX(isp)) {				/* only issue a PLOGI if not logged in */				mbs.param[1] |= 0x1;			}			isp_mboxcmd(isp, &mbs, MBLOGALL & ~(MBOX_LOOP_ID_USED |			    MBOX_PORT_ID_USED | MBOX_COMMAND_ERROR));			if (fcp->isp_fwstate != FW_READY ||			    fcp->isp_loopstate != LOOP_SYNCING_PDB) {				return (-1);			}			switch (mbs.param[0]) {			case MBOX_LOOP_ID_USED:				/*				 * Try the next available loop id.				 */				loopid++;				break;			case MBOX_PORT_ID_USED:				/*				 * This port is already logged in.				 * Snaffle the loop id it's using if it's				 * nonzero, otherwise we're hosed.				 */				if (mbs.param[1] != 0) {					loopid = mbs.param[1];					isp_prt(isp, ISP_LOGINFO, retained,					    loopid, (int) (lp - fcp->portdb),					    lp->portid);				} else {					loopid = MAX_FC_TARG;					break;				}				/* FALLTHROUGH */			case MBOX_COMMAND_COMPLETE:				lp->loggedin = 1;				lp->loopid = loopid;

⌨️ 快捷键说明

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