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

📄 xp_osi_queue.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 4 页
字号:
        }        pChannel->wLockInuse--;    }    else if(ppBAddr == pChannel->pLockData[wIndex].ppBAddr)    {        pChannel->pLockData[wIndex].ppBAddr = ppEAddr;    }    else    {        pChannel->pLockData[wIndex].ppEAddr = ppBAddr;    }    /*------------------------------------------------------------------------+    |  If the record being unlocked matches the current read pointer in    |  hardware, then we have to move the read pointer    +------------------------------------------------------------------------*/    if(pChannel->ppLockAddr == ppBAddr)    {        /*--------------------------------------------------------------------+        |  If there are no more lock records, then use the most recent        |  region processed        +--------------------------------------------------------------------*/        if(pChannel->wLockInuse == 0)        {            update_read_pointer(pGlobal,wChannelId, pChannel->ppProcessAddr);        }        /*--------------------------------------------------------------------+        |  If there is another entry in the list, then use address of the        |  next entry, otherwise use the address in the beginning of the list        +--------------------------------------------------------------------*/        else        {            if(wIndex < pChannel->wLockInuse)            {                pChannel->ppLockAddr = pChannel->pLockData[wIndex].ppBAddr;            }            else            {                pChannel->ppLockAddr = pChannel->pLockData[0].ppBAddr;            }            update_read_pointer(pGlobal,wChannelId, pChannel->ppLockAddr);        }    }    /*------------------------------------------------------------------------+    |  if we're in an RPI condition, then try to find a new region to get    |  going again    +------------------------------------------------------------------------*/    else if(pChannel->wRpiStatus)    {        process_read_pointer(pGlobal,wChannelId);    }    return(0);}/*----------------------------------------------------------------------------+|  queue_valid+----------------------------------------------------------------------------*/static short queue_valid(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId){    if(pGlobal->QueueInfo.XpQueueChData[wChannelId].State == XP_QUEUE_STATUS_UNDEFINED)    {        return(XP_ERROR_QUEUE_UNDEFINED);    }    return(0);}/*----------------------------------------------------------------------------+| 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+----------------------------------------------------------------------------*/void xp_osi_queue_de_init(GLOBAL_RESOURCES *pGlobal){    if(pGlobal->gpPMRoot != NULL)    {        __pm_alloc_physical_deinit(pGlobal->gpPMRoot);        os_free_physical(pGlobal->hRoot);        pGlobal->gpPMRoot = NULL;        pGlobal->hRoot = NULL;    }}/*----------------------------------------------------------------------------+|  xp0_queue_init+----------------------------------------------------------------------------*/SHORT xp_osi_queue_init(GLOBAL_RESOURCES *pGlobal){    short i;    short rc=0;    ULONG ulAddr;    UINT32  flag;    MEM_HANDLE_T hRoot;    UINT uPhyAddr;    void *pLogicalAddr;    /*------------------------------------------------------------------------+    |  Free any space from a previous initialization    +------------------------------------------------------------------------*/    if(pGlobal->QueueInfo.uXpQueueInited)    {        for(i=0; i<XP_CHANNEL_COUNT; i++)        {            if(pGlobal->QueueInfo.XpQueueChData[i].pLockData)            {                FREE(pGlobal->QueueInfo.XpQueueChData[i].pLockData);            }        }    }    pGlobal->QueueInfo.uXpQueueInited = 1;    /*------------------------------------------------------------------------+    |  Setup the channels    +------------------------------------------------------------------------*/    for(i=0; i<XP_CHANNEL_COUNT; i++)    {        pGlobal->QueueInfo.XpQueueChData[i].State       = XP_QUEUE_STATUS_UNDEFINED;        pGlobal->QueueInfo.XpQueueChData[i].ulQueueAddr  = 0;        pGlobal->QueueInfo.XpQueueChData[i].ulQueueSize  = 0;        pGlobal->QueueInfo.XpQueueChData[i].wLockAlloc  = 0;        pGlobal->QueueInfo.XpQueueChData[i].wLockInuse  = 0;        pGlobal->QueueInfo.XpQueueChData[i].pLockData   = NULL;        pGlobal->QueueInfo.XpQueueChData[i].hMem    = NULL;        xp_osi_queue_reset_errors(pGlobal,i);    }    /*------------------------------------------------------------------------+    |  If the address is to be used, then make sure the address is    |  properly aligned    +------------------------------------------------------------------------*///lingh added in 5/29/2002    __os_alloc_physical_heap_walk();    hRoot = os_alloc_physical_justify(pGlobal->uReservedBufSize, 0x400000);    __os_alloc_physical_heap_walk();    if(hRoot == NULL )    {        return -1;    }    pGlobal->hRoot = hRoot;    uPhyAddr = os_get_physical_address(hRoot);    pLogicalAddr = os_get_logical_address(hRoot);    ulAddr = uPhyAddr;    pGlobal->gpPMRoot = __pm_alloc_physical_init(uPhyAddr, pLogicalAddr,        pGlobal->uReservedBufSize,256);    __os_alloc_physical_heap_walk();    if(pGlobal->gpPMRoot == NULL)    {        os_free_physical(hRoot);        return -1;    }    /*------------------------------------------------------------------------+    |  We have an aligned address, so save the address onto the freelist,    |  and setup the hardware base address    +------------------------------------------------------------------------*/    pGlobal->QueueInfo.ulXpQueueBAddr = ulAddr & 0xff000000;    flag = os_enter_critical_section();    xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QBASE, pGlobal->QueueInfo.ulXpQueueBAddr);    os_leave_critical_section(flag);    pGlobal->QueueInfo.ulXpQueueBAddr |= REGION_PLB_BYTE_OFFSET;    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_get_status+----------------------------------------------------------------------------*/SHORT xp_osi_queue_get_status(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                              XP_QUEUE_STATUS *pStatus){    short rc;//    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        *pStatus = pGlobal->QueueInfo.XpQueueChData[wChannelId].State;    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_process_data+-----------------------------------------------------------------------------+||  DESCRIPTION:  define a queue for data unloaded on this channel||  PROTOTYPE  :  short xp0_queue_process_data(|                short wChannel_Id,|                CHANNEL_UNLOAD_TYPE unload_type,|                XP_CHANNEL_NOTIFY_FN notify_fn)||  ARGUMENTS  :  wChannel_Id    -  the channel id as returned from the|                                 xp0_channel_allocate().|                unload_type   -  type of data being unloaded||  RETURNS    :||  COMMENTS   :  This function determines the amount of data to process.|                The starting address of the data to process is the|                address where we last read (read_addr).  The ending|                address is acquired from hardware.|                    If the unload type is for tables, then the tables are|                determined and the application is notified for each|                completed table.|+----------------------------------------------------------------------------*/void xp_osi_queue_process_data(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                               XP_CHANNEL_UNLOAD_TYPE UnloadType, XP_CHANNEL_NOTIFY_FN notify_fn){    short rc;    SHORT wSectionFilter;       /* 1=filtering enabled, 0=no filtering  */    ULONG ulWriteStart;         /* hardware write pointer               */    UCHAR *ppBQueue=NULL;       /* starting address of the queue        */    UCHAR *ppEQueue=NULL;       /* ending address of the queue          */    UCHAR *ppBAddr=NULL;        /* start address of the data            */    UCHAR *ppEAddr=NULL;        /* end address of the data              */    UCHAR *plBQueue=NULL;       /* starting address of the queue        */    UCHAR *plEQueue=NULL;       /* ending address of the queue          */    UCHAR *plBAddr=NULL;        /* start address of the data            */    UCHAR *plEAddr=NULL;        /* end address of the data              */    ULONG ulLength;             /* ending address of the data           */    XP_CHANNEL_NOTIFY_DATA Info;    /* notification data                    */    QUEUE_PTR pChannel;    UINT32  flag;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    /*------------------------------------------------------------------------+    |  Make sure the channel is still allocated    +------------------------------------------------------------------------*/    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        flag = os_enter_critical_section();        rc = xp_atom_dcr_read_register_channel(pGlobal->uDeviceIndex,XP_QSTATD_REG_WSTART,                                       wChannelId, &ulWriteStart);        os_leave_critical_section(flag);    }    if(rc == 0)    {        /*--------------------------------------------------------------------+        |  Get the queue range, and the address range of the data        +--------------------------------------------------------------------*/        ppBAddr  = pChannel->ppReadAddr;        ppEAddr  = MAKE_PLB_ADDR(ulWriteStart);        ppBQueue = MAKE_PLB_ADDR(pChannel->ulQueueAddr);        ppEQueue = ppBQueue + pChannel->ulQueueSize;    PDEBUG("ppBAddr = %8.8x\n",ppBAddr);    PDEBUG("ppEAddr = %8.8x\n",ppEAddr);    PDEBUG("ppBQueue = %8.8x\n",ppBQueue);    PDEBUG("ppEQueue = %8.8x    \n",ppEQueue);        /*--------------------------------------------------------------------+        |  make sure the address range is within the bounds of the queue        +--------------------------------------------------------------------*/        if((ppBAddr < ppBQueue) || (ppEAddr > ppEQueue))        {    PDEBUG("XP_ERROR_QUEUE_ADDRESS1\n");            pChannel->Errors.uwQueueAddress++;            rc = XP_ERROR_QUEUE_ADDRESS;        }        /*--------------------------------------------------------------------+        |  Abort if there is no data        +--------------------------------------------------------------------*/        else if(ppBAddr == ppEAddr)        {    PDEBUG("XP_ERROR_QUEUE_ADDRESS2\n");            pChannel->Errors.uwNoData++;            rc = XP_ERROR_QUEUE_ADDRESS;        }    }    if(rc == 0)    {        /*--------------------------------------------------------------------+        |  Check if queue is not active, then we'll skip the new record        |  which must have arrived in the hardware when we changed the state        |  to DISABLED.        +--------------------------------------------------------------------*/        if(pChannel->State != XP_QUEUE_STATUS_ENABLED)        {    PDEBUG("pChannel->Errors.uwQueueDisabled\n");            pChannel->Errors.uwQueueDisabled++;        }        else        {            /*----------------------------------------------------------------+            |  Calculate the number of bytes, and adjust the read pointer.            |  We must also check if a queue wrap occurred.            +----------------------------------------------------------------*/        PDEBUG("ppBAddr = %8.8x\n",ppBAddr);        PDEBUG("ppEAddr = %8.8x\n",ppEAddr);        PDEBUG("ppBQueue = %8.8x\n",ppBQueue);        PDEBUG("ppEQueue = %8.8x        \n",ppEQueue);            if(ppBAddr <= ppEAddr)            {    PDEBUG("ppBAddr <= ppEAddr\n");                ulLength = ppEAddr - ppBAddr;            }            else            {        PDEBUG("2\n");                ulLength = (ppEQueue - ppBAddr) + (ppEAddr - ppBQueue);            }       PDEBUG("uulLength = %8.8x\n",ulLength);            /*----------------------------------------------------------------+            |  If the application has requested notification, then process            |  the data, otherwise the hardware will continue to advance the            |  writeStart until a read pointer error occurs or the application            |  sets the notify function.            +----------------------------------------------------------------*/            if(notify_fn)            {                /*------------------------------------------------------------+                |  For table unloading, process each table section                |  The sectionFilter = 0 if the unload type does NOT require                |  filtering, 1=filtering tables                +------------------------------------------------------------*/                if(UnloadType >= XP_CHANNEL_UNLOAD_PSI)                {                    wSectionFilter = (UnloadType % 2);                    plBQueue = (UCHAR*)os_get_logical_address(pChannel->hMem);                    plEQueue = plBQueue + pChannel->ulQueueSize;                    plBAddr = plBQueue+(ULONG)ppBAddr - (ULONG)pChannel->ulQueueAddr;                    plEAddr = plBQueue+(ULONG)ppEAddr - (ULONG)pChannel->ulQueueAddr;                    xp_osi_filter_process_table_data(pGlobal,wChannelId, plBAddr, plEAddr,                              plBQueue, plEQueue, wSectionFilter, notify_fn);                }                /*------------------------------------------------------------+                |  Keep track of the record locked call the application to                |  notify of data available                +------------------------------------------------------------*/                else                {                    Info.pGlobal        = pGlobal;                    Info.wChannelId     = wChannelId;                    Info.ulMatchWord    = 0;                    Info.plData         = (UCHAR*)((ULONG)os_get_logical_address(pChannel->hMem)                        +(ULONG)ppBAddr - (ULONG)pChannel->ulQueueAddr);                    Info.ulLength       = ulLength;                    xp_osi_queue_lock_data(pGlobal,wChannelId, XP_QUEUE_MODE_LOCK,                                       ppBAddr, ppEAddr);                    (notify_fn)(&Info);                }                /*------------------------------------------------------------+                |  Update the read pointer after processing the data                +------------------------------------------------------------*/                pGlobal->QueueInfo.XpQueueChData[wChannelId].ppReadAddr = ppEAddr;            }        }    }//    xp_os_semaphore_signal();}/*----------------------------------------------------------------------------+|  xp0_queue_process_interrupt+----------------------------------------------------------------------------*/short xp_osi_queue_process_interrupt(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                                     ULONG ulInterrupt){    short rc;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    /*------------------------------------------------------------------------+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -