|
Packit Service |
3470d1 |
/* BEGIN_ICS_COPYRIGHT4 ****************************************
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
Copyright (c) 2015, Intel Corporation
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
3470d1 |
modification, are permitted provided that the following conditions are met:
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
* Redistributions of source code must retain the above copyright notice,
|
|
Packit Service |
3470d1 |
this list of conditions and the following disclaimer.
|
|
Packit Service |
3470d1 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit Service |
3470d1 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit Service |
3470d1 |
documentation and/or other materials provided with the distribution.
|
|
Packit Service |
3470d1 |
* Neither the name of Intel Corporation nor the names of its contributors
|
|
Packit Service |
3470d1 |
may be used to endorse or promote products derived from this software
|
|
Packit Service |
3470d1 |
without specific prior written permission.
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
Packit Service |
3470d1 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit Service |
3470d1 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit Service |
3470d1 |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
|
Packit Service |
3470d1 |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit Service |
3470d1 |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
Packit Service |
3470d1 |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
Packit Service |
3470d1 |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
Packit Service |
3470d1 |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit Service |
3470d1 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
** END_ICS_COPYRIGHT4 ****************************************/
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
#include "ibnotify.h"
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Globals
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_GROUP NotifyGroup;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Initialize the Notify Group
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//INPUT:
|
|
Packit Service |
3470d1 |
// Callback - when a new User is added to the Notify group, this routine
|
|
Packit Service |
3470d1 |
// is called to distribute initial events to User
|
|
Packit Service |
3470d1 |
void
|
|
Packit Service |
3470d1 |
IbtInitNotifyGroup (
|
|
Packit Service |
3470d1 |
IN IB_ROOT_CALLBACK Callback
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, IbtInitNotifyGroup );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
ASSERT(! NotifyGroup.Initialized);
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
MapInitState( &NotifyGroup.Lists );
|
|
Packit Service |
3470d1 |
SpinLockInitState( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (MapInit( &NotifyGroup.Lists ) != FSUCCESS)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
_DBG_ERROR (("Failed to Initialize Notification Map\n"));
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (SpinLockInit( &NotifyGroup.Lock ) == FALSE)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
_DBG_ERROR (("Failed to Initialize Notification lock\n"));
|
|
Packit Service |
3470d1 |
goto faillock;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Add root callback for new users
|
|
Packit Service |
3470d1 |
ASSERT ( Callback );
|
|
Packit Service |
3470d1 |
NotifyGroup.RootCallback = Callback;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
NotifyGroup.Initialized = TRUE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
return;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
faillock:
|
|
Packit Service |
3470d1 |
MapDestroy ( &NotifyGroup.Lists );
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Cleanup for shutdown
|
|
Packit Service |
3470d1 |
void
|
|
Packit Service |
3470d1 |
IbtDestroyNotifyGroup ( void )
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
QUICK_LIST *pList;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, IbtDestroyNotifyGroup );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! NotifyGroup.Initialized)
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Empty list contents
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
while (NULL != (pList = (QUICK_LIST*)MapRemoveHead(&NotifyGroup.Lists)))
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LIST_ITEM *pListItem;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
while (NULL != (pListItem = QListRemoveHead(pList)))
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_USER_BLOCK *pUser = (IBT_NOTIFY_USER_BLOCK *)pListItem;
|
|
Packit Service |
3470d1 |
MemoryDeallocate( pUser );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
QListDestroy(pList);
|
|
Packit Service |
3470d1 |
MemoryDeallocate(pList);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
NotifyGroup.Initialized = FALSE;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
MapDestroy( &NotifyGroup.Lists );
|
|
Packit Service |
3470d1 |
SpinLockDestroy( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Notify all users in pList of pRec event
|
|
Packit Service |
3470d1 |
void
|
|
Packit Service |
3470d1 |
IbtNotifyList(
|
|
Packit Service |
3470d1 |
QUICK_LIST *pList,
|
|
Packit Service |
3470d1 |
IB_NOTIFY_RECORD *pRec
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
LIST_ITEM *pListFirst;
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_USER_BLOCK *pUser;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
pListFirst = QListHead( pList );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
while (pListFirst)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
// If event has been subscribed by user, notify
|
|
Packit Service |
3470d1 |
if ( pRec->EventType & ((IBT_NOTIFY_USER_BLOCK *)pListFirst)->EventMask)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
pUser = (IBT_NOTIFY_USER_BLOCK *)pListFirst;
|
|
Packit Service |
3470d1 |
pRec->Context = pUser->Context;
|
|
Packit Service |
3470d1 |
if (pUser->Locking == IB_NOTIFY_ASYNC)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
pUser->RefCount++;
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
( pUser->Callback )( *pRec );
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
pListFirst = QListNext( pList, pListFirst );
|
|
Packit Service |
3470d1 |
if (--(pUser->RefCount) == 0)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
QListRemoveItem ( pList, &pUser->ListItem );
|
|
Packit Service |
3470d1 |
MemoryDeallocate( pUser );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
continue;
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ASSERT(pUser->RefCount);
|
|
Packit Service |
3470d1 |
( pUser->Callback )( *pRec );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
pListFirst = QListNext( pList, pListFirst );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Notify all registered clients of an event against the given Guid
|
|
Packit Service |
3470d1 |
void
|
|
Packit Service |
3470d1 |
IbtNotifyGroup (
|
|
Packit Service |
3470d1 |
IN EUI64 Guid, // Port/Node GUID
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_TYPE EventType // Type of event being reported
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
IB_NOTIFY_RECORD Rec;
|
|
Packit Service |
3470d1 |
QUICK_LIST* pList;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, IbtNotifyGroup );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_PRINT( _DBG_LVL_IBT_API,(
|
|
Packit Service |
3470d1 |
"NotifyGroup\n"
|
|
Packit Service |
3470d1 |
"\tEventType...:%"PRIxN"\n"
|
|
Packit Service |
3470d1 |
"\tGUID........:x%016"PRIx64"\n",
|
|
Packit Service |
3470d1 |
EventType,
|
|
Packit Service |
3470d1 |
Guid ));
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! NotifyGroup.Initialized)
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Fill in common record info
|
|
Packit Service |
3470d1 |
Rec.Guid = Guid;
|
|
Packit Service |
3470d1 |
Rec.EventType = EventType;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// iterate on List in Map for Guid, then map for Guid==0
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MapGet(&NotifyGroup.Lists, Guid);
|
|
Packit Service |
3470d1 |
if (pList != NULL)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
IbtNotifyList(pList, &Rec;;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MapGet(&NotifyGroup.Lists, 0);
|
|
Packit Service |
3470d1 |
if (pList != NULL)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
IbtNotifyList(pList, &Rec;;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Send a notification to a single registered notify client
|
|
Packit Service |
3470d1 |
// used as part of RootCallback to send initial events to a newly
|
|
Packit Service |
3470d1 |
// registered client
|
|
Packit Service |
3470d1 |
// returns FALSE if client has deregistered itself in callback
|
|
Packit Service |
3470d1 |
boolean
|
|
Packit Service |
3470d1 |
IbtNotifyUserEvent (
|
|
Packit Service |
3470d1 |
IN void *UserContext,
|
|
Packit Service |
3470d1 |
IN EUI64 Guid, // Port/Node GUID
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_TYPE EventType // Type of event being reported
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
IB_NOTIFY_RECORD Rec;
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_USER_BLOCK *pUser = (IBT_NOTIFY_USER_BLOCK*)UserContext;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, IbtNotifyUserEvent );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_PRINT( _DBG_LVL_IBT_API,(
|
|
Packit Service |
3470d1 |
"NotifyGroup\n"
|
|
Packit Service |
3470d1 |
"\tEventType...:%"PRIxN"\n"
|
|
Packit Service |
3470d1 |
"\tGUID........:x%016"PRIx64"\n",
|
|
Packit Service |
3470d1 |
EventType,
|
|
Packit Service |
3470d1 |
Guid ));
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! NotifyGroup.Initialized)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
pUser = NULL; // no more notifications needed
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Fill in common record info
|
|
Packit Service |
3470d1 |
Rec.Guid = Guid;
|
|
Packit Service |
3470d1 |
Rec.EventType = EventType;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// If event has been subscribed by user, notify
|
|
Packit Service |
3470d1 |
if ( ( EventType & pUser->EventMask )
|
|
Packit Service |
3470d1 |
&& (pUser->Guid == 0 || pUser->Guid == Guid))
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
Rec.Context = pUser->Context;
|
|
Packit Service |
3470d1 |
if (pUser->Locking == IB_NOTIFY_ASYNC)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
pUser->RefCount++;
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
( pUser->Callback )( Rec );
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
if (--(pUser->RefCount) == 0)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
QUICK_LIST* pList;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MapGet(&NotifyGroup.Lists, pUser->Guid);
|
|
Packit Service |
3470d1 |
if (pList != NULL)
|
|
Packit Service |
3470d1 |
QListRemoveItem ( pList, &pUser->ListItem );
|
|
Packit Service |
3470d1 |
MemoryDeallocate( pUser );
|
|
Packit Service |
3470d1 |
pUser = NULL;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ASSERT(pUser->RefCount);
|
|
Packit Service |
3470d1 |
( pUser->Callback )( Rec );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
return (pUser != NULL);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// iba_register_notify
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// The caller uses this API to register for notifications of IB type events
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// INPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Callback -Callback routine to be registered for notifications
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Context -User specified context to return in callbacks
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// EventMask -Mask to subscribe to event types
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Locking -locking model for callback
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// OUTPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// NotifyHandle -Notification handle on successful registration
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// RETURNS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// FSUCCESS
|
|
Packit Service |
3470d1 |
// FINSUFFICIENT_MEMORY
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
FSTATUS
|
|
Packit Service |
3470d1 |
iba_register_notify (
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_CALLBACK Callback,
|
|
Packit Service |
3470d1 |
IN void *Context,
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_TYPE EventMask,
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_LOCKING Locking,
|
|
Packit Service |
3470d1 |
OUT IB_HANDLE *NotifyHandle
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
FSTATUS status = FSUCCESS;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, iba_register_notify );
|
|
Packit Service |
3470d1 |
status = iba_register_guid_notify(0, Callback, Context, EventMask, Locking, NotifyHandle);
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
return status;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// iba_register_guid_notify
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// The caller uses this API to register for notifications of IB type events
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// INPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Guid -Guid user is interested in
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Callback -Callback routine to be registered for notifications
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Context -User specified context to return in callbacks
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// EventMask -Mask to subscribe to event types
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// Locking -locking model for callback
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// OUTPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// NotifyHandle -Notification handle on successful registration
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// RETURNS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// FSUCCESS
|
|
Packit Service |
3470d1 |
// FINSUFFICIENT_MEMORY
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
FSTATUS
|
|
Packit Service |
3470d1 |
iba_register_guid_notify (
|
|
Packit Service |
3470d1 |
IN EUI64 Guid,
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_CALLBACK Callback,
|
|
Packit Service |
3470d1 |
IN void *Context,
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_TYPE EventMask,
|
|
Packit Service |
3470d1 |
IN IB_NOTIFY_LOCKING Locking,
|
|
Packit Service |
3470d1 |
OUT IB_HANDLE *NotifyHandle
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
FSTATUS status = FSUCCESS;
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_USER_BLOCK *pUser;
|
|
Packit Service |
3470d1 |
QUICK_LIST *pList;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, iba_register_notify );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! NotifyGroup.Initialized)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
status = FINVALID_STATE;
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Allocate memory to hold user registration
|
|
Packit Service |
3470d1 |
pUser = (IBT_NOTIFY_USER_BLOCK*)MemoryAllocateAndClear(
|
|
Packit Service |
3470d1 |
sizeof(IBT_NOTIFY_USER_BLOCK), FALSE,
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_TAG );
|
|
Packit Service |
3470d1 |
if ( !pUser )
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
status = FINSUFFICIENT_MEMORY;
|
|
Packit Service |
3470d1 |
_DBG_ERROR(("%s\n", _DBG_PTR(FSTATUS_MSG(status))));
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Fill in user details
|
|
Packit Service |
3470d1 |
pUser->Guid = Guid; // all Guids
|
|
Packit Service |
3470d1 |
pUser->Callback = Callback;
|
|
Packit Service |
3470d1 |
pUser->Context = Context;
|
|
Packit Service |
3470d1 |
pUser->RefCount = 1;
|
|
Packit Service |
3470d1 |
pUser->EventMask = EventMask;
|
|
Packit Service |
3470d1 |
pUser->Locking = Locking;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
// Save user list in group
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MapGet(&NotifyGroup.Lists, Guid);
|
|
Packit Service |
3470d1 |
if (pList == NULL)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MemoryAllocateAndClear( sizeof(QUICK_LIST), FALSE,
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_TAG );
|
|
Packit Service |
3470d1 |
QListInitState(pList);
|
|
Packit Service |
3470d1 |
if (! QListInit(pList))
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
status = FINSUFFICIENT_RESOURCES;
|
|
Packit Service |
3470d1 |
goto faillist;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
status = MapInsert(&NotifyGroup.Lists, Guid, pList);
|
|
Packit Service |
3470d1 |
if (status != FSUCCESS)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
goto failmap;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
QListInsertHead( pList, &pUser->ListItem );
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
*NotifyHandle = pUser;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_PRINT(_DBG_LVL_IBT_API,("Created entry x%p\n", _DBG_PTR(pUser)));
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (EventMask & IB_NOTIFY_ON_REGISTER)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
// Notify Root to pass user initial events
|
|
Packit Service |
3470d1 |
ASSERT (( NotifyGroup.RootCallback ));
|
|
Packit Service |
3470d1 |
( NotifyGroup.RootCallback )( pUser );
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
return status;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
failmap:
|
|
Packit Service |
3470d1 |
QListDestroy(pList);
|
|
Packit Service |
3470d1 |
faillist:
|
|
Packit Service |
3470d1 |
MemoryDeallocate(pList);
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// iba_deregister_notify
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// The caller uses this API to Deregister previously registered notifications
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// INPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// NotifyHandle -Handle returned on successful registration
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// OUTPUTS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// RETURNS:
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
// FSUCCESS
|
|
Packit Service |
3470d1 |
// FINVALID_PARAMETER
|
|
Packit Service |
3470d1 |
// FINSUFFICIENT_MEMORY
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
//
|
|
Packit Service |
3470d1 |
FSTATUS
|
|
Packit Service |
3470d1 |
iba_deregister_notify (
|
|
Packit Service |
3470d1 |
IN IB_HANDLE NotifyHandle
|
|
Packit Service |
3470d1 |
)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
FSTATUS status = FSUCCESS;
|
|
Packit Service |
3470d1 |
IBT_NOTIFY_USER_BLOCK *pUser = (IBT_NOTIFY_USER_BLOCK*)NotifyHandle;
|
|
Packit Service |
3470d1 |
QUICK_LIST *pList;
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_ENTER_LVL( _DBG_LVL_IBT_API, iba_deregister_notify );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
if (! NotifyGroup.Initialized)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
// could have never registered if we didn't initialize
|
|
Packit Service |
3470d1 |
status = FINVALID_PARAMETER;
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
SpinLockAcquire( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
pList = (QUICK_LIST*)MapGet(&NotifyGroup.Lists, pUser->Guid);
|
|
Packit Service |
3470d1 |
ASSERT(pList);
|
|
Packit Service |
3470d1 |
if ( !QListIsItemInList( pList, &pUser->ListItem ) )
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
status = FINVALID_PARAMETER;
|
|
Packit Service |
3470d1 |
_DBG_ERROR(("Could not deregister. Notification is not in List!!!\n"));
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
if (pUser->Locking == IB_NOTIFY_ASYNC)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
if (--(pUser->RefCount) != 0)
|
|
Packit Service |
3470d1 |
{
|
|
Packit Service |
3470d1 |
// in use in callback
|
|
Packit Service |
3470d1 |
goto done;
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
} else {
|
|
Packit Service |
3470d1 |
ASSERT(pUser->RefCount == 1);
|
|
Packit Service |
3470d1 |
}
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
QListRemoveItem ( pList, &pUser->ListItem );
|
|
Packit Service |
3470d1 |
MemoryDeallocate( pUser );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
done:
|
|
Packit Service |
3470d1 |
SpinLockRelease( &NotifyGroup.Lock );
|
|
Packit Service |
3470d1 |
|
|
Packit Service |
3470d1 |
_DBG_LEAVE_LVL(_DBG_LVL_IBT_API);
|
|
Packit Service |
3470d1 |
return status;
|
|
Packit Service |
3470d1 |
}
|