コード例 #1
0
ファイル: bmamain.c プロジェクト: 01org/opa-ff
//////////////////////////////////////////////////////////////////////////
// BmaRemoveDevice()
//
// This routine is called once for every CA device being removed.  Nothing
//	is performed in this function.  All cleanup is performed in the BmaUnload
//	function.
//
// INPUTS:
//		CaGuid - the channel adapters GUID
//		Context - driver defined unique context for this CA
//
// OUTPUTS:
//
//	None.
//
// RETURNS:
//
//	FSUCCESS - Indicates a successful initialization.
//
//
FSTATUS
BmaRemoveDevice(
	IN	EUI64			CaGuid,
	IN void				*Context
	)
{
	FSTATUS			status = FSUCCESS;
	BMA_DEV_INFO	*pDevInfo=NULL;

	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaRemoveDevice);

	ASSERT(g_BmaGlobalInfo);

	SpinLockAcquire( &g_BmaGlobalInfo->DevListLock );
	pDevInfo = g_BmaGlobalInfo->DevList;
	if ( g_BmaGlobalInfo->DevList->CaGuid == CaGuid )
	{
		g_BmaGlobalInfo->DevList = pDevInfo->Next;
	}
	else
	{
		while ( pDevInfo->Next )
		{
			if ( pDevInfo->Next->CaGuid == CaGuid )
			{
				BMA_DEV_INFO *Found = pDevInfo->Next;
				pDevInfo->Next = Found->Next;
				pDevInfo = Found;
				break;
			}
			pDevInfo = pDevInfo->Next;
		}
	}
	SpinLockRelease( &g_BmaGlobalInfo->DevListLock );

	if (pDevInfo && pDevInfo->CaGuid == CaGuid)
	{
		MemoryDeallocate( pDevInfo->Port );
		MemoryDeallocate( pDevInfo );
	}
	else
	{
		_DBG_ERROR(("Unable to find Ca with GUID 0x%"PRIx64"\n", CaGuid));
		status = FERROR;
	}

	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);

	return status;

} // BmaRemoveDevice()
コード例 #2
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
// reaper callback
static void
ReapTrapReference(LIST_ITEM *pItem)
{
	// Reaper uses QListObj, so we must use PARENT_STRUCT
	TRAP_REFERENCE *pTrapReference = PARENT_STRUCT(pItem, TRAP_REFERENCE, ListItem);
	TimerDestroy(&pTrapReference->Timer);
	MemoryDeallocate(pTrapReference);
}
コード例 #3
0
ファイル: smamain.c プロジェクト: 01org/opa-ff
//
// SmaUnload
//
//	This routine should release resources allocated in the SmaLoad function. 
//
// INPUTS:
//
//	None.
//
// OUTPUTS:
//
//	None.
//
// RETURNS:
//
//	FSUCCESS - Successful unload of SMA.
//
//	This routine is called at IRQL_PASSIVE_LEVEL.
//
void
SMAUnload(void)
{
	GLOBAL_MEM_LIST		*pMemList;
	
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaUnload);

	// there should be no CAs at this point, all VPD must be unloaded
	// before IbAccess
	ASSERT(0 == g_Sma->NumCa);
	ASSERT(NULL == g_Sma->CaObj);

	// Free up global memory
	//
	//Note: Global Grh gets freed automatically here
	for (pMemList = g_Sma->Bin.MemList; NULL != pMemList; )
	{
		GLOBAL_MEM_LIST	*pMemListNext;
		pMemListNext = (GLOBAL_MEM_LIST*)pMemList->Next;
		MemoryDeallocate( pMemList->VirtualAddr );	// registered SMP emm
		if (pMemList->HdrAddr )
			MemoryDeallocate( pMemList->HdrAddr );	// SmpBlock memory
		MemoryDeallocate( pMemList );
		pMemList = pMemListNext;
	}

	_TRC_UNREGISTER();

	// Remove user list
	if ( NULL != g_Sma->SmUserTbl )
		MemoryDeallocate( g_Sma->SmUserTbl );

	IbtDestroyNotifyGroup();

	// Locks
	MutexDestroy( &g_Sma->Bin.Mutex );
	SpinLockDestroy( &g_Sma->Bin.Lock );
	SpinLockDestroy( &g_Sma->RQ.Lock );
	SpinLockDestroy( &g_Sma->CaListLock );
		
	MemoryDeallocate( g_Sma );

	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
}
コード例 #4
0
ファイル: keyboard.c プロジェクト: 0664j35t3r/sweb
void KeyboardDeallocate(struct UsbDevice *device) {
  struct KeyboardDevice *data;
  
  data = (struct KeyboardDevice*)((struct HidDevice*)device->DriverData)->DriverData;
  if (data != NULL) {
    MemoryDeallocate(data);
    ((struct HidDevice*)device->DriverData)->DriverData = NULL;
  }
  ((struct HidDevice*)device->DriverData)->HidDeallocate = NULL;
  ((struct HidDevice*)device->DriverData)->HidDetached = NULL;
}
コード例 #5
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
// must be called with SubscribedTrapsListLock held
static
void IssueTrapUnSubscribe(TRAP_REFERENCE *pTrapReference)
{
	FSTATUS               Status;
	FABRIC_OPERATION_DATA *pFabOp;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, IssueTrapUnSubscribe);
	
	pFabOp = (FABRIC_OPERATION_DATA*)MemoryAllocate2AndClear( sizeof(FABRIC_OPERATION_DATA), IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG );
	if ( pFabOp == NULL )
	{
		_DBG_ERROR(("SubscribeForTrap MemoryAllocateError\n"));
		QueueTrapTimer(pTrapReference, RETRY_DELAY);	// try again later
	} else {
		pFabOp->Type = FabOpSetInformInfo;
		memset(&pFabOp->Value.InformInfo.GID, 0, sizeof(pFabOp->Value.InformInfo.GID));
		pFabOp->Value.InformInfo.LIDRangeBegin = LID_PERMISSIVE;
		pFabOp->Value.InformInfo.LIDRangeEnd = 0;
		pFabOp->Value.InformInfo.Reserved = 0;
		pFabOp->Value.InformInfo.IsGeneric = 1;
		pFabOp->Value.InformInfo.Subscribe = 0;
		pFabOp->Value.InformInfo.Type = IB_NOTICE_ALL;

		pFabOp->Value.InformInfo.u.Generic.TrapNumber = pTrapReference->TrapNumber;
		pFabOp->Value.InformInfo.u.Generic.u2.s.QPNumber = GSI_QP;
		pFabOp->Value.InformInfo.u.Generic.u2.s.RespTimeValue = 18;
		pFabOp->Value.InformInfo.u.Generic.u.s.ProducerType = STL_NODE_FI;

		Status = iba_sd_port_fabric_operation( SdClientHandle, pTrapReference->PortGuid, pFabOp, ProcessTrapSubscribeResponse, NULL, pTrapReference );
		if ((Status != FPENDING) && (Status != FSUCCESS))
		{
			/* Port may not yet be active.
			 * ReRegisterTrapSubscriptions will be called when it goes active
			 * but we queue a slow timer just in case operation failed for
			 * another reason (such as low memory, etc)
			 */
			/* _DBG_ERROR(("PortFabricOperation Status = %d\n", Status)); */
			QueueTrapTimer(pTrapReference, PORT_DOWN_DELAY);// try again later
		} else {
			// to be conservative, assume we are unsubscribed, just in case
			// SA processes request, but delivers response late
			// also avoids us retrying unsubscribe in event SM is down
			pTrapReference->Flags = (TRAP_REFERENCE_FLAGS)(pTrapReference->Flags & ~TRAP_REF_FLAGS_SUBSCRIBED);
			pTrapReference->Flags = (TRAP_REFERENCE_FLAGS)(pTrapReference->Flags | TRAP_REF_FLAGS_OPQUEUED);
		}

		MemoryDeallocate( pFabOp );
	}

	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
}
コード例 #6
0
ファイル: bmamain.c プロジェクト: 01org/opa-ff
//
// BmaUnload
//
//	This routine should release resources allocated in the BmaLoad function.
//	Also, since their is a single instance of the service for all channel
//	adapters in the system, it will also release resources allocated in the
//	BmaAddDevice function. 
//
// INPUTS:
//
//	None.
//
// OUTPUTS:
//
//	None.
//
// RETURNS:
//
//	None
//
//
void
BmaUnload(void)
{

	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaUnload);

	_TRC_UNREGISTER();

	if ( g_BmaGlobalInfo )
	{

		// Destroy the datagram pool
		if ( g_BmaGlobalInfo->DgrmPoolHandle )
			iba_gsi_destroy_dgrm_pool( g_BmaGlobalInfo->DgrmPoolHandle );

		// Deregister this class agent with the GSA	
		if ( g_BmaGlobalInfo->GsaHandle )
			iba_gsi_deregister_class(g_BmaGlobalInfo->GsaHandle);

		//
		// Recv Thread
		//
		CmdThreadDestroy(&g_BmaGlobalInfo->RecvThread);
				
		//
		// Ca List Members
		//
		while ( g_BmaGlobalInfo->DevList )
		{
			BmaRemoveDevice( g_BmaGlobalInfo->DevList->CaGuid, NULL );
		}

		//
		// Ca List Lock
		//
		SpinLockDestroy( &g_BmaGlobalInfo->DevListLock );


		//
		// Free up global memory
		//
		MemoryDeallocate( g_BmaGlobalInfo );
		g_BmaGlobalInfo = NULL;

	} // if g_BmaGlobalInfo

	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
  

}
コード例 #7
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
FSTATUS
iba_sd_trap_notice_unsubscribe(CLIENT_HANDLE ClientHandle, uint16 TrapNumber, EUI64 PortGuid)
{
	FSTATUS                   Status;
	CLIENT_CONTROL_PARAMETERS ClientParams;
	ClientListEntry           *pClientEntry = (ClientListEntry *)ClientHandle;
	CLIENT_TRAP_INFO          *pClientTrapInfo;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, iba_sd_trap_notice_unsubscribe);

	Status = ValidateClientHandle(ClientHandle, &ClientParams);
	if (Status != FSUCCESS)
	{
		_DBG_ERROR(("Invalid Client Handle Specified\n"));
		goto exit;
	}

	SpinLockAcquire(pClientListLock);

	pClientTrapInfo = FindClientTrapInfo(&pClientEntry->ClientTraps, TrapNumber, PortGuid);
	if (pClientTrapInfo == NULL)
	{
		// Not Found
		Status = FERROR;
		SpinLockRelease(pClientListLock);
		goto exit;
	}

	QListRemoveItem(&pClientEntry->ClientTraps, &pClientTrapInfo->ListItem);

	SpinLockRelease(pClientListLock);

	MemoryDeallocate(pClientTrapInfo);

	DecrementTrapUsageCount(TrapNumber, PortGuid);

exit:
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
	return Status;
}
コード例 #8
0
ファイル: oib_utils.c プロジェクト: andyw-lala/opa-fm
/** ========================================================================= */
int oib_open_port_by_num (struct oib_port **port, int hfiNum, uint8_t port_num)
{
	FSTATUS fstatus;
	char name[IBV_SYSFS_NAME_MAX];
	int  num = -1;
	uint32_t ca_count;
	uint32_t port_count;
	IB_PORT_ATTRIBUTES	*attrib = NULL;
	int ret_code;
	
    fstatus = oib_get_portguid(hfiNum, port_num, NULL, NULL, NULL, NULL, &attrib,
			       &ca_count, &port_count, name, &num, NULL);
	if (fstatus != FSUCCESS) {
		if (fstatus != FNOT_FOUND ||
		(ca_count == 0 || port_count == 0) ||
		hfiNum > ca_count || port_num > port_count) {
			ret_code=EIO;
			goto done;
		}
		/* no active port was found for wildcard ca/port.
		 * return EAGAIN so caller could query specific port/ca
		 */
		ret_code=EAGAIN;
		goto done;
	}

	ret_code = oib_open_port(port, name, num);

	// Remember the local guid for pa client
	if (ret_code >= 0 && port && *port && attrib) 
	{
		(*port)->local_gid = attrib->GIDTable[0];
	}
	
	done:
		if (attrib)
			MemoryDeallocate(attrib);
		return ret_code;
}
コード例 #9
0
ファイル: gsamgmt.c プロジェクト: 01org/opa-ff
void
GsaUpdateCaList(void)
{
	if (g_GsaGlobalInfo)
	{
		SpinLockAcquire( &g_GsaGlobalInfo->CaListLock );
	
		if ( g_GsaGlobalInfo->SmObj.CaTbl )
		{
			MemoryDeallocate( g_GsaGlobalInfo->SmObj.CaTbl );
			g_GsaGlobalInfo->SmObj.CaTbl = NULL;
			/* for final RemoveDevice, NumCa = 0 and SmaCreateObj is a Noop
			 * for AddDevice SmaCreateSmaObj will reinitialize NumCa
			 */
			g_GsaGlobalInfo->SmObj.NumCa--;
		}

		SmaCreateSmaObj( &g_GsaGlobalInfo->SmObj );

		SpinLockRelease( &g_GsaGlobalInfo->CaListLock );
	
	}
}
コード例 #10
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
// client is deregistering from SD, remove all their trap registrations
void
UnsubscribeClient(ClientListEntry *pClientEntry)
{
	LIST_ITEM *pClientTrapItem = QListRemoveHead(&pClientEntry->ClientTraps);

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, UnsubscribeClient);

	while (pClientTrapItem != NULL)
	{
		CLIENT_TRAP_INFO *pClientTrapInfo = (CLIENT_TRAP_INFO *)QListObj(pClientTrapItem);

		ASSERT(pClientTrapInfo != NULL);

		DecrementTrapUsageCount(pClientTrapInfo->TrapNumber, pClientTrapInfo->PortGuid);

		MemoryDeallocate(pClientTrapInfo);

		pClientTrapItem = QListRemoveHead(&pClientEntry->ClientTraps);
	}

	QListDestroy(&pClientEntry->ClientTraps);

	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
}
コード例 #11
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
void
SubscribeTerminate()
{
	LIST_ITEM *pTrapReferenceListItem;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, SubscribeTerminate);

	SpinLockAcquire(&SubscribedTrapsListLock);
	SubscribeInitialized = 0;
	SpinLockRelease(&SubscribedTrapsListLock);

	iba_sd_deregister(SdClientHandle);

	/* no more SD callbacks will occur now, so OPQUEUED is not important */
	SpinLockAcquire(&SubscribedTrapsListLock);
	while ( NULL != (pTrapReferenceListItem = QListRemoveHead(&SubscribedTrapsList)))
	{
		TRAP_REFERENCE *pTrapReference = (TRAP_REFERENCE *)QListObj(pTrapReferenceListItem);

		ASSERT(pTrapReference != NULL);
		TimerStop(&pTrapReference->Timer);
		// release lock so TimerDestroy can wait for callback
		SpinLockRelease(&SubscribedTrapsListLock);
		TimerDestroy(&pTrapReference->Timer);

		MemoryDeallocate(pTrapReference);

		SpinLockAcquire(&SubscribedTrapsListLock);
	}
	SpinLockRelease(&SubscribedTrapsListLock);

	QListDestroy(&SubscribedTrapsList);
	SpinLockDestroy(&SubscribedTrapsListLock);

	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
}
コード例 #12
0
ファイル: smamain.c プロジェクト: 01org/opa-ff
FSTATUS
SMALoad(
	IN IBT_COMPONENT_INFO	 *ComponentInfo
	)
{
	FSTATUS				status = FSUCCESS;

	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaLoad);
	_DBG_INIT;
	
	_TRC_REGISTER();

#if !defined(VXWORKS)
	_DBG_PRINT(_DBG_LVL_MAIN,  
	(" InfiniBand Subnet Management Agent. Built %s %s\n",\
	__DATE__, __TIME__ ));
#else
	_DBG_PRINT(_DBG_LVL_MAIN,  
	(" InfiniBand Subnet Management Agent. Built %s %s\n",\
	_DBG_PTR(__DATE__), _DBG_PTR(__TIME__) ));
#endif

    // Establish dispatch entry points for the functions supported.
	MemoryClear( ComponentInfo, sizeof(IBT_COMPONENT_INFO) );
	
	ComponentInfo->AddDevice = SmaAddDevice;
	ComponentInfo->RemoveDevice = SmaRemoveDevice;
	ComponentInfo->Unload = SMAUnload;

    // Read Global settings for the driver which may be set in a 
	// OS specific way.
	SmaInitGlobalSettings();
	
	// Allocate space for Global data
	g_Sma = (SMA_GLOBAL_INFO*)MemoryAllocate2AndClear(sizeof(SMA_GLOBAL_INFO), IBA_MEM_FLAG_PREMPTABLE, SMA_MEM_TAG);
	if ( NULL == g_Sma )
	{
		_DBG_ERROR(("MemAlloc failed for g_Sma!\n"));
		goto done;
	}

	// initialize global data
	g_Sma->NumCa = 0;
	g_Sma->CaObj = NULL;
	g_Sma->WorkReqRecv = g_Sma->WorkReqSend = NULL;

	g_Sma->SmUserTbl = NULL;
	g_Sma->NumUser = 0;

	// SpinLockInitState( &g_Sma->Lock )
	// SpinLockInit( &g_Sma->Lock )

	// Init Storage area for MADs
	g_Sma->Bin.NumBlocks = 0;
	g_Sma->Bin.Head = g_Sma->Bin.Tail = NULL;
	g_Sma->Bin.MemList = NULL;
	g_Sma->Bin.CurrentIndex = 0;			// set start mem index

	// Locks
	SpinLockInitState( &g_Sma->CaListLock );
	SpinLockInit( &g_Sma->CaListLock );
	SpinLockInitState( &g_Sma->Bin.Lock );
	SpinLockInit( &g_Sma->Bin.Lock );
	MutexInitState( &g_Sma->Bin.Mutex );
	MutexInit( &g_Sma->Bin.Mutex );
	SpinLockInitState( &g_Sma->RQ.Lock );
	SpinLockInit( &g_Sma->RQ.Lock );
	
	// Init Global Ibt user group for notifications
	IbtInitNotifyGroup(NotifyIbtCallback);

	// Allocate memory for Global GRH since the SMA does not need a GRH.
	// This memory will automatically get mapped to all CA registrations.
	g_Sma->GlobalGrh = CreateGlobalMemList( 0, sizeof(IB_GRH), 0, FALSE );
	if ( NULL == g_Sma->GlobalGrh )
	{
		status = FINSUFFICIENT_RESOURCES;
		goto failmemlist;
	}
		
	g_Sma->GlobalGrh->VirtualAddr = MemoryAllocate2AndClear(sizeof(IB_GRH), IBA_MEM_FLAG_PREMPTABLE, SMA_MEM_TAG);
	if ( NULL == g_Sma->GlobalGrh->VirtualAddr )
	{
		status = FINSUFFICIENT_RESOURCES;
		goto failgrhvirt;
	}
	g_Sma->GlobalGrh->AccessControl.AsUINT16 = 0;
	g_Sma->GlobalGrh->AccessControl.s.LocalWrite = 1;
	g_Sma->GlobalGrh->CaMemIndex = 0;

	// Increment index for future allocations
	g_Sma->Bin.CurrentIndex++;

done:
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
    return status;

failgrhvirt:
	MemoryDeallocate( g_Sma->GlobalGrh );
failmemlist:
	IbtDestroyNotifyGroup();
	SpinLockDestroy( &g_Sma->RQ.Lock );
	MutexDestroy( &g_Sma->Bin.Mutex );
	SpinLockDestroy( &g_Sma->Bin.Lock );
	SpinLockDestroy( &g_Sma->CaListLock );
	MemoryDeallocate( g_Sma );
	goto done;
}
コード例 #13
0
ファイル: smamain.c プロジェクト: 01org/opa-ff
FSTATUS
SmaAddDevice(
	IN	EUI64			CaGuid,
	OUT void			**Context
	)
{
	FSTATUS				status = FSUCCESS;
	SMA_CA_OBJ_PRIVATE	*pCaObj=NULL;
	uint32				i;
	
	_DBG_ENTER_LVL(_DBG_LVL_MAIN, SmaAddDevice);

	pCaObj = (SMA_CA_OBJ_PRIVATE*)MemoryAllocateAndClear(sizeof(SMA_CA_OBJ_PRIVATE), FALSE, SMA_MEM_TAG);
	if ( NULL == pCaObj ) 
	{
		_DBG_ERROR(("MemAlloc failed for pCaObj/WorkReq!\n"));
		status = FINSUFFICIENT_MEMORY;
		goto done;
	}

	pCaObj->CaPublic.CaGuid = CaGuid;
	pCaObj->CaPublic.SmaCaContext = pCaObj;

	EventThreadInitState(&pCaObj->SmaEventThread);
	if (! EventThreadCreate(&pCaObj->SmaEventThread, "Smi",
		THREAD_PRI_VERY_HIGH, SmaCompletionCallback, pCaObj))
	{
		_DBG_ERROR(("Sma Event Thread Create FAILED\n"));
		goto failsmathread;
	}
		
	EventThreadInitState(&pCaObj->GsaEventThread);
	if (! EventThreadCreate(&pCaObj->GsaEventThread, "Gsi",
		THREAD_PRI_VERY_HIGH, GsaCompletionThreadCallback, pCaObj))
	{
		_DBG_ERROR(("Gsa Event Thread Create FAILED\n"));
		goto failgsathread;
	}

	status = iba_open_ca( CaGuid, SmaGsaCompletionCallback,
				SmaAsyncEventCallback, pCaObj/*Context*/, &pCaObj->CaHandle);
	if ( FSUCCESS != status )
	{
		_DBG_ERROR(("OpenCA() failed!\n"));
		goto failopen;
	}
	status = SetCAInternal(pCaObj->CaHandle);
	if ( FSUCCESS != status )
	{
		_DBG_ERROR(("SetCAInternal() failed!\n"));
		goto failinternal;
	}

	// Reserve CQ/QP/PD...
	status = SmaDeviceReserve( pCaObj );
	if ( FSUCCESS != status )
	{
		goto failreserve;
	}
	// we hold the Mutex across Bind and addition to Ca list
	// so that CreateDgrmPool cannot race and cause double
	// registration of memory in new DgrmPool
	AcquireMemListMutex();
	status = SmaBindGlobalMem( pCaObj );
	if (status != FSUCCESS)
	{
		ReleaseMemListMutex();
		// TBD need to undo SmaDeviceReserve
		goto failreserve;
	}

	// lock

	// update global info
	SpinLockAcquire(&g_Sma->CaListLock);
	g_Sma->NumCa++;
	pCaObj->Next = g_Sma->CaObj;
	pCaObj->Prev = NULL;
	if ( NULL != g_Sma->CaObj )
		g_Sma->CaObj->Prev = pCaObj;
	g_Sma->CaObj = pCaObj;
	pCaObj->UseCount++;	// hold reference so we can use object below
	SpinLockRelease(&g_Sma->CaListLock);

	ReleaseMemListMutex();

	// QPConfig 
	status = SmaDeviceConfig( pCaObj, QPTypeSMI );
	status = SmaDeviceConfig( pCaObj, QPTypeGSI );

	// Create GSA data structures
	GsaUpdateCaList();

	// Preallocate Buffers based on per device.
	// If we know the amount of buffers we need per device and go ahead
	// and allocate them in advance, subnet sweeps will not allocate
	// any buffers in the speed path
	//
	// NOTE: This call can fail if there are no system resources
	SmaAllocToBin( g_Settings.PreAllocSMPsPerDevice, FALSE );
	
	// post some descriptors on recv side if port is up or something...
	for (i=0; i<pCaObj->CaPublic.Ports; i++)
	{
		status = iba_smi_post_recv( NULL, pCaObj, (uint8)(i+1), 
							g_Settings.MinSMPsToPostPerPort );	
	}

	// Set Port capabilities across all CA's
	SetPortCapabilities();

	// Rearm CQ to receive event notifications.
	// The next Work Completion written to the CQ 
	// will generate an event
	status = iba_rearm_cq( pCaObj->CqHandle, CQEventSelNextWC);						
	SpinLockAcquire(&g_Sma->CaListLock);
	pCaObj->UseCount--;
	SpinLockRelease(&g_Sma->CaListLock);

	// Bind 
		
	// unlock

	// notify users through callbacks!
	IbtNotifyGroup( CaGuid, IB_NOTIFY_CA_ADD );
	// TBD - failure above causes bad status return here, can confuse caller
	// also does not cleanup QPs, CQ, PD, MRs, buffers
	// SmaRemoveCaObj might solve, but not clear if safe to call it
	// need some peers to the SmaDeviceReserve and SmaDeviceConfig routines
	// to undo their effects

done:
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
      
    return status;

failreserve:
failinternal:
	iba_close_ca( pCaObj->CaHandle );
failopen:
	EventThreadDestroy(&pCaObj->GsaEventThread);
failgsathread:
	EventThreadDestroy(&pCaObj->SmaEventThread);
failsmathread:
	MemoryDeallocate( pCaObj );
	goto done;
}
コード例 #14
0
ファイル: multicast.c プロジェクト: 01org/opa-ff
FSTATUS
MulticastTerminate(void)
{
	FSTATUS       Status;
	CLIENT_HANDLE McSdHandleTemp;
	LIST_ITEM     *pListItem;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, MulticastTerminate);
	
	/* Just in case maintenance routine is running */
	SpinLockAcquire(&MulticastLock);
	McSdHandleTemp = McSdHandle;
	McSdHandle = NULL;
	SpinLockRelease(&MulticastLock);
		
	if (McSdHandleTemp == NULL)
	{
		_DBG_ERROR(("Multicast Module Not A Registered Subnet Driver "
		            "Client Process.\n"));
		Status = FINVALID_STATE;
		goto exit;
	}

	if (MaintenanceTimerActivated == TRUE)
	{
		TimerStop(&MaintenanceTimer);
		MaintenanceTimerActivated = FALSE;
	}
	
	Status = iba_sd_deregister(McSdHandleTemp);
	if (Status != FSUCCESS) {
		_DBG_ERROR(("Cannot Deregister With "
		            "Subnet Data Interface.\n"));
	}

	for (pListItem = QListRemoveHead(&MasterMcGroupList);
	     pListItem != NULL;
	     pListItem = QListRemoveHead(&MasterMcGroupList))
	{
		MC_GROUP *pMcGroup = (MC_GROUP *)QListObj(pListItem);
		
		ASSERT(pMcGroup != NULL);
		
		TimerStop(&pMcGroup->Timer);
		TimerDestroy(&pMcGroup->Timer);
		QListDestroy(&pMcGroup->McClientList);
		MemoryDeallocate(pMcGroup);
	}
	
	for (pListItem = QListRemoveHead(&MasterMcClientList);
	     pListItem != NULL;
	     pListItem = QListRemoveHead(&MasterMcClientList))
	{
		MC_CLIENT *pMcClient = (MC_CLIENT *)QListObj(pListItem);
		
		ASSERT(pMcClient != NULL);
		
		MemoryDeallocate(pMcClient);
	}
	
	QListDestroy(&MasterMcGroupList);
	QListDestroy(&MasterMcClientList);
	TimerDestroy(&MaintenanceTimer);
	SpinLockDestroy(&MulticastLock);

exit:
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
	
	return Status;
}
コード例 #15
0
ファイル: subscribe.c プロジェクト: 01org/opa-ff
FSTATUS
iba_sd_trap_notice_subscribe(CLIENT_HANDLE ClientHandle,
                    uint16 TrapNumber,
                    EUI64 PortGuid,
                    void *pContext,
                    SD_REPORT_NOTICE_CALLBACK *pReportNoticeCallback)
{
	FSTATUS                   Status;
	CLIENT_CONTROL_PARAMETERS ClientParams;
	ClientListEntry           *pClientEntry = (ClientListEntry *)ClientHandle;
	CLIENT_TRAP_INFO          *pClientTrapInfo;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, iba_sd_trap_notice_subscribe);

	Status = ValidateClientHandle(ClientHandle, &ClientParams);
	if (Status != FSUCCESS)
	{
		_DBG_ERROR(("Invalid Client Handle Specified\n"));
		goto exit;
	}

	SpinLockAcquire(pClientListLock);

	pClientTrapInfo = FindClientTrapInfo(&pClientEntry->ClientTraps, TrapNumber, PortGuid);
	if (pClientTrapInfo != NULL)
	{
		// Already Subscribed
		Status = FDUPLICATE;
		SpinLockRelease(pClientListLock);
		goto exit;
	}

	SpinLockRelease(pClientListLock);

	pClientTrapInfo = (CLIENT_TRAP_INFO*)MemoryAllocate2AndClear(sizeof(CLIENT_TRAP_INFO), IBA_MEM_FLAG_NONE, SUBNET_DRIVER_TAG);
	if (pClientTrapInfo == NULL)
	{
		Status = FINSUFFICIENT_MEMORY;
		goto exit;
	}

	pClientTrapInfo->TrapNumber = TrapNumber;
	pClientTrapInfo->PortGuid = PortGuid;
	pClientTrapInfo->pContext = pContext;
	pClientTrapInfo->pReportNoticeCallback = pReportNoticeCallback;

	QListSetObj(&pClientTrapInfo->ListItem, pClientTrapInfo);

	SpinLockAcquire(pClientListLock);
	QListInsertTail(&pClientEntry->ClientTraps, &pClientTrapInfo->ListItem);
	SpinLockRelease(pClientListLock);

	Status = IncrementTrapUsageCount(TrapNumber, PortGuid);
	if (Status != FSUCCESS)
	{
		SpinLockAcquire(pClientListLock);
		QListRemoveItem(&pClientEntry->ClientTraps, &pClientTrapInfo->ListItem);
		SpinLockRelease(pClientListLock);
		MemoryDeallocate(pClientTrapInfo);
	}

exit:
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
	return Status;
}
コード例 #16
0
ファイル: multicast.c プロジェクト: 01org/opa-ff
static
FSTATUS
IncrementMcGroupUsageCount(CLIENT_HANDLE       SdClientHandle,
                           void                *pContext,
                           SD_MULTICAST_CALLBACK *pMulticastCallback,
                           uint16              McFlags,
                           uint64              ComponentMask,
                           IB_MCMEMBER_RECORD  *pMcMemberRecord,
                           MC_GROUP_ID         *pMcGroupId)
{
	MC_CLIENT *pMcClientTemp;
	MC_CLIENT *pMcClient = NULL;
	MC_GROUP  *pMcGroupTemp;
	MC_GROUP  *pMcGroup = NULL;
	boolean   StartTrapNotification;

	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, IncrementMcGroupUsageCount);
	
	/* Allocate Everything up front to avoid locking issues */
	pMcClientTemp = (MC_CLIENT *)MemoryAllocate2AndClear(sizeof(MC_CLIENT), IBA_MEM_FLAG_NONE, SUBNET_DRIVER_TAG);
	if (pMcClientTemp == NULL)
	{
		_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
		return FINSUFFICIENT_MEMORY;
	}
	
	pMcClientTemp->SdClientHandle = SdClientHandle;
	pMcClientTemp->pContext = pContext;
	pMcClientTemp->McFlags = McFlags;
	pMcClientTemp->pMulticastCallback = pMulticastCallback;

	pMcGroupTemp = (MC_GROUP*)MemoryAllocate2AndClear(sizeof(MC_GROUP), IBA_MEM_FLAG_SHORT_DURATION, SUBNET_DRIVER_TAG);
	if (pMcGroupTemp == NULL)
	{
		_DBG_ERROR(("IncrementMcGroupUsageCount MemoryAllocateError\n"));
		MemoryDeallocate(pMcClientTemp);
		_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
		return FINSUFFICIENT_MEMORY;
	}
	
	SpinLockAcquire(&MulticastLock);

	pMcClient = FindMcClient(SdClientHandle, pMcGroupId);
	if (pMcClient == NULL) 
	{
		pMcClient= pMcClientTemp;
		pMcClientTemp = NULL;
	}
	else 
	{
		_DBG_ERROR(("IncrementMcGroupUsageCount Client already exists.\n"));
		/*SpinLockRelease(&MulticastLock);
		MemoryDeallocate(pMcGroupTemp);
		MemoryDeallocate(pMcClient);
		_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
		return FDUPLICATE;*/
		// continue anyway
	}
	
	StartTrapNotification = QListIsEmpty(&MasterMcGroupList);
	
	pMcGroup = FindMcGroup(pMcGroupId);
	if (pMcGroup == NULL)
	{
		// didn't find Mcgroup in list, let us add one
		pMcGroupTemp->McGroupState = MC_GROUP_STATE_REQUEST_JOIN;
		pMcGroupTemp->ComponentMask = ComponentMask;
		pMcGroupTemp->McMemberRecord = *pMcMemberRecord;
		pMcGroupTemp->McGroupId = *pMcGroupId;
		QListInit(&pMcGroupTemp->McClientList);
		QListSetObj(&pMcGroupTemp->ListItem, pMcGroupTemp);

		pMcGroup = pMcGroupTemp;
		pMcGroupTemp = NULL;

		QListInsertTail(&MasterMcGroupList, &pMcGroup->ListItem);

		TimerInitState(&pMcGroup->Timer);
		TimerInit(&pMcGroup->Timer, IssueSubnetDriverCall, pMcGroup );
	}
	else
	{
		// group already exists - check state
		if ( (pMcGroup->McGroupState != MC_GROUP_STATE_REQUEST_JOIN) &&
		     (pMcGroup->McGroupState != MC_GROUP_STATE_AVAILABLE) )
		{
			if (pMcGroup->McGroupState == MC_GROUP_STATE_JOIN_FAILED)
			{
				_DBG_ERROR(("Prior attempt to join Multicast Group failed\n"));
			}
			else
			{
				_DBG_ERROR(("IncrementMcGroupUsageCount McGroup invalid state:%d.\n",
				pMcGroup->McGroupState));
			}
			SpinLockRelease(&MulticastLock);
			MemoryDeallocate(pMcGroupTemp);
			if(pMcClientTemp)
				MemoryDeallocate(pMcClientTemp);
			_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
			return FDUPLICATE;
		}
	}

	pMcClient->pMcGroup = pMcGroup;
	
	QListSetObj(&pMcClient->ListItem, pMcClient);
	QListInsertTail(&MasterMcClientList, &pMcClient->ListItem);
	
	QListSetObj(&pMcClient->McGroupListItem, pMcClient);
	QListInsertTail(&pMcGroup->McClientList, &pMcClient->McGroupListItem);
	
	if (pMcGroupTemp == NULL)
	{
		/* First client joining the group - Get The Process Started */
		_DBG_INFO(("new mcgroup - queuing join\n"));
		QueueSubnetDriverCall(pMcGroup, MC_GROUP_STATE_REQUEST_JOIN);
	}
	else
	{
		_DBG_INFO(("existing mcgroup - checking flags %d\n",
			pMcGroup->McGroupState));
		if ((McJoinFlagsAdjusted(pMcGroup, pMcMemberRecord) == TRUE) && 
		    (pMcGroup->McGroupState == MC_GROUP_STATE_AVAILABLE)) // TODO: Check Concurrency Here
			/* we had already joined and the flags changes - so rejoin */
		{
			_DBG_INFO(("flags changed after we joined - rejoining \n"));
			QueueSubnetDriverCall(pMcGroup, MC_GROUP_STATE_REQUEST_JOIN);
		}
		else if (pMcGroup->McGroupState == MC_GROUP_STATE_AVAILABLE) 
		{
			// we already had joined but we got a new client - issue callbacks
			_DBG_INFO(("someone joined when state is available - issuing callbacks \n"));
			CallMcClients(pMcGroup, FSUCCESS, MC_GROUP_STATE_AVAILABLE);
		}
		// NOTE if state is JOIN, then when that completes all clients
		// including new one will be notified via callback
	}

	if (MaintenanceTimerActivated == FALSE)
	{
		MaintenanceTimerActivated = TRUE;
		TimerStart(&MaintenanceTimer, 5000);
	}
	
	SpinLockRelease(&MulticastLock);
	
	if (StartTrapNotification)
	{
		McSubscribeForTraps();
	}

	if (pMcGroupTemp)
	{
		TimerDestroy(&pMcGroupTemp->Timer);
		QListDestroy(&pMcGroupTemp->McClientList);
		MemoryDeallocate(pMcGroupTemp);
	}

	if (pMcClientTemp)
	{
		MemoryDeallocate(pMcClientTemp);
	}

	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );

	return FSUCCESS;
}
コード例 #17
0
ファイル: bmamain.c プロジェクト: 01org/opa-ff
//////////////////////////////////////////////////////////////////////////
// BmaAddDevice()
//
// This routine is called once for every new device added.
//
// INPUTS:
//		CaGuid - the channel adapters GUID
//
// OUTPUTS:
//
//	None.  Although function is defined to return context value, this
//	value is not set since their is nothing specifically allocated for
//	each new channel adapter, so nothing is done in the BmaRemoveDevice
//	function that needs the context.
//
// RETURNS:
//
//	FSUCCESS - Indicates a successful initialization.
//
//
FSTATUS
BmaAddDevice(
	IN	EUI64			CaGuid,
	OUT void			**Context
	)
{
	FSTATUS			status = FSUCCESS;
	uint32			BufferSize;
	BMA_DEV_INFO	*pDevInfo=NULL;

	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BmaAddDevice);

	ASSERT(g_BmaGlobalInfo);

	if (!g_BmaGlobalInfo->binitsuccess)
	{
		// Create the datagram pool
		BufferSize = sizeof(PERF_MAD);
		status = iba_gsi_create_dgrm_pool(g_BmaGlobalInfo->GsaHandle,
								g_BmaSettings.MaxNDgrm,
								1,
								&BufferSize,
								0, //1,
								&g_BmaGlobalInfo->DgrmPoolHandle
								);
		if (status != FSUCCESS)
		{
			// Cleanup
			iba_gsi_deregister_class(g_BmaGlobalInfo->GsaHandle);

			MemoryDeallocate(g_BmaGlobalInfo);

			g_BmaGlobalInfo = NULL;

			_DBG_ERROR(("Unable to create BMA datagram pool!!! <status %d>\n", status));
		}
		else
		{
			g_BmaGlobalInfo->binitsuccess = TRUE;
		}

	}

	if (g_BmaGlobalInfo->binitsuccess)
	{
		pDevInfo = (BMA_DEV_INFO*)MemoryAllocateAndClear(sizeof(BMA_DEV_INFO), FALSE, BMA_TAG );

		if (pDevInfo)
		{
			IB_CA_ATTRIBUTES CaAttributes;

			pDevInfo->CaGuid = CaGuid;
			status = iba_query_ca_by_guid_alloc(CaGuid, &CaAttributes);
			if ( status == FSUCCESS )
			{
				pDevInfo->NumPorts = CaAttributes.Ports;
				pDevInfo->Port = (BMA_PORT_INFO*)
					MemoryAllocateAndClear(sizeof(BMA_PORT_INFO)*pDevInfo->NumPorts, FALSE, BMA_TAG);
				if (pDevInfo->Port)
				{
					IB_PORT_ATTRIBUTES *pPortAttr;
					unsigned i;

					for ( i = 0, pPortAttr = CaAttributes.PortAttributesList;
						  i < pDevInfo->NumPorts;
						  i++, pPortAttr = pPortAttr->Next )
					{
						// Traps disabled by default, Trap settings are all zero
						// BKey, BKeyProtect, BKeyViolations, and BKeyLease all init to zero
						pDevInfo->Port[i].Guid = pPortAttr->GUID;
					}

					MemoryDeallocate(CaAttributes.PortAttributesList);

					// Success, add this CA to the list
					SpinLockAcquire( &g_BmaGlobalInfo->DevListLock );
					pDevInfo->Next = g_BmaGlobalInfo->DevList;
					g_BmaGlobalInfo->DevList = pDevInfo;
					SpinLockRelease( &g_BmaGlobalInfo->DevListLock );
				}
				else
				{
					_DBG_ERROR(("MemAlloc failed for Port List!\n"));
					status = FINSUFFICIENT_MEMORY;
				}
			}
			else
			{
				_DBG_ERROR(("CA Query Failed!\n"));
				MemoryDeallocate(pDevInfo);
			}
		}
		else
		{
			_DBG_ERROR(("MemAlloc failed for pDevInfo!\n"));
			status = FINSUFFICIENT_MEMORY;
		}
	}

	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);

	return status;

} // BmaAddDevice()
コード例 #18
0
ファイル: gsadgrm.c プロジェクト: 01org/opa-ff
uint32									
iba_gsi_coalesce_dgrm2(
	IN IBT_DGRM_ELEMENT			*DgrmElement,
	IN uint8					**ppBuffer,
	IN uint32					ClassHeaderSize,
	IN uint32					MemAllocFlags
	)
{
	uint32						messageSize = 0;
	uint32						byteCount, totalBytesToCopy;
	IBT_ELEMENT					*pElement;
	IBT_BUFFER					*pBufferHdr;
	uint8						*pBuffer;
	MAD_RMPP					*pMadRmpp;
#ifdef TEST_DUMP
	static int counter;
#endif

	_DBG_ENTER_LVL(_DBG_LVL_POOL, iba_gsi_coalesce_dgrm);

	pElement	= &DgrmElement->Element;
	pBufferHdr	= pElement->pBufferList;
	pMadRmpp	= (MAD_RMPP*)pBufferHdr->pNextBuffer->pData;// 2nd buffer is MAD
	
	// Calculate total bytes to copy. 
	// Each buffer has a GRH+Mad Common Header+RMPP Header+ClassHeader+RMPP Data
	//
	// We copy only one copy of the headers and coalesce the data
	messageSize = totalBytesToCopy = iba_gsi_dgrm_len(DgrmElement, ClassHeaderSize);
	if (! messageSize)
		goto fail;
	_DBG_PRINT(_DBG_LVL_POOL,("Total bytes to copy: %d\n", totalBytesToCopy));

	if (*ppBuffer == NULL)
	{
		*ppBuffer = (uint8*)MemoryAllocate2(totalBytesToCopy, MemAllocFlags, GSA_MEM_TAG);
		if (*ppBuffer == NULL)
			goto fail;
	}
	pBuffer		= *ppBuffer;

	// Copy GRH
	if (pBufferHdr->ByteCount != sizeof(IB_GRH)) {
		_DBG_ERROR(("Bad buffer header size: %u expected %u\n", pBufferHdr->ByteCount, (unsigned)sizeof(IB_GRH)));
		messageSize = 0;	// indicate invalid packets
		goto fail;
	}
	byteCount = pBufferHdr->ByteCount;
	MemoryCopy( pBuffer, pBufferHdr->pData, byteCount ); 
	pBuffer += byteCount;
	totalBytesToCopy -= byteCount; // keep count
	pBufferHdr = pBufferHdr->pNextBuffer;
	
	// Copy Mad Common + RMPP Header + class header + first data area
	byteCount = (totalBytesToCopy > pBufferHdr->ByteCount) ? \
					pBufferHdr->ByteCount:totalBytesToCopy;
	MemoryCopy( pBuffer, pBufferHdr->pData, byteCount );
	pBuffer += byteCount;
	totalBytesToCopy -= byteCount; // keep count
	
	// Walk all elements of RMPP list
	while ( totalBytesToCopy )
	{
		pElement = pElement->pNextElement;

		if ( NULL == pElement )
		{
			_DBG_ERROR(("LIST ERROR DgrmElement %p ClassHeaderSize %d messageSize %d BytesLeft %d\n", 
					_DBG_PTR(DgrmElement), ClassHeaderSize, messageSize, totalBytesToCopy));
			DumpDgrmElement(DgrmElement);
			messageSize = 0;	// indicate invalid packets/buffers
			goto fail;
		}
		else
		{
#ifdef TEST_DUMP
			if ((++counter%50) == 0)
			{
				_DBG_ERROR(("LIST ERROR DgrmElement %p ClassHeaderSize %d messageSize %d BytesLeft %d\n", 
					_DBG_PTR(DgrmElement), ClassHeaderSize, messageSize, totalBytesToCopy));
				DumpDgrmElement(DgrmElement);
				messageSize = 0;	// indicate invalid packets/buffers
				goto fail;
			}
#endif
		}

		// skip GRH
		pBufferHdr = pElement->pBufferList->pNextBuffer;
		
		pMadRmpp = (MAD_RMPP *)pBufferHdr->pData;

		// copy as much class data as is left in packet
		// subtract common headers, if packet too small, don't copy anything
		byteCount = (sizeof(MAD_COMMON) + sizeof(RMPP_HEADER) + ClassHeaderSize);
		byteCount = (byteCount > pBufferHdr->ByteCount)? \
								0:(pBufferHdr->ByteCount - byteCount);

		byteCount = (totalBytesToCopy > byteCount)?byteCount:totalBytesToCopy;
		if (byteCount)
		{
			MemoryCopy( pBuffer, &pMadRmpp->Data[ClassHeaderSize], byteCount); 
			pBuffer += byteCount;
			totalBytesToCopy -= byteCount; // keep count
		}
	}
	_DBG_LEAVE_LVL(_DBG_LVL_POOL);
	return messageSize;

fail:
	if (*ppBuffer)
	{
		MemoryDeallocate(*ppBuffer);
		*ppBuffer = NULL;
	}
	_DBG_LEAVE_LVL(_DBG_LVL_POOL);
	return messageSize;
}
コード例 #19
0
ファイル: bmamain.c プロジェクト: 01org/opa-ff
FSTATUS
BmaLoad(
	IN IBT_COMPONENT_INFO		*ComponentInfo
	)
{
	FSTATUS						status = FSUCCESS;
	extern uint32 BmaDbg;
#ifdef IB_TRACE
	extern uint32 BmaTrace;
#endif


	_DBG_ENTER_LVL(_DBG_LVL_MAIN, BMALoad);
	_DBG_INIT;

	__DBG_LEVEL__ = BmaDbg;
#ifdef IB_TRACE
	__DBG_TRACE_LEVEL__ = BmaTrace;
#endif
#if defined(IB_DEBUG) || defined(DBG)
	MsgOut ("Bma:DebugFlags = 0x%8x\n", __DBG_LEVEL__);
#endif

#if defined(VXWORKS)
	_DBG_PRINT(_DBG_LVL_MAIN,  
	(" InfiniBand Baseboard Management Class agent. Built %s %s\n",\
	__DATE__, __TIME__ ));
#else
	_DBG_PRINT(_DBG_LVL_MAIN,  
	(" InfiniBand Baseboard Management Class agent. Built %s %s\n",\
	_DBG_PTR(__DATE__), _DBG_PTR(__TIME__) ));
#endif

	_TRC_REGISTER();

	//
    // Establish dispatch entry points for the functions supported.
	//

	MemoryClear( ComponentInfo, sizeof(IBT_COMPONENT_INFO) );

	ComponentInfo->AddDevice = BmaAddDevice;
	ComponentInfo->RemoveDevice = BmaRemoveDevice;
	ComponentInfo->Unload = BmaUnload;

	
	//
    // Read any registry parameters for the driver which may be present.
	//
	//BmaReadRegistryParameters();

	//
    // This function is called to initialize the GSA subsystem. This must be 
	// called only once and if the function does not return success, the 
	// caller must unload the component containing GSA or else not use the 
	// GSA functionality since GSA will not be available.
	//
	// We are being asked to do a one-time initialization. Here we initialize 
	// the list of channel adapters as well as initialize the list of service 
	// classes as well as initialize the spin locks guarding these lists.
	//


	//
	// Allocate space for Global data
	//

	g_BmaGlobalInfo = (BMA_GLOBAL_INFO*)MemoryAllocateAndClear(
									 sizeof(BMA_GLOBAL_INFO), FALSE, BMA_TAG );
	if ( NULL != g_BmaGlobalInfo )
	{
	
		//
		// initialize global data
		//

		g_BmaGlobalInfo->binitsuccess = FALSE; 

		SpinLockInitState( &g_BmaGlobalInfo->DevListLock );
		if( !SpinLockInit( &g_BmaGlobalInfo->DevListLock ) )
		{
			_DBG_ERROR(( "Unable to initialize spin locks!\n" ));
			status = FINSUFFICIENT_RESOURCES;
			goto fail_lock;
		}

		//
		// Recv Queue and Thread
		//
		CmdThreadInitState(&g_BmaGlobalInfo->RecvThread);
		if ( ! CmdThreadCreate(&g_BmaGlobalInfo->RecvThread,
				THREAD_PRI_HIGH, "Bma", (CMD_THREAD_CALLBACK)BmaThreadCallback,
				(CMD_THREAD_CALLBACK)BmaFreeCallback, (void*)g_BmaGlobalInfo))
		{
			_DBG_ERROR(("BmaMain: Unable to Create RecvThread\n"));
			status = FINSUFFICIENT_RESOURCES;
			goto fail_thread;
		}
		

		// initialize this general service class manager with GSI
		status = iba_gsi_register_class(MCLASS_BM, 
									IB_BM_CLASS_VERSION,
									GSI_REGISTER_RESPONDER,	// Register as a Responder
									FALSE,					// No SAR cap needed
									g_BmaGlobalInfo,		// Context
									BmaSendCallback,
									BmaRecvCallback,
									&g_BmaGlobalInfo->GsaHandle);
							
		if (status != FSUCCESS)
		{
			CmdThreadDestroy(&g_BmaGlobalInfo->RecvThread);
fail_thread:
			SpinLockDestroy( &g_BmaGlobalInfo->DevListLock );
fail_lock:
			MemoryDeallocate(g_BmaGlobalInfo);
			g_BmaGlobalInfo = NULL;

			_DBG_ERROR(("BmaMain: Unable to register with GSA!!! <status %d>\n", status));

			_DBG_LEAVE_EXT(_DBG_LVL_FUNC_TRACE);

			return status;
		}
 
	}
	else
	{
		status = FINSUFFICIENT_RESOURCES;
		_DBG_PRINT(_DBG_LVL_MAIN,("Not enough memory!\n"));
	}

    
	_DBG_LEAVE_LVL(_DBG_LVL_MAIN);
    
    return status;
}
コード例 #20
0
ファイル: multicast.c プロジェクト: 01org/opa-ff
static
void
McMaintenance(void *pContext)
{
	LIST_ITEM *pListItem;
	
	_DBG_ENTER_LVL(_DBG_LVL_FUNC_TRACE, McMaintenance);
	
	if (McSdHandle != NULL)
	{
		SpinLockAcquire(&MulticastLock);

		if (TimerCallbackStopped(&MaintenanceTimer))
		{
			// stale timer callback
			SpinLockRelease(&MulticastLock);
			goto done;
		}

		// Loop Through MasterMcClientList

		pListItem = QListHead(&MasterMcClientList);

		while(pListItem != NULL)
		{
			MC_CLIENT *pMcClient = (MC_CLIENT *)QListObj(pListItem);

			ASSERT(pMcClient != NULL);

			pListItem = QListNext(&MasterMcClientList, pListItem);

			if ((pMcClient->McClientDelete == TRUE) && 
				(pMcClient->McClientInUse == 0))
			{
				QListRemoveItem(&MasterMcClientList, &pMcClient->ListItem);
				SpinLockRelease(&MulticastLock);
				MemoryDeallocate(pMcClient);
				if (McSdHandle == NULL)
				{
					break;
				}
				SpinLockAcquire(&MulticastLock);
			}
		}
	}

	if (McSdHandle != NULL)
	{
		// Loop Through MasterMcGroupList

		pListItem = QListHead(&MasterMcGroupList);

		while(pListItem != NULL)
		{
			MC_GROUP *pMcGroup = (MC_GROUP *)QListObj(pListItem);

			ASSERT(pMcGroup != NULL);

			pListItem = QListNext(&MasterMcGroupList, pListItem);

			if ((pMcGroup->McGroupDelete == TRUE) && 
				(pMcGroup->McGroupInUse == 0))
			{
				TimerDestroy(&pMcGroup->Timer);
				QListDestroy(&pMcGroup->McClientList);
				QListRemoveItem(&MasterMcGroupList, &pMcGroup->ListItem);
				SpinLockRelease(&MulticastLock);
				MemoryDeallocate(pMcGroup);
				if (McSdHandle == NULL)
				{
					break;
				}
				SpinLockAcquire(&MulticastLock);
			}
		}
	}

	if (McSdHandle != NULL)
	{
		if (!QListIsEmpty(&MasterMcGroupList) ||
			!QListIsEmpty(&MasterMcClientList))
		{
			/* Only Start It If There Is A Possibility Of Something To Do */
			TimerStart(&MaintenanceTimer, 5000);
			SpinLockRelease(&MulticastLock);
		}
		else
		{
			McUnsubscribeForTraps();
			MaintenanceTimerActivated = FALSE;
			SpinLockRelease(&MulticastLock);
		}
	}
	
done:
	_DBG_LEAVE_LVL( _DBG_LVL_FUNC_TRACE );
}