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

📄 isp.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
				break;			case MBOX_COMMAND_ERROR:				isp_prt(isp, ISP_LOGINFO, plogierr,				    portid, mbs.param[1]);				/* FALLTHROUGH */			case MBOX_ALL_IDS_USED: /* We're outta IDs */			default:				loopid = MAX_FC_TARG;				break;			}		} while (lp->loopid == FL_PORT_ID && loopid < MAX_FC_TARG);		/*		 * If we get here and we haven't set a Loop ID,		 * we failed to log into this device.		 */		if (lp->loopid == FL_PORT_ID) {			lp->loopid = 0;			continue;		}		/*		 * Make sure we can get the approriate port information.		 */		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {			isp_prt(isp, ISP_LOGWARN, nopdb, lp->portid);			goto dump_em;		}		if (fcp->isp_fwstate != FW_READY ||		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {			return (-1);		}		if (pdb.pdb_loopid != lp->loopid) {			isp_prt(isp, ISP_LOGWARN, pdbmfail1,			    lp->portid, pdb.pdb_loopid);			goto dump_em;		}		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {			isp_prt(isp, ISP_LOGWARN, pdbmfail2,			    lp->portid, BITS2WORD(pdb.pdb_portid_bits));			goto dump_em;		}		lp->roles =		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;		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]));		/*		 * Check to make sure this all makes sense.		 */		if (lp->node_wwn && lp->port_wwn) {			lp->valid = 1;			loopid = lp - fcp->portdb;			(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);			continue;		}dump_em:		lp->valid = 0;		isp_prt(isp, ISP_LOGINFO,		    ldumped, loopid, lp->loopid, lp->portid);		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);		if (fcp->isp_fwstate != FW_READY ||		    fcp->isp_loopstate != LOOP_SYNCING_PDB) {			return (-1);		}	}	/*	 * If we get here, we've for sure seen not only a valid loop	 * but know what is or isn't on it, so mark this for usage	 * in isp_start.	 */	fcp->loop_seen_once = 1;	fcp->isp_loopstate = LOOP_READY;	return (0);}static intisp_scan_loop(struct ispsoftc *isp){	struct lportdb *lp;	fcparam *fcp = isp->isp_param;	isp_pdb_t pdb;	int loopid, lim, hival;	switch (fcp->isp_topo) {	case TOPO_NL_PORT:		hival = FL_PORT_ID;		break;	case TOPO_N_PORT:		hival = 2;		break;	case TOPO_FL_PORT:		hival = FC_PORT_ID;		break;	default:		fcp->isp_loopstate = LOOP_LSCAN_DONE;		return (0);	}	fcp->isp_loopstate = LOOP_SCANNING_LOOP;	/*	 * make sure the temp port database is clean...	 */	MEMZERO((void *)fcp->tport, sizeof (fcp->tport));	/*	 * Run through the local loop ports and get port database info	 * for each loop ID.	 *	 * There's a somewhat unexplained situation where the f/w passes back	 * the wrong database entity- if that happens, just restart (up to	 * FL_PORT_ID times).	 */	for (lim = loopid = 0; loopid < hival; loopid++) {		lp = &fcp->tport[loopid];		/*		 * Don't even try for ourselves...	 	 */		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;		}		/*		 * Get an entry....		 */		if (isp_getpdb(isp, loopid, &pdb) != 0) {			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)				return (-1);			continue;		}		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {			return (-1);		}		/*		 * If the returned database element doesn't match what we		 * asked for, restart the process entirely (up to a point...).		 */		if (pdb.pdb_loopid != loopid) {			loopid = 0;			if (lim++ < hival) {				continue;			}			isp_prt(isp, ISP_LOGWARN,			    "giving up on synchronizing the port database");			return (-1);		}		/*		 * Save the pertinent info locally.		 */		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;	}	/*	 * Mark all of the permanent local loop database entries as invalid	 * (except our own entry).	 */	for (loopid = 0; loopid < hival; loopid++) {		if (loopid == fcp->isp_iid) {			fcp->portdb[loopid].valid = 1;			fcp->portdb[loopid].loopid = fcp->isp_loopid;			continue;		}		fcp->portdb[loopid].valid = 0;	}	/*	 * Now merge our local copy of the port database into our saved copy.	 * Notify the outer layers of new devices arriving.	 */	for (loopid = 0; loopid < hival; loopid++) {		int i;		/*		 * If we don't have a non-zero Port WWN, we're not here.		 */		if (fcp->tport[loopid].port_wwn == 0) {			continue;		}		/*		 * Skip ourselves.		 */		if (loopid == fcp->isp_iid) {			continue;		}		/*		 * For the purposes of deciding whether this is the		 * 'same' device or not, we only search for an identical		 * Port WWN. Node WWNs may or may not be the same as		 * the Port WWN, and there may be multiple different		 * Port WWNs with the same Node WWN. It would be chaos		 * to have multiple identical Port WWNs, so we don't		 * allow that.		 */		for (i = 0; i < hival; i++) {			int j;			if (fcp->portdb[i].port_wwn == 0)				continue;			if (fcp->portdb[i].port_wwn !=			    fcp->tport[loopid].port_wwn)				continue;			/*			 * We found this WWN elsewhere- it's changed			 * loopids then. We don't change it's actual			 * position in our cached port database- we			 * just change the actual loop ID we'd use.			 */			if (fcp->portdb[i].loopid != loopid) {				isp_prt(isp, ISP_LOGINFO, portshift, i,				    fcp->portdb[i].loopid,				    fcp->portdb[i].portid, loopid,				    fcp->tport[loopid].portid);			}			fcp->portdb[i].portid = fcp->tport[loopid].portid;			fcp->portdb[i].loopid = loopid;			fcp->portdb[i].valid = 1;			fcp->portdb[i].roles = fcp->tport[loopid].roles;			/*			 * Now make sure this Port WWN doesn't exist elsewhere			 * in the port database.			 */			for (j = i+1; j < hival; j++) {				if (fcp->portdb[i].port_wwn !=				    fcp->portdb[j].port_wwn) {					continue;				}				isp_prt(isp, ISP_LOGWARN, portdup, j, i);				/*				 * Invalidate the 'old' *and* 'new' ones.				 * This is really harsh and not quite right,				 * but if this happens, we really don't know				 * who is what at this point.				 */				fcp->portdb[i].valid = 0;				fcp->portdb[j].valid = 0;			}			break;		}		/*		 * If we didn't traverse the entire port database,		 * then we found (and remapped) an existing entry.		 * No need to notify anyone- go for the next one.		 */		if (i < hival) {			isp_prt(isp, ISP_LOGINFO, retained,			    fcp->portdb[i].loopid, i, fcp->portdb[i].portid);			continue;		}		/*		 * We've not found this Port WWN anywhere. It's a new entry.		 * See if we can leave it where it is (with target == loopid).		 */		if (fcp->portdb[loopid].port_wwn != 0) {			for (lim = 0; lim < hival; lim++) {				if (fcp->portdb[lim].port_wwn == 0)					break;			}			/* "Cannot Happen" */			if (lim == hival) {				isp_prt(isp, ISP_LOGWARN, "Remap Overflow");				continue;			}			i = lim;		} else {			i = loopid;		}		/*		 * NB:	The actual loopid we use here is loopid- we may		 *	in fact be at a completely different index (target).		 */		fcp->portdb[i].loopid = loopid;		fcp->portdb[i].port_wwn = fcp->tport[loopid].port_wwn;		fcp->portdb[i].node_wwn = fcp->tport[loopid].node_wwn;		fcp->portdb[i].roles = fcp->tport[loopid].roles;		fcp->portdb[i].portid = fcp->tport[loopid].portid;		fcp->portdb[i].valid = 1;		/*		 * Tell the outside world we've arrived.		 */		(void) isp_async(isp, ISPASYNC_PROMENADE, &i);	}	/*	 * Now find all previously used targets that are now invalid and	 * notify the outer layers that they're gone.	 */	for (lp = &fcp->portdb[0]; lp < &fcp->portdb[hival]; lp++) {		if (lp->valid || lp->port_wwn == 0) {			continue;		}		/*		 * Tell the outside world we've gone		 * away and erase our pdb entry.		 *		 */		loopid = lp - fcp->portdb;		(void) isp_async(isp, ISPASYNC_PROMENADE, &loopid);		MEMZERO((void *) lp, sizeof (*lp));	}	fcp->isp_loopstate = LOOP_LSCAN_DONE;	return (0);}static intisp_fabric_mbox_cmd(struct ispsoftc *isp, mbreg_t *mbp){	isp_mboxcmd(isp, mbp, MBLOGNONE);	if (mbp->param[0] != MBOX_COMMAND_COMPLETE) {		if (FCPARAM(isp)->isp_loopstate == LOOP_SCANNING_FABRIC) {			FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;		}		if (mbp->param[0] == MBOX_COMMAND_ERROR) {			char tbuf[16];			char *m;			switch (mbp->param[1]) {			case 1:				m = "No Loop";				break;			case 2:				m = "Failed to allocate IOCB buffer";				break;			case 3:				m = "Failed to allocate XCB buffer";				break;			case 4:				m = "timeout or transmit failed";				break;			case 5:				m = "no fabric loop";				break;			case 6:				m = "remote device not a target";				break;			default:				SNPRINTF(tbuf, sizeof tbuf, "%x",				    mbp->param[1]);				m = tbuf;				break;			}			isp_prt(isp, ISP_LOGERR, "SNS Failed- %s", m);		}		return (-1);	}	if (FCPARAM(isp)->isp_fwstate != FW_READY ||	    FCPARAM(isp)->isp_loopstate < LOOP_SCANNING_FABRIC) {		return (-1);	}	return(0);}#ifdef	ISP_USE_GA_NXTstatic intisp_scan_fabric(struct ispsoftc *isp, int ftype){	fcparam *fcp = isp->isp_param;	u_int32_t portid, first_portid, last_portid;	int hicap, last_port_same;	if (fcp->isp_onfabric == 0) {		fcp->isp_loopstate = LOOP_FSCAN_DONE;		return (0);	}	FC_SCRATCH_ACQUIRE(isp);	/*	 * Since Port IDs are 24 bits, we can check against having seen	 * anything yet with this value.	 */	last_port_same = 0;	last_portid = 0xffffffff;	/* not a port */	first_portid = portid = fcp->isp_portid;	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;	for (hicap = 0; hicap < GA_NXT_MAX; hicap++) {		mbreg_t mbs;		sns_screq_t *rq;		sns_ga_nxt_rsp_t *rs0, *rs1;		struct lportdb lcl;		u_int8_t sc[SNS_GA_NXT_RESP_SIZE];		rq = (sns_screq_t *)sc;		MEMZERO((void *) rq, SNS_GA_NXT_REQ_SIZE);		rq->snscb_rblen = SNS_GA_NXT_RESP_SIZE >> 1;		rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma+0x100);		rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma+0x100);		rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma+0x100);		rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma+0x100);		rq->snscb_sblen = 6;		rq->snscb_data[0] = SNS_GA_NXT;		rq->snscb_data[4] = portid & 0xffff;		rq->snscb_data[5] = (portid >> 16) & 0xff;		isp_put_sns_request(isp, rq, (sns_screq_t *) fcp->isp_scratch);		MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GA_NXT_REQ_SIZE);		mbs.param[0] = MBOX_SEND_SNS;		mbs.param[1] = SNS_GA_NXT_REQ_SIZE >> 1;		mbs.param[2] = DMA_WD1(fcp->isp_scdma);		mbs.param[3] = DMA_WD0(fcp->isp_scdma);		/*		 * Leave 4 and 5 alone		 */		mbs.param[6] = DMA_WD3(fcp->isp_scdma);		mbs.param[7] = DMA_WD2(fcp->isp_scdma);		if (isp_fabric_mbox_cmd(isp, &mbs)) {			if (fcp->isp_loopstate >= LOOP_SCANNING_FABRIC) {				fcp->isp_loopstate = LOOP_PDB_RCVD;			}			FC_SCRATCH_RELEASE(isp);			return (-1);		}		MEMORYBARRIER(isp, SYNC_SFORCPU, 0x100, SNS_GA_NXT_RESP_SIZE);		rs1 = (sns_ga_nxt_rsp_t *) sc;		rs0 = (sns_ga_nxt_

⌨️ 快捷键说明

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