📄 bf_util.c
字号:
} /* end of bf_ActivateMapping() */
/*---------------------------------------------------------------------------
** bf_AddMapping()
**---------------------------------------------------------------------------
*/
void bf_AddMapping( BF_AddTrrblType *pTrrbl )
{
UINT16 iMappingEntry;
volatile bf_MappingEntryType *psMappingEntry;
GS_UseCritical();
/*
** If an entry already exists, glom onto it.
*/
iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );
if( iMappingEntry != BF_NO_MAPPING )
{
bf_s.asMappingEntries[ iMappingEntry ].iConfiguredUsers++;
return;
}
/*
** Check to make sure mapping doesn't run off end of data area
*/
if( pTrrbl->iAppDataOffset + pTrrbl->iMaxSize > bf_s.asAppDataAreas[ pTrrbl->eAppDataAreaId ].iSize )
{
/*
** Put an error code in the trrbl, and return.
*/
pTrrbl->eStatus = BF_MAPPING_BOUND_ERROR;
return;
}
/*
** New entry gets created one past the last entry in the list.
*/
psMappingEntry = &bf_s.asMappingEntries[ bf_s.iMappingEntries ];
psMappingEntry->iClass = pTrrbl->iClass;
psMappingEntry->iInstance = pTrrbl->iInstance;
psMappingEntry->fCon = pTrrbl->fCon;
psMappingEntry->eAppDataAreaId = pTrrbl->eAppDataAreaId;
psMappingEntry->iAppDataAreaOffset = pTrrbl->iAppDataOffset;
psMappingEntry->iMaxMappingSize = pTrrbl->iMaxSize;
psMappingEntry->iStatusBit = pTrrbl->iStatusBit;
psMappingEntry->iStatusStyle = pTrrbl->iStatusStyle;
psMappingEntry->iConfiguredUsers = 1;
psMappingEntry->iActiveUsers = 0;
psMappingEntry->iTransportId = 0;
psMappingEntry->iActiveEntry = BF_NO_MAPPING;
psMappingEntry->iActiveSubList = 0;
/*
** Subtract the size of the status data from the size of the
** mapping entry. The status data does not appear in the data area.
*/
switch( psMappingEntry->iStatusStyle )
{
case CD_RI_STYLE_32_BIT:
psMappingEntry->iMaxMappingSize -= 4;
break;
case CD_RI_STYLE_ZERO_LEN:
case CD_RI_STYLE_PURE_DATA:
case CD_RI_STYLE_HEARTBEAT:
default:
/*
** These styles don't have any status size associated with them
*/
break;
}
/*
** Make it official by adding to the size of the list.
*/
GS_EnterCritical();
{
bf_s.iMappingEntries++;
}
GS_ExitCritical();
} /* end of bf_AddMapping() */
/*---------------------------------------------------------------------------
** bf_DeactivateMapping()
**---------------------------------------------------------------------------
*/
void bf_DeactivateMapping( BF_DeTrrblType *pTrrbl )
{
UINT16 iActiveSubList;
UINT16 iAppDataAreaId;
UINT16 iLastEntry;
UINT16 iMappingEntry;
volatile BF_ActiveEntryType *psActiveEntry;
volatile bf_ActiveSubListType *psActiveSubList;
volatile bf_AppDataAreaType *psAppDataArea;
volatile bf_MappingEntryType *psMappingEntry;
CM_AppOpenCloseTrrblType *psAppOpenCloseTrrbl; /* October,28th 2005, H.F. */
UINT16 iTransport; /* October,28th 2005, H.F. */
GS_UseCritical();
/*
** Find the appropriate entry & validate that it exists and is active.
*/
iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );
if( iMappingEntry == BF_NO_MAPPING )
{
return;
}
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
/*
** Only delete the active entry when the last user goes away.
*/
if( psMappingEntry->iActiveUsers > 0 )
{
psMappingEntry->iActiveUsers--;
}
if( psMappingEntry->iActiveUsers > 0 )
{
/*
** start edits: October,28th 2005, H.F.
**
** Problem: iTransportId is NOT unique for a Consumer Assembly.
** If there are 3 class 1 connections to the same Consumer
** Connection Point, there will also be 3 iTransportIds.
** However, it is used for mapping entries. So it can happen
** that the iTransportId, that is currently used for mapping
** a Consumer Assembly is now used in conjunction with another
** Consumer Assembly, as the associated connection to the
** first Consumer Assembly was closed and so the iTransportId
** was released and is now used by another connection to the
** second Consumer Assembly. The mapping of the first Consumer
** Assembly has been overwritten by the mapping of the second
** Consumer Assembly, then. And this can result in an Access
** Violation when closing the connection to the first Consumer
** Assembly.
**
** Workaround: Re-Map the Consumer Connection Point, if the connection
** with the currently actually used iTransportId is closed.
** And delete the mapping for this iTransportId.
*/
/* check, if Consumer */
if( psMappingEntry->fCon )
{
/* get 'iTransportId' of closing transport */
psAppOpenCloseTrrbl = (CM_AppOpenCloseTrrblType *)pTrrbl->xUserHandle;
iTransport = psAppOpenCloseTrrbl->psConnRecord->iConTransportId;
/* delete mapping */
bf_s.aiMappingByTransport[ iTransport ] = BF_NO_MAPPING;
/* check, if actually used mapping has just been deleted */
if( psMappingEntry->iTransportId == iTransport )
{
/* find another mapping */
psMappingEntry->iTransportId = 1;
while( psMappingEntry->iTransportId <= EN_CD_LAST_C1C_TRANSPORT )
{
if( bf_s.aiMappingByTransport[ psMappingEntry->iTransportId ] == iMappingEntry )
{
/* get active entry */
psActiveEntry = &bf_s.asActiveEntries[ psMappingEntry->iActiveEntry ];
/* assign new iTransportId */
psActiveEntry->iTransportId = psMappingEntry->iTransportId;
break;
}
psMappingEntry->iTransportId++;
}
}
}
/*
** end edits: October,28th 2005, H.F.
*/
return;
}
if( psMappingEntry->iActiveEntry == BF_NO_MAPPING )
{
return;
}
/*
** Collect convenience pointers and such.
*/
iAppDataAreaId = psMappingEntry->eAppDataAreaId;
psAppDataArea = &bf_s.asAppDataAreas[ iAppDataAreaId ];
psActiveSubList = &psAppDataArea->asActiveSubList[ psMappingEntry->iActiveSubList ];
psActiveEntry = &bf_s.asActiveEntries[ psMappingEntry->iActiveEntry ];
/*
** Remove the penalty for the entry being deactivated.
*/
psActiveSubList->lCpuTimeAreaSubList -= psAppDataArea->lCpuTimePerEntry + ( psAppDataArea->lCpuTimePerByte * psActiveEntry->iResyncSize );
/*
** If there are entries remaining in this active entry sub list,
** take the last entry in the list and backfill the hole we're creating.
** In any case, bump the active entry counts.
*/
GS_EnterCritical();
{
iLastEntry = psActiveSubList->iActiveEntry1 + psActiveSubList->iActiveEntries - 1;
if( ( psActiveSubList->iActiveEntries > 1 ) &&
( psMappingEntry->iActiveEntry != iLastEntry ) )
{
bf_MoveActiveEntry( psMappingEntry->iActiveEntry, iLastEntry );
}
psActiveSubList->iActiveEntries--;
bf_s.iActiveEntries--;
/*
** Zap the references to the now defunct active entry.
*/
iActiveSubList = psMappingEntry->iActiveSubList + 1;
psActiveSubList++;
bf_s.aiMappingByTransport[ psMappingEntry->iTransportId ] = BF_NO_MAPPING;
psMappingEntry->iTransportId = 0;
psMappingEntry->iActiveEntry = BF_NO_MAPPING;
psMappingEntry->iActiveSubList = 0;
}
GS_ExitCritical();
/*
** Roll the remaining active entry lists down to fill the vacated space.
*/
while( iAppDataAreaId < AD_NUM_APP_DATA_AREAS )
{
while( iActiveSubList < BF_NUM_SUB_LISTS )
{
if( psActiveSubList->iActiveEntries > 0 )
{
GS_EnterCritical();
{
psActiveSubList->iActiveEntry1--;
bf_MoveActiveEntry( psActiveSubList->iActiveEntry1, psActiveSubList->iActiveEntry1 + psActiveSubList->iActiveEntries );
}
GS_ExitCritical();
}
iActiveSubList++;
psActiveSubList++;
}
/*
** Roll to the next app mem area starting with the first sub list.
*/
iAppDataAreaId++;
psAppDataArea++;
iActiveSubList = 0;
psActiveSubList = &psAppDataArea->asActiveSubList[ 0 ];
}
/*
** Debug aid. Clean out the last entry in the list
** (we've just abandoned it).
*/
psActiveEntry = &bf_s.asActiveEntries[ bf_s.iActiveEntries ];
psActiveEntry->pSource = NULL;
psActiveEntry->pDestination = NULL;
psActiveEntry->iResyncSize = 0;
psActiveEntry->iTranBufOffset = 0;
psActiveEntry->pAddStatus = NULL;
psActiveEntry->iTransportId = 0;
} /* end of bf_DeactivateMapping() */
/*---------------------------------------------------------------------------
** bf_DeleteMapping()
**---------------------------------------------------------------------------
*/
void bf_DeleteMapping( BF_DeTrrblType *pTrrbl )
{
UINT16 iMappingEntry;
volatile bf_MappingEntryType *psMappingEntry;
volatile bf_MappingEntryType *psLastEntry;
GS_UseCritical();
/*
** Find the entry in the main list.
*/
iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );
if( iMappingEntry == BF_NO_MAPPING )
{
return;
}
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
/*
** Delete one user. Bail if there are more users left.
*/
psMappingEntry->iConfiguredUsers--;
if( psMappingEntry->iConfiguredUsers > 0 )
{
return;
}
/*
** This is the last user. We really need to delete the mapping entry.
** Make sure the entry is deactivated.
*/
while( psMappingEntry->iActiveUsers )
{
bf_DeactivateMapping( pTrrbl );
}
/*
** Bump the mapping entry count.
** If this was the last entry in the list, we be done.
*/
GS_EnterCritical();
{
if( --bf_s.iMappingEntries == iMappingEntry )
{
GS_ExitCritical();
goto Cleanup;
}
/*
** More stuff left in the list. Copy down the last entry in the list
** to fill the space left by the deleted entry.
** Assume the entry being deleted is already disabled.
*/
psLastEntry = &bf_s.asMappingEntries[ bf_s.iMappingEntries ];
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
psMappingEntry->iClass = psLastEntry->iClass;
psMappingEntry->iInstance = psLastEntry->iInstance;
psMappingEntry->fCon = psLastEntry->fCon;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -