FreeBSD/sys/dev/isp/isp.c
/*
 * Find an unused handle and try and use to login to a port.
 */
Find an unused handle and try and use to login to a port.
Find an unused handle and try and use to login to a port .
static int
isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
{
	int lim, i, r;
	uint16_t handle;
	if (ISP_CAP_2KLOGIN(isp)) {
		lim = NPH_MAX_2K;
	} else {
		lim = NPH_MAX;
	}
	handle = isp_next_handle(isp, ohp);
	for (i = 0; i < lim; i++) {
		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
			return (-1);
		r = isp_getpdb(isp, chan, handle, p);
		if (r == 0) {
			if (p->portid != portid) {
				handle = isp_next_handle(isp, ohp);
				continue;
			}
			break;
		}
		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
			return (-1);
		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
		if (r == 0) {
			break;
		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
			}
			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
				return (-1);
			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
			if (r != 0)
				i = lim;
			break;
		} else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
			handle = isp_next_handle(isp, ohp);
		} else {
			i = lim;
			break;
		}
	}
	if (i == lim) {
		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
		return (-1);
	}
	r = isp_getpdb(isp, chan, handle, p);
	if (r != 0) {
		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
		return (-1);
	}
	if (p->handle != handle || p->portid != portid) {
		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
		    chan, portid, handle, p->portid, p->handle);
		return (-1);
	}
	return (0);
}
static int isp_login_device ( ispsoftc_t * isp , int chan , uint32_t portid , isp_pdb_t * p , uint16_t * ohp ) { int lim , i , r ; uint16_t handle ; if ( ISP_CAP_2KLOGIN ( isp ) ) { lim = NPH_MAX_2K ; } else { lim = NPH_MAX ; } handle = isp_next_handle ( isp , ohp ) ; for ( i = 0 ; i < lim ; i ++ ) { if ( FCPARAM ( isp , chan ) -> isp_loopstate != LOOP_SCANNING_FABRIC ) return ( -1 ) ; r = isp_getpdb ( isp , chan , handle , p ) ; if ( r == 0 ) { if ( p -> portid != portid ) { handle = isp_next_handle ( isp , ohp ) ; continue ; } break ; } if ( FCPARAM ( isp , chan ) -> isp_loopstate != LOOP_SCANNING_FABRIC ) return ( -1 ) ; r = isp_plogx ( isp , chan , handle , portid , PLOGX_FLG_CMD_PLOGI ) ; if ( r == 0 ) { break ; } else if ( ( r & 0xffff ) == MBOX_PORT_ID_USED ) { if ( isp_plogx ( isp , chan , r >> 16 , portid , PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL ) ) { isp_prt ( isp , ISP_LOGERR , " " , r >> 16 ) ; } if ( FCPARAM ( isp , chan ) -> isp_loopstate != LOOP_SCANNING_FABRIC ) return ( -1 ) ; r = isp_plogx ( isp , chan , handle , portid , PLOGX_FLG_CMD_PLOGI ) ; if ( r != 0 ) i = lim ; break ; } else if ( ( r & 0xffff ) == MBOX_LOOP_ID_USED ) { handle = isp_next_handle ( isp , ohp ) ; } else { i = lim ; break ; } } if ( i == lim ) { isp_prt ( isp , ISP_LOGWARN , " " , chan , portid ) ; return ( -1 ) ; } r = isp_getpdb ( isp , chan , handle , p ) ; if ( r != 0 ) { isp_prt ( isp , ISP_LOGERR , " " , chan , portid , handle ) ; return ( -1 ) ; } if ( p -> handle != handle || p -> portid != portid ) { isp_prt ( isp , ISP_LOGERR , " " , chan , portid , handle , p -> portid , p -> handle ) ; return ( -1 ) ; } return ( 0 ) ; }
Find an unused handle and try and use to login to a port.
Find an unused handle and try and use to login to a port .
/* Check if this handle is free. */ /* This handle is busy, try next one. */ /*
		 * Now try and log into the device
		 */ /*
			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
			 * handle. We need to break that association. We used to try and just substitute the handle, but then
			 * failed to get any data via isp_getpdb (below).
			 */ /* Try the next handle. */ /* Give up. */ /*
	 * If we successfully logged into it, get the PDB for it
	 * so we can crosscheck that it is still what we think it
	 * is and that we also have the role it plays
	 */