|
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 |
}
|