FreeBSD/sys/cam/ctl/ctl.c
/*
 * This routine is for handling a message from the other SC pertaining to
 * persistent reserve out. All the error checking will have been done
 * so only perorming the action need be done here to keep the two
 * in sync.
 */
This routine is for handling a message from the other SC pertaining to
persistent reserve out. All the error checking will have been done
so only perorming the action need be done here to keep the two
in sync.
This routine is for handling a message from the other SC pertaining to persistent reserve out . All the error checking will have been done so only perorming the action need be done here to keep the two in sync .
static void
ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg)
{
	struct ctl_softc *softc = control_softc;
	struct ctl_lun *lun;
	int i;
	uint32_t residx, targ_lun;
	targ_lun = msg->hdr.nexus.targ_mapped_lun;
	mtx_lock(&softc->ctl_lock);
	if ((targ_lun >= CTL_MAX_LUNS) ||
	    ((lun = softc->ctl_luns[targ_lun]) == NULL)) {
		mtx_unlock(&softc->ctl_lock);
		return;
	}
	mtx_lock(&lun->lun_lock);
	mtx_unlock(&softc->ctl_lock);
	if (lun->flags & CTL_LUN_DISABLED) {
		mtx_unlock(&lun->lun_lock);
		return;
	}
	residx = ctl_get_initindex(&msg->hdr.nexus);
	switch(msg->pr.pr_info.action) {
	case CTL_PR_REG_KEY:
		ctl_alloc_prkey(lun, msg->pr.pr_info.residx);
		if (ctl_get_prkey(lun, msg->pr.pr_info.residx) == 0)
			lun->pr_key_count++;
		ctl_set_prkey(lun, msg->pr.pr_info.residx,
		    scsi_8btou64(msg->pr.pr_info.sa_res_key));
		lun->pr_generation++;
		break;
	case CTL_PR_UNREG_KEY:
		ctl_clr_prkey(lun, msg->pr.pr_info.residx);
		lun->pr_key_count--;
		if (msg->pr.pr_info.residx == lun->pr_res_idx) {
			lun->flags &= ~CTL_LUN_PR_RESERVED;
			lun->pr_res_idx = CTL_PR_NO_RESERVATION;
			if ((lun->pr_res_type == SPR_TYPE_WR_EX_RO ||
			     lun->pr_res_type == SPR_TYPE_EX_AC_RO) &&
			    lun->pr_key_count) {
				for (i = softc->init_min; i < softc->init_max; i++) {
					if (ctl_get_prkey(lun, i) == 0)
						continue;
					ctl_est_ua(lun, i, CTL_UA_RES_RELEASE);
				}
			}
			lun->pr_res_type = 0;
		} else if (lun->pr_res_idx == CTL_PR_ALL_REGISTRANTS) {
			if (lun->pr_key_count==0) {
				lun->flags &= ~CTL_LUN_PR_RESERVED;
				lun->pr_res_type = 0;
				lun->pr_res_idx = CTL_PR_NO_RESERVATION;
			}
		}
		lun->pr_generation++;
		break;
	case CTL_PR_RESERVE:
		lun->flags |= CTL_LUN_PR_RESERVED;
		lun->pr_res_type = msg->pr.pr_info.res_type;
		lun->pr_res_idx = msg->pr.pr_info.residx;
		break;
	case CTL_PR_RELEASE:
		if (lun->pr_res_type != SPR_TYPE_EX_AC &&
		    lun->pr_res_type != SPR_TYPE_WR_EX) {
			for (i = softc->init_min; i < softc->init_max; i++)
				if (i == residx || ctl_get_prkey(lun, i) == 0)
					continue;
				ctl_est_ua(lun, i, CTL_UA_RES_RELEASE);
		}
		lun->flags &= ~CTL_LUN_PR_RESERVED;
		lun->pr_res_idx = CTL_PR_NO_RESERVATION;
		lun->pr_res_type = 0;
		break;
	case CTL_PR_PREEMPT:
		ctl_pro_preempt_other(lun, msg);
		break;
	case CTL_PR_CLEAR:
		lun->flags &= ~CTL_LUN_PR_RESERVED;
		lun->pr_res_type = 0;
		lun->pr_key_count = 0;
		lun->pr_res_idx = CTL_PR_NO_RESERVATION;
		for (i=0; i < CTL_MAX_INITIATORS; i++) {
			if (ctl_get_prkey(lun, i) == 0)
				continue;
			ctl_clr_prkey(lun, i);
			ctl_est_ua(lun, i, CTL_UA_REG_PREEMPT);
		}
		lun->pr_generation++;
		break;
	}
	mtx_unlock(&lun->lun_lock);
}
static void ctl_hndl_per_res_out_on_other_sc ( union ctl_ha_msg * msg ) { struct ctl_softc * softc = control_softc ; struct ctl_lun * lun ; int i ; uint32_t residx , targ_lun ; targ_lun = msg -> hdr . nexus . targ_mapped_lun ; mtx_lock ( & softc -> ctl_lock ) ; if ( ( targ_lun >= CTL_MAX_LUNS ) || ( ( lun = softc -> ctl_luns [ targ_lun ] ) == NULL ) ) { mtx_unlock ( & softc -> ctl_lock ) ; return ; } mtx_lock ( & lun -> lun_lock ) ; mtx_unlock ( & softc -> ctl_lock ) ; if ( lun -> flags & CTL_LUN_DISABLED ) { mtx_unlock ( & lun -> lun_lock ) ; return ; } residx = ctl_get_initindex ( & msg -> hdr . nexus ) ; switch ( msg -> pr . pr_info . action ) { case CTL_PR_REG_KEY : ctl_alloc_prkey ( lun , msg -> pr . pr_info . residx ) ; if ( ctl_get_prkey ( lun , msg -> pr . pr_info . residx ) == 0 ) lun -> pr_key_count ++ ; ctl_set_prkey ( lun , msg -> pr . pr_info . residx , scsi_8btou64 ( msg -> pr . pr_info . sa_res_key ) ) ; lun -> pr_generation ++ ; break ; case CTL_PR_UNREG_KEY : ctl_clr_prkey ( lun , msg -> pr . pr_info . residx ) ; lun -> pr_key_count -- ; if ( msg -> pr . pr_info . residx == lun -> pr_res_idx ) { lun -> flags &= ~ CTL_LUN_PR_RESERVED ; lun -> pr_res_idx = CTL_PR_NO_RESERVATION ; if ( ( lun -> pr_res_type == SPR_TYPE_WR_EX_RO || lun -> pr_res_type == SPR_TYPE_EX_AC_RO ) && lun -> pr_key_count ) { for ( i = softc -> init_min ; i < softc -> init_max ; i ++ ) { if ( ctl_get_prkey ( lun , i ) == 0 ) continue ; ctl_est_ua ( lun , i , CTL_UA_RES_RELEASE ) ; } } lun -> pr_res_type = 0 ; } else if ( lun -> pr_res_idx == CTL_PR_ALL_REGISTRANTS ) { if ( lun -> pr_key_count == 0 ) { lun -> flags &= ~ CTL_LUN_PR_RESERVED ; lun -> pr_res_type = 0 ; lun -> pr_res_idx = CTL_PR_NO_RESERVATION ; } } lun -> pr_generation ++ ; break ; case CTL_PR_RESERVE : lun -> flags |= CTL_LUN_PR_RESERVED ; lun -> pr_res_type = msg -> pr . pr_info . res_type ; lun -> pr_res_idx = msg -> pr . pr_info . residx ; break ; case CTL_PR_RELEASE : if ( lun -> pr_res_type != SPR_TYPE_EX_AC && lun -> pr_res_type != SPR_TYPE_WR_EX ) { for ( i = softc -> init_min ; i < softc -> init_max ; i ++ ) if ( i == residx || ctl_get_prkey ( lun , i ) == 0 ) continue ; ctl_est_ua ( lun , i , CTL_UA_RES_RELEASE ) ; } lun -> flags &= ~ CTL_LUN_PR_RESERVED ; lun -> pr_res_idx = CTL_PR_NO_RESERVATION ; lun -> pr_res_type = 0 ; break ; case CTL_PR_PREEMPT : ctl_pro_preempt_other ( lun , msg ) ; break ; case CTL_PR_CLEAR : lun -> flags &= ~ CTL_LUN_PR_RESERVED ; lun -> pr_res_type = 0 ; lun -> pr_key_count = 0 ; lun -> pr_res_idx = CTL_PR_NO_RESERVATION ; for ( i = 0 ; i < CTL_MAX_INITIATORS ; i ++ ) { if ( ctl_get_prkey ( lun , i ) == 0 ) continue ; ctl_clr_prkey ( lun , i ) ; ctl_est_ua ( lun , i , CTL_UA_REG_PREEMPT ) ; } lun -> pr_generation ++ ; break ; } mtx_unlock ( & lun -> lun_lock ) ; }
This routine is for handling a message from the other SC pertaining to
 persistent reserve out.
This routine is for handling a message from the other SC pertaining to persistent reserve out .
/* XXX Need to see if the reservation has been released */ /* if so do we need to generate UA? */ /*
				 * If the reservation is a registrants
				 * only type we need to generate a UA
				 * for other registered inits.  The
				 * sense code should be RESERVATIONS
				 * RELEASED
				 */ /*
		 * if this isn't an exclusive access res generate UA for all
		 * other registrants.
		 */