📄 xp_osi_filte.c
字号:
{ /*-----------------------------------------------------------------+ | Check for an invalid matchword +-----------------------------------------------------------------*/ if(i >= pChannel->wInuse) { errorMatchWord++; skip = 1; } else { wFilterId = pChannel->wFilterId[i]; if(wFilterId == FILTER_ID_UNUSED) { pChannel->Errors.uwFilterFreed++; skip = 1; } else if (pGlobal->FilterInfo.pXpFilterData[wFilterId]->state!=XP_FILTER_ENABLED) { pChannel->Errors.uwFilterDisabled++; skip = 1; } /*-------------------------------------------------------------+ | Check for filter_length > table length | Determine how to treat short filters +-------------------------------------------------------------*/ else if(pGlobal->FilterInfo.pXpFilterData[wFilterId]->uwLength > pInfo->ulLength) { pChannel->Errors.uwShortTable++; shortFilter = (pChannel->ShortFilter==XP_FILTER_SHORT_DEFAULT) ? pGlobal->FilterInfo.XpFilterDefaultShort : pChannel->ShortFilter; if(shortFilter == XP_FILTER_SHORT_MISS) { skip = 1; } } else if(pGlobal->FilterInfo.pXpFilterData[wFilterId]->wSoftFilter) { /*---------------------------------------------------------+ | Software filter to check the hardware, Reset the | software filtering after the first valid data arrives +---------------------------------------------------------*/ if (filter_match(pGlobal,pGlobal->FilterInfo.pXpFilterData[wFilterId], pInfo, plBQueue, plEQueue) == 1) { pGlobal->FilterInfo.pXpFilterData[wFilterId]->wSoftFilter = 0; skip = 0; } else { pChannel->Errors.uwFilterMatch++; skip = 1; } } else { skip = 0; } } if(skip) { pInfo->ulMatchWord &= ~mask; } } } if(errorMatchWord) { pChannel->Errors.uwFilterMatchWord++; }}/*----------------------------------------------------------------------------+| process_section_change+----------------------------------------------------------------------------*/static void process_section_change(GLOBAL_RESOURCES *pGlobal){ short i; unsigned long changes; unsigned long mask; UINT32 flag; flag = os_enter_critical_section(); changes = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_SFCHNG); os_leave_critical_section(flag); if (changes != pGlobal->FilterInfo.ulXpFilterSectionChange) { for (i=0, mask=0x80000000; i<32; i++, mask>>=1) { if((pGlobal->FilterInfo.ulXpFilterSectionChange & mask) && !(changes & mask)) { xp_osi_filter_process_pending(pGlobal,i); } } }}/*----------------------------------------------------------------------------+| filter_get_state+----------------------------------------------------------------------------*/static SHORT filter_get_state(GLOBAL_RESOURCES *pGlobal,SHORT wFilterId,XP_FILTER_STATUS *pState) /* state of this filter block */{ short rc; rc = xp_osi_filter_valid(pGlobal,wFilterId); if(rc == 0) { *pState = pGlobal->FilterInfo.pXpFilterData[wFilterId]->state; } return(rc);}/*----------------------------------------------------------------------------+| filter_get_pending+----------------------------------------------------------------------------*/static SHORT filter_get_pending(GLOBAL_RESOURCES *pGlobal,SHORT wFilterId, XP_FILTER_PENDING *pPending) /* state of this filter block */{ short rc; rc = xp_osi_filter_valid(pGlobal,wFilterId); if(rc == 0) { *pPending = pGlobal->FilterInfo.pXpFilterData[wFilterId]->pending; } return(rc);}/*----------------------------------------------------------------------------+| XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX| XX X XX XX X XX X XX X XX XX XXX XX XXXX XX| XX X XXX XX XX X XX XX XXXX XX XX XX XX| XXXX X XX XXXX XXXXX XX XXXX XX XX XX| XX X XXX XX XX X XX XX XX XXX XXXXXX XX| XX X XX XX XX XX X XX XX XX XX XX XX XX XX| XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| xp0_filter_init+----------------------------------------------------------------------------*/short xp_osi_filter_init(GLOBAL_RESOURCES *pGlobal){ memset((void *) pGlobal->FilterInfo.pXpFilterData, 0, sizeof(pGlobal->FilterInfo.pXpFilterData)); memset((void *) pGlobal->FilterInfo.XpFilterHwData, 0, sizeof(pGlobal->FilterInfo.XpFilterHwData)); memset((void *) pGlobal->FilterInfo.XpFilterChData, 0, sizeof(pGlobal->FilterInfo.XpFilterChData)); return(0);}/*----------------------------------------------------------------------------+| xp0_filter_process_pending+----------------------------------------------------------------------------*/void xp_osi_filter_process_pending(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId) /* channel containing the data */{ short i; SHORT wFilterId; FILTER_CHANNEL_PTR pChannel; FILTER_PTR pFilter;// xp_os_semaphore_wait(); pChannel = &pGlobal->FilterInfo.XpFilterChData[wChannelId]; /*------------------------------------------------------------------------+ | Process the pending operations +------------------------------------------------------------------------*/ if(pChannel->wPendingRequest) { pChannel->wPendingRequest = 0; for(i=0; i<pChannel->wCount; i++) { wFilterId = pChannel->wFilterId[i]; if(wFilterId != FILTER_ID_UNUSED) { pFilter = pGlobal->FilterInfo.pXpFilterData[wFilterId]; if(pFilter) { if(pFilter->pending == PENDING_FREE) { delete_filter(pGlobal,wChannelId, wFilterId, i); free_filter(pGlobal,wFilterId); } else if(pFilter->pending == PENDING_DELETE) { delete_filter(pGlobal,wChannelId, wFilterId, i); } } } } }// xp_os_semaphore_signal();}/*----------------------------------------------------------------------------+| xp0_filter_process_table_data| (Under interrupt control)+----------------------------------------------------------------------------*/void xp_osi_filter_process_table_data(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId, /* channel containing the data */UCHAR *plBa, /* starting address of available data */UCHAR *plEa, /* ending address of available data */UCHAR *plBq, /* starting address of the queue */UCHAR *plEq, /* ending address of the queue */SHORT wSectionFilter, /* 1=filtering enabled, 0=no filtering */XP_CHANNEL_NOTIFY_FN notify_fn) /* application function to call */{ short wrapCount; /* number of queue wraps,for loop check */ XP_QUEUE_MODE_TYPE mode; /* LOCK or SKIP */ UCHAR *plByteAddr; /* bytes address of current table */ ULONG *plAddr; /* address incremented through tables */ ULONG *plBAddr; /* starting word address of the data */ ULONG *plEAddr; /* ending word address of the data */ ULONG *plBQueue; /* starting word address of the queue */ ULONG *plEQueue; /* ending word address of the queue */ UCHAR *ppByteAddr; UCHAR *ppEAddr; UCHAR *ppBQueue; PSI_HEADER_TYPE h; /* word containing the table header */ unsigned long length; /* number of words in current table */ unsigned long avail; /* number of words until a queue wrap */ XP_CHANNEL_NOTIFY_DATA Info; /* notification data for application */// xp_os_semaphore_wait(); Info.pGlobal = pGlobal; /*------------------------------------------------------------------------+ | Convert pointers to improve performance of reads +------------------------------------------------------------------------*/ plBQueue = (unsigned long *) plBq; plEQueue = (unsigned long *) plEq; plBAddr = (unsigned long *) plBa; plEAddr = (unsigned long *) plEa; /*------------------------------------------------------------------------+ | Setup the pointer to the table section header +------------------------------------------------------------------------*/ Info.wChannelId = wChannelId; /*------------------------------------------------------------------------+ | Get the matchword | Read the word containing the table section header and setup the info | structure with the starting address and the length of the table +------------------------------------------------------------------------*/ for(wrapCount=0, plAddr=plBAddr; (plAddr != plEAddr) && (wrapCount < 2); ) { Info.ulMatchWord = *plAddr; plAddr++; if(plAddr == plEQueue) { plAddr = plBQueue; } h = *(PSI_HEADER_PTR)plAddr; /*--------------------------------------------------------------------+ | Determine the starting address and table length and calculate the | ending (byte) address for use when recording the record lock +--------------------------------------------------------------------*/ plByteAddr = (unsigned char *) plAddr; Info.plData = plByteAddr; Info.ulLength = PSI_HEADER_LENGTH + h.sectionLength; ppBQueue = (UCHAR*)os_get_physical_address(pGlobal->QueueInfo.XpQueueChData[wChannelId].hMem); ppByteAddr = ppBQueue + (ULONG)Info.plData - (ULONG)plBQueue; /*--------------------------------------------------------------------+ | Find the end of the table. We must adjust this pointer based on | where the queue wraps +--------------------------------------------------------------------*/ avail = plEq - plByteAddr; if(avail <= Info.ulLength) { plByteAddr = plBq + (Info.ulLength - avail); } else { plByteAddr += Info.ulLength; } ppEAddr = ppBQueue + (ULONG)plByteAddr - (ULONG)plBQueue; mode = XP_QUEUE_MODE_LOCK; /*--------------------------------------------------------------------+ | if we're filtering, check the filters against the software values. | Set the skip value if the hardware match is overridden. +--------------------------------------------------------------------*/ if(wSectionFilter) { /*----------------------------------------------------------------+ | Check the section filters to be sure they we're disabled by | software if we've overridden all the filter matches, then | skip the table +----------------------------------------------------------------*/ check_filters(pGlobal,wChannelId, &Info, plBq, plEq); if(Info.ulMatchWord == 0) { mode = XP_QUEUE_MODE_SKIP; } } /*--------------------------------------------------------------------+ | Calculate the number of words which we need to move to get to | the start of the next table. Since tables are aligned on word | boundaries, adjust the length to a 4 byte boundary. | Now move the address pointer. We must adjust this pointer based | on where the queue wraps. +--------------------------------------------------------------------*/ length = (Info.ulLength + 3) / 4; avail = plEQueue - plAddr; if(avail <= length) { plAddr = plBQueue + (length - avail); wrapCount++; } else { plAddr += length; } /*--------------------------------------------------------------------+ | Process the record by locking, and notifying the application. +--------------------------------------------------------------------*/ xp_osi_queue_lock_data(pGlobal,wChannelId, mode, ppByteAddr, ppEAddr); if(mode == XP_QUEUE_MODE_LOCK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -