FreeBSD/sys/cam/ctl/ctl.c
/*
 * Add an initiator to the initiator map.
 * Returns iid for success, < 0 for failure.
 */
Add an initiator to the initiator map.
Returns iid for success, < 0 for failure.
Add an initiator to the initiator map . Returns iid for success < 0 for failure .
int
ctl_add_initiator(struct ctl_port *port, int iid, uint64_t wwpn, char *name)
{
	struct ctl_softc *softc = port->ctl_softc;
	time_t best_time;
	int i, best;
	mtx_assert(&softc->ctl_lock, MA_NOTOWNED);
	if (iid >= CTL_MAX_INIT_PER_PORT) {
		printf("%s: WWPN %#jx initiator ID %u > maximum %u!\n",
		       __func__, wwpn, iid, CTL_MAX_INIT_PER_PORT);
		free(name, M_CTL);
		return (-1);
	}
	mtx_lock(&softc->ctl_lock);
	if (iid < 0 && (wwpn != 0 || name != NULL)) {
		for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
			if (wwpn != 0 && wwpn == port->wwpn_iid[i].wwpn) {
				iid = i;
				break;
			}
			if (name != NULL && port->wwpn_iid[i].name != NULL &&
			    strcmp(name, port->wwpn_iid[i].name) == 0) {
				iid = i;
				break;
			}
		}
	}
	if (iid < 0) {
		for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
			if (port->wwpn_iid[i].in_use == 0 &&
			    port->wwpn_iid[i].wwpn == 0 &&
			    port->wwpn_iid[i].name == NULL) {
				iid = i;
				break;
			}
		}
	}
	if (iid < 0) {
		best = -1;
		best_time = INT32_MAX;
		for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) {
			if (port->wwpn_iid[i].in_use == 0) {
				if (port->wwpn_iid[i].last_use < best_time) {
					best = i;
					best_time = port->wwpn_iid[i].last_use;
				}
			}
		}
		iid = best;
	}
	if (iid < 0) {
		mtx_unlock(&softc->ctl_lock);
		free(name, M_CTL);
		return (-2);
	}
	if (port->wwpn_iid[iid].in_use > 0 && (wwpn != 0 || name != NULL)) {
		if (wwpn != 0 && wwpn == port->wwpn_iid[iid].wwpn) {
#if 0
			printf("%s: port %d iid %u WWPN %#jx arrived"
			    " again\n", __func__, port->targ_port,
			    iid, (uintmax_t)wwpn);
#endif
			goto take;
		}
		if (name != NULL && port->wwpn_iid[iid].name != NULL &&
		    strcmp(name, port->wwpn_iid[iid].name) == 0) {
#if 0
			printf("%s: port %d iid %u name '%s' arrived"
			    " again\n", __func__, port->targ_port,
			    iid, name);
#endif
			goto take;
		}
		printf("%s: port %d iid %u WWPN %#jx '%s' arrived,"
		    " but WWPN %#jx '%s' is still at that address\n",
		    __func__, port->targ_port, iid, wwpn, name,
		    (uintmax_t)port->wwpn_iid[iid].wwpn,
		    port->wwpn_iid[iid].name);
	}
take:
	free(port->wwpn_iid[iid].name, M_CTL);
	port->wwpn_iid[iid].name = name;
	port->wwpn_iid[iid].wwpn = wwpn;
	port->wwpn_iid[iid].in_use++;
	mtx_unlock(&softc->ctl_lock);
	ctl_isc_announce_iid(port, iid);
	return (iid);
}
int ctl_add_initiator ( struct ctl_port * port , int iid , uint64_t wwpn , char * name ) { struct ctl_softc * softc = port -> ctl_softc ; time_t best_time ; int i , best ; mtx_assert ( & softc -> ctl_lock , MA_NOTOWNED ) ; if ( iid >= CTL_MAX_INIT_PER_PORT ) { printf ( " \n " , __func__ , wwpn , iid , CTL_MAX_INIT_PER_PORT ) ; free ( name , M_CTL ) ; return ( -1 ) ; } mtx_lock ( & softc -> ctl_lock ) ; if ( iid < 0 && ( wwpn != 0 || name != NULL ) ) { for ( i = 0 ; i < CTL_MAX_INIT_PER_PORT ; i ++ ) { if ( wwpn != 0 && wwpn == port -> wwpn_iid [ i ] . wwpn ) { iid = i ; break ; } if ( name != NULL && port -> wwpn_iid [ i ] . name != NULL && strcmp ( name , port -> wwpn_iid [ i ] . name ) == 0 ) { iid = i ; break ; } } } if ( iid < 0 ) { for ( i = 0 ; i < CTL_MAX_INIT_PER_PORT ; i ++ ) { if ( port -> wwpn_iid [ i ] . in_use == 0 && port -> wwpn_iid [ i ] . wwpn == 0 && port -> wwpn_iid [ i ] . name == NULL ) { iid = i ; break ; } } } if ( iid < 0 ) { best = -1 ; best_time = INT32_MAX ; for ( i = 0 ; i < CTL_MAX_INIT_PER_PORT ; i ++ ) { if ( port -> wwpn_iid [ i ] . in_use == 0 ) { if ( port -> wwpn_iid [ i ] . last_use < best_time ) { best = i ; best_time = port -> wwpn_iid [ i ] . last_use ; } } } iid = best ; } if ( iid < 0 ) { mtx_unlock ( & softc -> ctl_lock ) ; free ( name , M_CTL ) ; return ( -2 ) ; } if ( port -> wwpn_iid [ iid ] . in_use > 0 && ( wwpn != 0 || name != NULL ) ) { if ( wwpn != 0 && wwpn == port -> wwpn_iid [ iid ] . wwpn ) { #if 0 printf ( " " " \n " , __func__ , port -> targ_port , iid , ( uintmax_t ) wwpn ) ; #endif goto take ; } if ( name != NULL && port -> wwpn_iid [ iid ] . name != NULL && strcmp ( name , port -> wwpn_iid [ iid ] . name ) == 0 ) { #if 0 printf ( " " " \n " , __func__ , port -> targ_port , iid , name ) ; #endif goto take ; } printf ( " " " \n " , __func__ , port -> targ_port , iid , wwpn , name , ( uintmax_t ) port -> wwpn_iid [ iid ] . wwpn , port -> wwpn_iid [ iid ] . name ) ; } take : free ( port -> wwpn_iid [ iid ] . name , M_CTL ) ; port -> wwpn_iid [ iid ] . name = name ; port -> wwpn_iid [ iid ] . wwpn = wwpn ; port -> wwpn_iid [ iid ] . in_use ++ ; mtx_unlock ( & softc -> ctl_lock ) ; ctl_isc_announce_iid ( port , iid ) ; return ( iid ) ; }
Add an initiator to the initiator map.
Add an initiator to the initiator map .
/*
		 * This is not an error yet.
		 */ /*
		 * This is an error, but what do we do about it?  The
		 * driver is telling us we have a new WWPN for this
		 * initiator ID, so we pretty much need to use it.
		 */ /*
		 * XXX KDM clear have_ca and ua_pending on each LUN for
		 * this initiator.
		 */