Blame IbAccess/Common/Ibt/Sma/smamain.c

Packit 857059
/* BEGIN_ICS_COPYRIGHT4 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
     documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT4   ****************************************/
Packit 857059
Packit 857059
#include "smamain.h"
Packit 857059
Packit 857059
// Globals
Packit 857059
Packit 857059
Packit 857059
// Debug params
Packit 857059
#ifdef ICS_LOGGING
Packit 857059
_IB_DBG_PARAM_BLOCK((_DBG_LVL_FATAL|_DBG_LVL_ERROR), _DBG_BREAK_ENABLE, SMA_MEM_TAG, "Sma", MOD_SMA, Sma);
Packit 857059
#else
Packit 857059
_IB_DBG_PARAM_BLOCK((_DBG_LVL_FATAL|_DBG_LVL_ERROR), _DBG_BREAK_ENABLE, SMA_MEM_TAG, "Sma");
Packit 857059
#endif
Packit 857059
Packit 857059
// Global Info
Packit 857059
SMA_GLOBAL_INFO	*g_Sma;
Packit 857059
Packit 857059
// Stored settings
Packit 857059
SMA_STORED_SETTINGS g_Settings = DEFAULT_SMA_SETTINGS;
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// SmaLoad
Packit 857059
//
Packit 857059
// This routine is called by the VCA Init when the driver is first loaded. 
Packit 857059
// This routine is to create and initialize driver data structures.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	ComponentInfo - Pointer to ComponentInfo that is OS specific
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSUCCESS - Indicates a successful load.
Packit 857059
//
Packit 857059
// IRQL:
Packit 857059
//
Packit 857059
//	This routine is called at IRQL_PASSIVE_LEVEL.
Packit 857059
//
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SMALoad(
Packit 857059
	IN IBT_COMPONENT_INFO	 *ComponentInfo
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS				status = FSUCCESS;
Packit 857059
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaLoad);
Packit 857059
	_DBG_INIT;
Packit 857059
	
Packit 857059
	_TRC_REGISTER();
Packit 857059
Packit 857059
#if !defined(VXWORKS)
Packit 857059
	_DBG_PRINT(_DBG_LVL_MAIN,  
Packit 857059
	(" InfiniBand Subnet Management Agent. Built %s %s\n",\
Packit 857059
	__DATE__, __TIME__ ));
Packit 857059
#else
Packit 857059
	_DBG_PRINT(_DBG_LVL_MAIN,  
Packit 857059
	(" InfiniBand Subnet Management Agent. Built %s %s\n",\
Packit 857059
	_DBG_PTR(__DATE__), _DBG_PTR(__TIME__) ));
Packit 857059
#endif
Packit 857059
Packit 857059
    // Establish dispatch entry points for the functions supported.
Packit 857059
	MemoryClear( ComponentInfo, sizeof(IBT_COMPONENT_INFO) );
Packit 857059
	
Packit 857059
	ComponentInfo->AddDevice = SmaAddDevice;
Packit 857059
	ComponentInfo->RemoveDevice = SmaRemoveDevice;
Packit 857059
	ComponentInfo->Unload = SMAUnload;
Packit 857059
Packit 857059
    // Read Global settings for the driver which may be set in a 
Packit 857059
	// OS specific way.
Packit 857059
	SmaInitGlobalSettings();
Packit 857059
	
Packit 857059
	// Allocate space for Global data
Packit 857059
	g_Sma = (SMA_GLOBAL_INFO*)MemoryAllocate2AndClear(sizeof(SMA_GLOBAL_INFO), IBA_MEM_FLAG_PREMPTABLE, SMA_MEM_TAG);
Packit 857059
	if ( NULL == g_Sma )
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("MemAlloc failed for g_Sma!\n"));
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	// initialize global data
Packit 857059
	g_Sma->NumCa = 0;
Packit 857059
	g_Sma->CaObj = NULL;
Packit 857059
	g_Sma->WorkReqRecv = g_Sma->WorkReqSend = NULL;
Packit 857059
Packit 857059
	g_Sma->SmUserTbl = NULL;
Packit 857059
	g_Sma->NumUser = 0;
Packit 857059
Packit 857059
	// SpinLockInitState( &g_Sma->Lock )
Packit 857059
	// SpinLockInit( &g_Sma->Lock )
Packit 857059
Packit 857059
	// Init Storage area for MADs
Packit 857059
	g_Sma->Bin.NumBlocks = 0;
Packit 857059
	g_Sma->Bin.Head = g_Sma->Bin.Tail = NULL;
Packit 857059
	g_Sma->Bin.MemList = NULL;
Packit 857059
	g_Sma->Bin.CurrentIndex = 0;			// set start mem index
Packit 857059
Packit 857059
	// Locks
Packit 857059
	SpinLockInitState( &g_Sma->CaListLock );
Packit 857059
	SpinLockInit( &g_Sma->CaListLock );
Packit 857059
	SpinLockInitState( &g_Sma->Bin.Lock );
Packit 857059
	SpinLockInit( &g_Sma->Bin.Lock );
Packit 857059
	MutexInitState( &g_Sma->Bin.Mutex );
Packit 857059
	MutexInit( &g_Sma->Bin.Mutex );
Packit 857059
	SpinLockInitState( &g_Sma->RQ.Lock );
Packit 857059
	SpinLockInit( &g_Sma->RQ.Lock );
Packit 857059
	
Packit 857059
	// Init Global Ibt user group for notifications
Packit 857059
	IbtInitNotifyGroup(NotifyIbtCallback);
Packit 857059
Packit 857059
	// Allocate memory for Global GRH since the SMA does not need a GRH.
Packit 857059
	// This memory will automatically get mapped to all CA registrations.
Packit 857059
	g_Sma->GlobalGrh = CreateGlobalMemList( 0, sizeof(IB_GRH), 0, FALSE );
Packit 857059
	if ( NULL == g_Sma->GlobalGrh )
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_RESOURCES;
Packit 857059
		goto failmemlist;
Packit 857059
	}
Packit 857059
		
Packit 857059
	g_Sma->GlobalGrh->VirtualAddr = MemoryAllocate2AndClear(sizeof(IB_GRH), IBA_MEM_FLAG_PREMPTABLE, SMA_MEM_TAG);
Packit 857059
	if ( NULL == g_Sma->GlobalGrh->VirtualAddr )
Packit 857059
	{
Packit 857059
		status = FINSUFFICIENT_RESOURCES;
Packit 857059
		goto failgrhvirt;
Packit 857059
	}
Packit 857059
	g_Sma->GlobalGrh->AccessControl.AsUINT16 = 0;
Packit 857059
	g_Sma->GlobalGrh->AccessControl.s.LocalWrite = 1;
Packit 857059
	g_Sma->GlobalGrh->CaMemIndex = 0;
Packit 857059
Packit 857059
	// Increment index for future allocations
Packit 857059
	g_Sma->Bin.CurrentIndex++;
Packit 857059
Packit 857059
done:
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
    return status;
Packit 857059
Packit 857059
failgrhvirt:
Packit 857059
	MemoryDeallocate( g_Sma->GlobalGrh );
Packit 857059
failmemlist:
Packit 857059
	IbtDestroyNotifyGroup();
Packit 857059
	SpinLockDestroy( &g_Sma->RQ.Lock );
Packit 857059
	MutexDestroy( &g_Sma->Bin.Mutex );
Packit 857059
	SpinLockDestroy( &g_Sma->Bin.Lock );
Packit 857059
	SpinLockDestroy( &g_Sma->CaListLock );
Packit 857059
	MemoryDeallocate( g_Sma );
Packit 857059
	goto done;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// SmaUnload
Packit 857059
//
Packit 857059
//	This routine should release resources allocated in the SmaLoad function. 
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSUCCESS - Successful unload of SMA.
Packit 857059
//
Packit 857059
//	This routine is called at IRQL_PASSIVE_LEVEL.
Packit 857059
//
Packit 857059
void
Packit 857059
SMAUnload(void)
Packit 857059
{
Packit 857059
	GLOBAL_MEM_LIST		*pMemList;
Packit 857059
	
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaUnload);
Packit 857059
Packit 857059
	// there should be no CAs at this point, all VPD must be unloaded
Packit 857059
	// before IbAccess
Packit 857059
	ASSERT(0 == g_Sma->NumCa);
Packit 857059
	ASSERT(NULL == g_Sma->CaObj);
Packit 857059
Packit 857059
	// Free up global memory
Packit 857059
	//
Packit 857059
	//Note: Global Grh gets freed automatically here
Packit 857059
	for (pMemList = g_Sma->Bin.MemList; NULL != pMemList; )
Packit 857059
	{
Packit 857059
		GLOBAL_MEM_LIST	*pMemListNext;
Packit 857059
		pMemListNext = (GLOBAL_MEM_LIST*)pMemList->Next;
Packit 857059
		MemoryDeallocate( pMemList->VirtualAddr );	// registered SMP emm
Packit 857059
		if (pMemList->HdrAddr )
Packit 857059
			MemoryDeallocate( pMemList->HdrAddr );	// SmpBlock memory
Packit 857059
		MemoryDeallocate( pMemList );
Packit 857059
		pMemList = pMemListNext;
Packit 857059
	}
Packit 857059
Packit 857059
	_TRC_UNREGISTER();
Packit 857059
Packit 857059
	// Remove user list
Packit 857059
	if ( NULL != g_Sma->SmUserTbl )
Packit 857059
		MemoryDeallocate( g_Sma->SmUserTbl );
Packit 857059
Packit 857059
	IbtDestroyNotifyGroup();
Packit 857059
Packit 857059
	// Locks
Packit 857059
	MutexDestroy( &g_Sma->Bin.Mutex );
Packit 857059
	SpinLockDestroy( &g_Sma->Bin.Lock );
Packit 857059
	SpinLockDestroy( &g_Sma->RQ.Lock );
Packit 857059
	SpinLockDestroy( &g_Sma->CaListLock );
Packit 857059
		
Packit 857059
	MemoryDeallocate( g_Sma );
Packit 857059
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// SmaAddDevice
Packit 857059
//
Packit 857059
// This routine is called by the VCA Startdevice loop for all driver libs. 
Packit 857059
// The CA device that just started will be identified by its GUID.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	CaGUID - GUID to the CA that was added and started.
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSTATUS.
Packit 857059
//
Packit 857059
// IRQL:
Packit 857059
//
Packit 857059
//	This routine is called at IRQL_PASSIVE_LEVEL.
Packit 857059
//
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SmaAddDevice(
Packit 857059
	IN	EUI64			CaGuid,
Packit 857059
	OUT void			**Context
Packit 857059
	)
Packit 857059
{
Packit 857059
	FSTATUS				status = FSUCCESS;
Packit 857059
	SMA_CA_OBJ_PRIVATE	*pCaObj=NULL;
Packit 857059
	uint32				i;
Packit 857059
	
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaAddDevice);
Packit 857059
Packit 857059
	pCaObj = (SMA_CA_OBJ_PRIVATE*)MemoryAllocateAndClear(sizeof(SMA_CA_OBJ_PRIVATE), FALSE, SMA_MEM_TAG);
Packit 857059
	if ( NULL == pCaObj ) 
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("MemAlloc failed for pCaObj/WorkReq!\n"));
Packit 857059
		status = FINSUFFICIENT_MEMORY;
Packit 857059
		goto done;
Packit 857059
	}
Packit 857059
Packit 857059
	pCaObj->CaPublic.CaGuid = CaGuid;
Packit 857059
	pCaObj->CaPublic.SmaCaContext = pCaObj;
Packit 857059
Packit 857059
	EventThreadInitState(&pCaObj->SmaEventThread);
Packit 857059
	if (! EventThreadCreate(&pCaObj->SmaEventThread, "Smi",
Packit 857059
		THREAD_PRI_VERY_HIGH, SmaCompletionCallback, pCaObj))
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("Sma Event Thread Create FAILED\n"));
Packit 857059
		goto failsmathread;
Packit 857059
	}
Packit 857059
		
Packit 857059
	EventThreadInitState(&pCaObj->GsaEventThread);
Packit 857059
	if (! EventThreadCreate(&pCaObj->GsaEventThread, "Gsi",
Packit 857059
		THREAD_PRI_VERY_HIGH, GsaCompletionThreadCallback, pCaObj))
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("Gsa Event Thread Create FAILED\n"));
Packit 857059
		goto failgsathread;
Packit 857059
	}
Packit 857059
Packit 857059
	status = iba_open_ca( CaGuid, SmaGsaCompletionCallback,
Packit 857059
				SmaAsyncEventCallback, pCaObj/*Context*/, &pCaObj->CaHandle);
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("OpenCA() failed!\n"));
Packit 857059
		goto failopen;
Packit 857059
	}
Packit 857059
	status = SetCAInternal(pCaObj->CaHandle);
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		_DBG_ERROR(("SetCAInternal() failed!\n"));
Packit 857059
		goto failinternal;
Packit 857059
	}
Packit 857059
Packit 857059
	// Reserve CQ/QP/PD...
Packit 857059
	status = SmaDeviceReserve( pCaObj );
Packit 857059
	if ( FSUCCESS != status )
Packit 857059
	{
Packit 857059
		goto failreserve;
Packit 857059
	}
Packit 857059
	// we hold the Mutex across Bind and addition to Ca list
Packit 857059
	// so that CreateDgrmPool cannot race and cause double
Packit 857059
	// registration of memory in new DgrmPool
Packit 857059
	AcquireMemListMutex();
Packit 857059
	status = SmaBindGlobalMem( pCaObj );
Packit 857059
	if (status != FSUCCESS)
Packit 857059
	{
Packit 857059
		ReleaseMemListMutex();
Packit 857059
		// TBD need to undo SmaDeviceReserve
Packit 857059
		goto failreserve;
Packit 857059
	}
Packit 857059
Packit 857059
	// lock
Packit 857059
Packit 857059
	// update global info
Packit 857059
	SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
	g_Sma->NumCa++;
Packit 857059
	pCaObj->Next = g_Sma->CaObj;
Packit 857059
	pCaObj->Prev = NULL;
Packit 857059
	if ( NULL != g_Sma->CaObj )
Packit 857059
		g_Sma->CaObj->Prev = pCaObj;
Packit 857059
	g_Sma->CaObj = pCaObj;
Packit 857059
	pCaObj->UseCount++;	// hold reference so we can use object below
Packit 857059
	SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
Packit 857059
	ReleaseMemListMutex();
Packit 857059
Packit 857059
	// QPConfig 
Packit 857059
	status = SmaDeviceConfig( pCaObj, QPTypeSMI );
Packit 857059
	status = SmaDeviceConfig( pCaObj, QPTypeGSI );
Packit 857059
Packit 857059
	// Create GSA data structures
Packit 857059
	GsaUpdateCaList();
Packit 857059
Packit 857059
	// Preallocate Buffers based on per device.
Packit 857059
	// If we know the amount of buffers we need per device and go ahead
Packit 857059
	// and allocate them in advance, subnet sweeps will not allocate
Packit 857059
	// any buffers in the speed path
Packit 857059
	//
Packit 857059
	// NOTE: This call can fail if there are no system resources
Packit 857059
	SmaAllocToBin( g_Settings.PreAllocSMPsPerDevice, FALSE );
Packit 857059
	
Packit 857059
	// post some descriptors on recv side if port is up or something...
Packit 857059
	for (i=0; i<pCaObj->CaPublic.Ports; i++)
Packit 857059
	{
Packit 857059
		status = iba_smi_post_recv( NULL, pCaObj, (uint8)(i+1), 
Packit 857059
							g_Settings.MinSMPsToPostPerPort );	
Packit 857059
	}
Packit 857059
Packit 857059
	// Set Port capabilities across all CA's
Packit 857059
	SetPortCapabilities();
Packit 857059
Packit 857059
	// Rearm CQ to receive event notifications.
Packit 857059
	// The next Work Completion written to the CQ 
Packit 857059
	// will generate an event
Packit 857059
	status = iba_rearm_cq( pCaObj->CqHandle, CQEventSelNextWC);						
Packit 857059
	SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
	pCaObj->UseCount--;
Packit 857059
	SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
Packit 857059
	// Bind 
Packit 857059
		
Packit 857059
	// unlock
Packit 857059
Packit 857059
	// notify users through callbacks!
Packit 857059
	IbtNotifyGroup( CaGuid, IB_NOTIFY_CA_ADD );
Packit 857059
	// TBD - failure above causes bad status return here, can confuse caller
Packit 857059
	// also does not cleanup QPs, CQ, PD, MRs, buffers
Packit 857059
	// SmaRemoveCaObj might solve, but not clear if safe to call it
Packit 857059
	// need some peers to the SmaDeviceReserve and SmaDeviceConfig routines
Packit 857059
	// to undo their effects
Packit 857059
Packit 857059
done:
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
      
Packit 857059
    return status;
Packit 857059
Packit 857059
failreserve:
Packit 857059
failinternal:
Packit 857059
	iba_close_ca( pCaObj->CaHandle );
Packit 857059
failopen:
Packit 857059
	EventThreadDestroy(&pCaObj->GsaEventThread);
Packit 857059
failgsathread:
Packit 857059
	EventThreadDestroy(&pCaObj->SmaEventThread);
Packit 857059
failsmathread:
Packit 857059
	MemoryDeallocate( pCaObj );
Packit 857059
	goto done;
Packit 857059
}
Packit 857059
Packit 857059
Packit 857059
//
Packit 857059
// SmaRemoveDevice
Packit 857059
//
Packit 857059
// This routine is called by the VCA Removedevice loop for all driver libs. 
Packit 857059
// The CA device that was removed will be identified by its GUID.
Packit 857059
//
Packit 857059
// INPUTS:
Packit 857059
//
Packit 857059
//	CaGUID - GUID to the CA that was added and started.
Packit 857059
//
Packit 857059
// OUTPUTS:
Packit 857059
//
Packit 857059
//	None.
Packit 857059
//
Packit 857059
// RETURNS:
Packit 857059
//
Packit 857059
//	FSTATUS.
Packit 857059
//
Packit 857059
// IRQL:
Packit 857059
//
Packit 857059
//	This routine is called at IRQL_PASSIVE_LEVEL.
Packit 857059
//
Packit 857059
Packit 857059
FSTATUS
Packit 857059
SmaRemoveDevice(
Packit 857059
		IN EUI64	CaGuid,
Packit 857059
		IN void		*Context
Packit 857059
		)
Packit 857059
{
Packit 857059
	FSTATUS				status = FSUCCESS;
Packit 857059
	SMA_CA_OBJ_PRIVATE	*pCaObj;
Packit 857059
	
Packit 857059
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaRemoveDevice);
Packit 857059
Packit 857059
	// notify users through callbacks
Packit 857059
	// SM should stop access to all registered memory on this Ca
Packit 857059
	IbtNotifyGroup( CaGuid, IB_NOTIFY_CA_REMOVE );
Packit 857059
	
Packit 857059
	// lock
Packit 857059
Packit 857059
	// find CaObj
Packit 857059
	SpinLockAcquire(&g_Sma->CaListLock);
Packit 857059
	for (pCaObj = g_Sma->CaObj; NULL != pCaObj; pCaObj = pCaObj->Next)
Packit 857059
	{
Packit 857059
		if ( CaGuid == pCaObj->CaPublic.CaGuid )
Packit 857059
			break;
Packit 857059
	}
Packit 857059
Packit 857059
	if ( NULL != pCaObj )
Packit 857059
	{
Packit 857059
		pCaObj->UseCount++;
Packit 857059
		SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
		status = SmaRemoveCaObj( pCaObj );	// will release reference to pCaObj
Packit 857059
	} else {
Packit 857059
		SpinLockRelease(&g_Sma->CaListLock);
Packit 857059
		_DBG_ERROR(("Could not find CA device!\n"));
Packit 857059
	}
Packit 857059
Packit 857059
	// Rebuild CA list for GSA
Packit 857059
	GsaUpdateCaList();
Packit 857059
Packit 857059
	// unlock
Packit 857059
	
Packit 857059
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
Packit 857059
Packit 857059
    return status;
Packit 857059
}