FreeBSD/sys/dev/isp/isp.c
/*
 * Complete the synchronization of our Port Database.
 *
 * At this point, we've scanned the local loop (if any) and the fabric
 * and performed fabric logins on all new devices.
 *
 * Our task here is to go through our port database removing any entities
 * that are still marked probational (issuing PLOGO for ones which we had
 * PLOGI'd into) or are dead, and notifying upper layers about new/changed
 * devices.
 */
Complete the synchronization of our Port Database.
At this point, we've scanned the local loop (if any) and the fabric
and performed fabric logins on all new devices.

Our task here is to go through our port database removing any entities
that are still marked probational (issuing PLOGO for ones which we had
PLOGI'd into) or are dead, and notifying upper layers about new/changed
devices.
Complete the synchronization of our Port Database . At this point we ' ve scanned the local loop ( if any ) and the fabric and performed fabric logins on all new devices . Our task here is to go through our port database removing any entities that are still marked probational ( issuing PLOGO for ones which we had PLOGI ' d into ) or are dead and notifying upper layers about new / changed devices .
static int
isp_pdb_sync(ispsoftc_t *isp, int chan)
{
	fcparam *fcp = FCPARAM(isp, chan);
	fcportdb_t *lp;
	uint16_t dbidx;
	if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
		return (-1);
	if (fcp->isp_loopstate >= LOOP_READY)
		return (0);
	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
	fcp->isp_loopstate = LOOP_SYNCING_PDB;
	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
		lp = &fcp->portdb[dbidx];
		if (lp->state == FC_PORTDB_STATE_NIL)
			continue;
		if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
			lp->state = FC_PORTDB_STATE_DEAD;
		switch (lp->state) {
		case FC_PORTDB_STATE_DEAD:
			lp->state = FC_PORTDB_STATE_NIL;
			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
			if ((lp->portid & 0xffff00) != 0) {
				(void) isp_plogx(isp, chan, lp->handle,
				    lp->portid,
				    PLOGX_FLG_CMD_LOGO |
				    PLOGX_FLG_IMPLICIT |
				    PLOGX_FLG_FREE_NPHDL);
			}
			break;
		case FC_PORTDB_STATE_NEW:
			lp->state = FC_PORTDB_STATE_VALID;
			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
			break;
		case FC_PORTDB_STATE_CHANGED:
			lp->state = FC_PORTDB_STATE_VALID;
			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
			lp->portid = lp->new_portid;
			lp->prli_word3 = lp->new_prli_word3;
			break;
		case FC_PORTDB_STATE_VALID:
			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
			break;
		case FC_PORTDB_STATE_ZOMBIE:
			break;
		default:
			isp_prt(isp, ISP_LOGWARN,
			    "isp_pdb_sync: state %d for idx %d",
			    lp->state, dbidx);
			isp_dump_portdb(isp, chan);
		}
	}
	if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
		isp_prt(isp, ISP_LOG_SANCFG,
		    "Chan %d FC PDB sync aborted", chan);
		return (1);
	}
	fcp->isp_loopstate = LOOP_READY;
	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
	return (0);
}
static int isp_pdb_sync ( ispsoftc_t * isp , int chan ) { fcparam * fcp = FCPARAM ( isp , chan ) ; fcportdb_t * lp ; uint16_t dbidx ; if ( fcp -> isp_loopstate < LOOP_FSCAN_DONE ) return ( -1 ) ; if ( fcp -> isp_loopstate >= LOOP_READY ) return ( 0 ) ; isp_prt ( isp , ISP_LOG_SANCFG , " " , chan ) ; fcp -> isp_loopstate = LOOP_SYNCING_PDB ; for ( dbidx = 0 ; dbidx < MAX_FC_TARG ; dbidx ++ ) { lp = & fcp -> portdb [ dbidx ] ; if ( lp -> state == FC_PORTDB_STATE_NIL ) continue ; if ( lp -> probational && lp -> state != FC_PORTDB_STATE_ZOMBIE ) lp -> state = FC_PORTDB_STATE_DEAD ; switch ( lp -> state ) { case FC_PORTDB_STATE_DEAD : lp -> state = FC_PORTDB_STATE_NIL ; isp_async ( isp , ISPASYNC_DEV_GONE , chan , lp ) ; if ( ( lp -> portid & 0xffff00 ) != 0 ) { ( void ) isp_plogx ( isp , chan , lp -> handle , lp -> portid , PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL ) ; } break ; case FC_PORTDB_STATE_NEW : lp -> state = FC_PORTDB_STATE_VALID ; isp_async ( isp , ISPASYNC_DEV_ARRIVED , chan , lp ) ; break ; case FC_PORTDB_STATE_CHANGED : lp -> state = FC_PORTDB_STATE_VALID ; isp_async ( isp , ISPASYNC_DEV_CHANGED , chan , lp ) ; lp -> portid = lp -> new_portid ; lp -> prli_word3 = lp -> new_prli_word3 ; break ; case FC_PORTDB_STATE_VALID : isp_async ( isp , ISPASYNC_DEV_STAYED , chan , lp ) ; break ; case FC_PORTDB_STATE_ZOMBIE : break ; default : isp_prt ( isp , ISP_LOGWARN , " " , lp -> state , dbidx ) ; isp_dump_portdb ( isp , chan ) ; } } if ( fcp -> isp_loopstate < LOOP_SYNCING_PDB ) { isp_prt ( isp , ISP_LOG_SANCFG , " " , chan ) ; return ( 1 ) ; } fcp -> isp_loopstate = LOOP_READY ; isp_prt ( isp , ISP_LOG_SANCFG , " " , chan ) ; return ( 0 ) ; }
Complete the synchronization of our Port Database.
Complete the synchronization of our Port Database .
/*
			 * Note that we might come out of this with our state
			 * set to FC_PORTDB_STATE_ZOMBIE.
			 */