📄 xp_osi_filte.c
字号:
|| ERRORS : XP_ERROR_CHANNEL_INVALID - channel_id is not defined|| COMMENTS : xp0_filter_control() is used to enable or disable the| filter.|+----------------------------------------------------------------------------*/SHORT xp_osi_filter_control(GLOBAL_RESOURCES *pGlobal,SHORT wFilterId,XP_FILTER_CONTROL_TYPE cmd){ short rc; SHORT wHwFilterId; FILTER_PTR pFilter=NULL; UINT32 flag;// xp_os_semaphore_wait(); /*------------------------------------------------------------------------+ | Verify the channel and filter id's are valid +------------------------------------------------------------------------*/ rc = xp_osi_filter_valid(pGlobal,wFilterId); PDEBUG("lingh ==== rc = %d\n",rc); /*------------------------------------------------------------------------+ | Make sure the filter was added to a channel +------------------------------------------------------------------------*/ if(rc == 0) { pFilter = pGlobal->FilterInfo.pXpFilterData[wFilterId]; switch(pFilter->state) { case XP_FILTER_ENABLED: case XP_FILTER_DISABLED: break; default: rc = XP_ERROR_FILTER_NOT_ASSIGN; break; } } if(rc == 0) { if(pFilter->pending == PENDING_FREE) { PDEBUG("rc = XP_ERROR_FILTER_PENDING\n"); rc = XP_ERROR_FILTER_PENDING; } } /*------------------------------------------------------------------------+ | Get the id number of the first filter block in hardware. All other | filter blocks should already be enabled +------------------------------------------------------------------------*/ if (rc == 0) { wHwFilterId = pFilter->cHwBlockId[0]; switch(cmd) { case XP_FILTER_CONTROL_ENABLE: flag = os_enter_critical_section(); xp_atom_dcr_write_register_channel(pGlobal->uDeviceIndex, XP_FILTER_CONTROL_REG_ENBL, wHwFilterId, 1); os_leave_critical_section(flag); pFilter->state = XP_FILTER_ENABLED; break; case XP_FILTER_CONTROL_DISABLE: flag = os_enter_critical_section(); xp_atom_dcr_write_register_channel(pGlobal->uDeviceIndex, XP_FILTER_CONTROL_REG_ENBL, wHwFilterId, 0); os_leave_critical_section(flag); pFilter->state = XP_FILTER_DISABLED; break; default: rc = XP_ERROR_INTERNAL; break; } }// xp_os_semaphore_signal(); return(rc);}/*----------------------------------------------------------------------------+| xp0_filter_delete_from_channel+-----------------------------------------------------------------------------+|| DESCRIPTION: remove table section filter from channel|| PROTOTYPE : short xp0_filter_delete_from_channel(| short channel_id,| short filter_id)|| ARGUMENTS : channel_id - the channel id as returned from the| xp0_channel_allocate().| filter_id - the filter number as returned from the| xp0_filter_allocate().|| RETURNS : 0 if successful, or non-zero if an error occurs|| ERRORS : XP_ERROR_CHANNEL_INVALID - channel_id is not defined| XP_ERROR_FILTER_INVALID - one or more filters invalid|| COMMENTS : section filters are removed from the channel by updating| the links in the hardware filter blocks. Table sections| are not be delivered to the application after the| xp0_filter_delete_from_channel() completes. If the last| filter is removed from the channel, and the channel is| configured for table section filtering, then the channel| is automatically disabled.|| Section filters may be removed from an active channel| without disabling the channel. Since the hardware could| be processing a table section split across multiple| packets, the hardware filter blocks are not released from| the channel until the hardware completes processing the| current table section.|+----------------------------------------------------------------------------*/SHORT xp_osi_filter_delete_from_channel(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId,SHORT wFilterId){ short rc; short i; unsigned long mask; FILTER_TYPE *pFilter=NULL; FILTER_CHANNEL_TYPE *pChannel=NULL; XP_CHANNEL_STATUS channel_status; XP_QUEUE_STATUS queue_status; UINT32 flag;// xp_os_semaphore_wait(); /*------------------------------------------------------------------------+ | Verify the channel and filter id's are valid +------------------------------------------------------------------------*/ rc = xp_osi_channel_valid(pGlobal,wChannelId); if(rc == 0) {// printk("1\n"); rc = xp_osi_filter_valid(pGlobal,wFilterId); } if(rc == 0) {// printk("2\n"); pChannel = &pGlobal->FilterInfo.XpFilterChData[wChannelId]; pFilter = pGlobal->FilterInfo.pXpFilterData[wFilterId]; if(pFilter->pending != PENDING_NONE) {// printk("3\n"); rc = XP_ERROR_FILTER_PENDING; } } /*------------------------------------------------------------------------+ | Check that the filter was added to the channel +------------------------------------------------------------------------*/ if(rc == 0) {// printk("4\n"); switch(pFilter->state) { case XP_FILTER_UNUSED: rc = XP_ERROR_FILTER_UNDEFINED;// printk("5\n"); break; case XP_FILTER_DEFINED:// printk("6\n"); rc = XP_ERROR_FILTER_NOT_ASSIGN; break; case XP_FILTER_ENABLED:// printk("7\n"); rc = xp_osi_filter_control(pGlobal,wFilterId, XP_FILTER_CONTROL_DISABLE); break; case XP_FILTER_DISABLED:// printk("8\n"); break; default:// printk("9\n"); rc = XP_ERROR_INTERNAL; break; } } /*------------------------------------------------------------------------+ | Determine if the filter is associated with the channel +------------------------------------------------------------------------*/ if(rc == 0) {// printk("10\n"); rc = find_filter(pGlobal,wChannelId, wFilterId, &i); } /*------------------------------------------------------------------------+ | Remove the filter only if the channel or queue is disabled, | otherwise, defer the request until the hardware has finished using | the filter block (ie. moveUp). +------------------------------------------------------------------------*/ if(rc == 0) {// printk("11\n"); rc = xp_osi_channel_get_status(pGlobal,wChannelId, &channel_status); } if(rc == 0) {// printk("12\n"); rc = xp_osi_queue_get_status(pGlobal,wChannelId, &queue_status); } /*------------------------------------------------------------------------+ | Signal to the changes register in hardware. Process the request later | if the stream is enabled and the section_change bit was not cleared +------------------------------------------------------------------------*/ if(rc == 0) {// printk("13\n"); pFilter->state = XP_FILTER_DEFINED; mask = 0x80000000 >> wChannelId; flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_SFCHNG, mask); pGlobal->FilterInfo.ulXpFilterSectionChange = xp_atom_dcr_read(pGlobal->uDeviceIndex,XP_DCR_ADDR_SFCHNG); os_leave_critical_section(flag); if((channel_status == XP_CHANNEL_ENABLED) && (queue_status == XP_QUEUE_STATUS_ENABLED) && (pGlobal->FilterInfo.ulXpFilterSectionChange & mask)) { pFilter->pending = PENDING_DELETE; pChannel->wPendingRequest++; } else {// printk("14\n"); delete_filter(pGlobal,wChannelId, wFilterId, i); } }// xp_os_semaphore_signal(); return(rc);}/*----------------------------------------------------------------------------+| xp0_filter_free+-----------------------------------------------------------------------------+|| DESCRIPTION: release space for a table section filter|| PROTOTYPE : short xp0_filter_free(| short filter_id)|| ARGUMENTS: : filter_id - the filter number as returned from the| xp0_filter_allocate().|| RETURNS : 0 if the operation was successful, or a negative value| if an error occurs|| ERRORS : XP_ERROR_FILTER_INVALID - filter_id was not allocated|| COMMENTS : This function frees filter blocks allocated to the filter.| If the filter was added to a channel using the| xp0_filter_add_to_channel(), it will be removed from the| before being freed.|+----------------------------------------------------------------------------*/SHORT xp_osi_filter_free(GLOBAL_RESOURCES *pGlobal,SHORT wFilterId){ short rc; FILTER_TYPE *pFilter=NULL;// xp_os_semaphore_wait(); rc = xp_osi_filter_valid(pGlobal,wFilterId); if(rc == 0) { pFilter = pGlobal->FilterInfo.pXpFilterData[wFilterId]; switch(pFilter->state) { case XP_FILTER_UNUSED: case XP_FILTER_DEFINED: break; case XP_FILTER_ENABLED: case XP_FILTER_DISABLED: rc = XP_ERROR_FILTER_INUSE; break; default: rc = XP_ERROR_INTERNAL; break; } } /*------------------------------------------------------------------------+ | Process immediately if there are no pending requests. Otherwise, | defer the request until the hardware has finished using the filter +------------------------------------------------------------------------*/ if(rc == 0) { if(pFilter->pending == PENDING_NONE) { free_filter(pGlobal,wFilterId); } else { pFilter->pending = PENDING_FREE; } }// xp_os_semaphore_signal(); return(rc);}/*----------------------------------------------------------------------------+| xp0_filter_free_channel+-----------------------------------------------------------------------------+|| DESCRIPTION: free all filter blocks for a channel|| PROTOTYPE : short xp0_filter_free_channel(| short channel_id)|| ARGUMENTS : channel_id - the channel id as returned from the| xp0_channel_allocate().|| RETURNS : 0 if successful, or non-zero if an error occurs|| ERRORS : XP_ERROR_CHANNEL_INVALID - channel_id is not defined|| COMMENTS : xp0_filter_free() is called to remove each filter assigned| to the channel.|+----------------------------------------------------------------------------*/SHORT xp_osi_filter_free_channel(GLOBAL_RESOURCES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -