⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xp_osi_filte.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 5 页
字号:
        {       /*-----------------------------------------------------------------+       |  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 + -