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

📄 xp_osi_queue.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 4 页
字号:
    |  Make sure the channel is still allocated    +------------------------------------------------------------------------*/    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        /*--------------------------------------------------------------------+        |  Try to recover from a read pointer error        +--------------------------------------------------------------------*/        if(ulInterrupt & XP_INTERRUPT_QSTAT_RPI)        {            pChannel->Errors.uwReadPointer++;            pChannel->wRpiStatus = 1;            process_read_pointer(pGlobal,wChannelId);        }        if(ulInterrupt & XP_INTERRUPT_QSTAT_CRCE)        {            pChannel->Errors.uwCrc32++;        }        if(ulInterrupt & XP_INTERRUPT_QSTAT_TSLE)        {            pChannel->Errors.uwSectionLength++;        }        if(ulInterrupt & XP_INTERRUPT_QSTAT_PSE)        {            pChannel->Errors.uwCc++;        }    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|   XX     XXXXXX    XXXXXX    XXXXX|  XXXX    XX   XX     XX     XX   XX| XX  XX   XX   XX     XX      XX| XX  XX   XXXXX       XX        XX| XXXXXX   XX          XX         XX| XX  XX   XX          XX     XX   XX| XX  XX   XX        XXXXXX    XXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|  xp0_queue_allocate+-----------------------------------------------------------------------------+||  DESCRIPTION:  define a queue for data delivered on this channel||  PROTOTYPE  :  short xp0_queue_allocate(|                short wChannel_Id,|                unsigned long queue_size||  ARGUMENTS  :  wChannel_Id    -  the channel id as returned from the|                                 xp0_channel_allocate().|                queue_size    -  minimum size of queue in bytes||  RETURNS    :  0 if successful, or non-zero if an error occurs||  ERRORS     :  XP_ERROR_CHANNEL_INVALID  -  channel id is not defined|                XP_ERROR_OUT_OF_SPACE     -  space is not available for a|                                          a queue of the requested size||  COMMENTS   :  defines a queue for use by the channel specified.|+----------------------------------------------------------------------------*/SHORT xp_osi_queue_allocate(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId, ULONG ulQueueSize){    short rc;    UCHAR *ppAddr;    unsigned long u;    ULONG ulQueueTop;    ULONG ulQueueBottom;    QUEUE_PTR pChannel;    UINT32  flag;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        if(queue_valid(pGlobal,wChannelId) == 0)        {            rc = XP_ERROR_QUEUE_DEFINED;        }    }    if(rc == 0)    {        u = ulQueueSize % QUEUE_BLOCK_SIZE;        if(u)        {            ulQueueSize += (QUEUE_BLOCK_SIZE - u);        }        if(pChannel->wLockAlloc > 0)        {            FREE(pChannel->pLockData);        }//lingh        pChannel->hMem = pm_alloc_physical(pGlobal->gpPMRoot,ulQueueSize);        if(pChannel->hMem == NULL)            return -1;    PDEBUG("pm_alloc_physical, phy = %x, logical = %x\n",os_get_physical_address(pChannel->hMem),os_get_logical_address(pChannel->hMem));        ppAddr = MAKE_PLB_ADDR(os_get_physical_address(pChannel->hMem));        pChannel->ulQueueAddr       = os_get_physical_address(pChannel->hMem);        pChannel->ulQueueSize       = ulQueueSize;        pChannel->wLockInuse        = 0;        pChannel->wLockAlloc        = 0;        pChannel->pLockData         = NULL;        pChannel->ppLockAddr        = NULL;        pChannel->ppProcessAddr     = ppAddr;        xp_osi_queue_reset_errors(pGlobal,wChannelId);        /*--------------------------------------------------------------------+        |  Write the new queue definition, and initialize the queue state        |  to disabled        +--------------------------------------------------------------------*/        ulQueueBottom = pChannel->ulQueueAddr / QUEUE_BLOCK_SIZE;        ulQueueTop    = (pChannel->ulQueueAddr +  pChannel->ulQueueSize) / QUEUE_BLOCK_SIZE;        flag = os_enter_critical_section();        xp_atom_dcr_init_queue(pGlobal->uDeviceIndex,wChannelId, ulQueueTop, ulQueueBottom);        os_leave_critical_section(flag);        pChannel->State = XP_QUEUE_STATUS_DISABLED;        /*--------------------------------------------------------------------+        |  Reset the queue.  This will cause the hardware to set the        |  read_address = queue_bottom        +--------------------------------------------------------------------*/        rc = xp_osi_queue_control(pGlobal,wChannelId, XP_QUEUE_CONTROL_RESET);    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_control+-----------------------------------------------------------------------------+||  DESCRIPTION:  controls the state of the queue||  PROTOTYPE  :  short xp0_queue_control(|                short wChannel_Id,|                XP_QUEUE_CONTROL_TYPE cmd)||  ARGUMENTS  :  wChannel_Id    -  the channel id as returned from the|                                 xp0_channel_allocate().|                cmd           -  XP_QUEUE_CONTROL_ENABLE  -  enable queue|                                 XP_QUEUE_CONTROL_DISABLE -  disable queue|                                 XP_QUEUE_CONTROL_RESET   -  reset the queue||  RETURNS    :  0 if successful, or non-zero if an error occurs||  ERRORS     :  XP_ERROR_CHANNEL_INVALID  -  channel id is not defined|                XP_ERROR_INTERNAL         -  internal driver error||  COMMENTS   :  controls the current queue state.  XP_QUEUE_CONTROL_DISABLE|                prevents the delivery of new data.  Existing data in the|                queue is undisturbed.  XP_QUEUE_CONTROL_ENABLE restarts a|                disabled queue.  XP_QUEUE_CONTROL_RESET disables the queue,|                resets the read/write pointers, and unlocks all locked|                sections for the channel.|+----------------------------------------------------------------------------*/SHORT xp_osi_queue_control(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId, XP_QUEUE_CONTROL_TYPE Cmd){    short rc;    ULONG ulData;    QUEUE_PTR pChannel;    UINT32  flag;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        rc = queue_valid(pGlobal,wChannelId);    }    if(rc == 0)    {        switch(Cmd)        {        case XP_QUEUE_CONTROL_ENABLE:            flag = os_enter_critical_section();            xp_atom_dcr_write_register_channel(pGlobal->uDeviceIndex,XP_QCONFIGB_REG_ENBL,                                                     wChannelId, 1);            os_leave_critical_section(flag);            pGlobal->QueueInfo.XpQueueChData[wChannelId].State = XP_QUEUE_STATUS_ENABLED;            rc = xp_osi_channel_restart(pGlobal,wChannelId);            break;            /*----------------------------------------------------------------+            |  Write the "stops" register to stop any "in-process" packets            |  from being delivered. Clear any pending filter operations            |  Clear the interrupts to get rid of any latent interrupts            +----------------------------------------------------------------*/        case XP_QUEUE_CONTROL_DISABLE:            ulData = (1 << (31 - wChannelId));            flag = os_enter_critical_section();            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QSTOPS, ulData);            os_leave_critical_section(flag);            xp_osi_filter_process_pending(pGlobal,wChannelId);            rc = xp_osi_interrupt_channel_control(pGlobal,wChannelId,                                 XP_INTERRUPT_CONTROL_RESET);            flag = os_enter_critical_section();            xp_atom_dcr_write_register_channel(pGlobal->uDeviceIndex,XP_QCONFIGB_REG_ENBL,                wChannelId, 0);            os_leave_critical_section(flag);            pChannel->State = XP_QUEUE_STATUS_DISABLED;            break;            /*----------------------------------------------------------------+            |  Reset the queue, and set the read_addr to the queue bottom.            |  Remove all the skip and lock records            +----------------------------------------------------------------*/        case XP_QUEUE_CONTROL_RESET:            if(pChannel->State != XP_QUEUE_STATUS_DISABLED)            {                rc = xp_osi_queue_control(pGlobal,wChannelId, XP_QUEUE_CONTROL_DISABLE);            }            ulData = (1 << (31 - wChannelId));            flag = os_enter_critical_section();            xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_QRESETS, ulData);            os_leave_critical_section(flag);            pChannel->ppReadAddr    =   MAKE_PLB_ADDR(pChannel->ulQueueAddr);            pChannel->ppProcessAddr =   MAKE_PLB_ADDR(pChannel->ulQueueAddr);            pChannel->wLockInuse = 0;            pChannel->ppLockAddr  = NULL;            break;        default:            break;        }    }//    xp_os_semaphore_signal();   PDEBUG("xp_osi_channel_restart return\n");    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_free+-----------------------------------------------------------------------------+||  DESCRIPTION:  define a queue for data unloaded on this channel||  PROTOTYPE  :  short xp0_queue_free(|                short wChannel_Id)||  ARGUMENTS  :  wChannel_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|                XP_ERROR_QUEUE_UNDEFINED  -  queue is not currently defined||  COMMENTS   :  frees the queue allocated to the channel.  All locked|                regions are released.|+----------------------------------------------------------------------------*/SHORT xp_osi_queue_free(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId){    short rc;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    /*------------------------------------------------------------------------+    |  Check that the wChannel_Id is valid and the queue is currently defined.    |  Then disable the queue    +------------------------------------------------------------------------*/    rc = xp_osi_queue_control(pGlobal,wChannelId, XP_QUEUE_CONTROL_DISABLE);    if(rc == 0 && pChannel->hMem != NULL)    {        //lingh        pm_free_physical(pGlobal->gpPMRoot,pChannel->hMem);    }    pChannel->ulQueueAddr = 0;    pChannel->ulQueueSize = 0;    pChannel->State      = XP_QUEUE_STATUS_UNDEFINED;        /*--------------------------------------------------------------------+        |  Remove all the skip and lock records        +--------------------------------------------------------------------*/    pChannel->wLockInuse = 0;    pChannel->ppLockAddr  = NULL;    if(pChannel->wLockAlloc > 0)    {        FREE(pChannel->pLockData);        pChannel->pLockData = NULL;        pChannel->wLockAlloc = 0;    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_get_config+----------------------------------------------------------------------------*/SHORT xp_osi_queue_get_config(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                              UCHAR **pBQueue, UCHAR **pEQueue)           /* queue range is exclusive             */{    short rc;    UCHAR *plBQueue;    UCHAR *plEQueue;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        plBQueue = os_get_logical_address(pChannel->hMem);        plEQueue = plBQueue + pChannel->ulQueueSize;        *pBQueue = plBQueue;        *pEQueue = plEQueue;    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_get_errors+----------------------------------------------------------------------------*/SHORT xp_osi_queue_get_errors(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                              XP_QUEUE_ERROR_PTR pErrors)

⌨️ 快捷键说明

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