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

📄 xp_osi_queue.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 4 页
字号:
{    short rc;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc)    {        return(rc);    }    memcpy(pErrors, &pChannel->Errors, sizeof(XP_QUEUE_ERROR_TYPE));    return(0);}/*----------------------------------------------------------------------------+|  xp0_queue_get_size+----------------------------------------------------------------------------*/SHORT xp_osi_queue_get_size(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId, ULONG *pQueueSize){    short rc;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];//    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        *pQueueSize = pChannel->ulQueueSize;    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_lock_data+-----------------------------------------------------------------------------+||  DESCRIPTION:  add a skip or lock record to the channel data||  PROTOTYPE  :  static short xp0_queue_lock_data(|                short wChannel_Id,|                XP_QUEUE_MODE_TYPE mode,|                unsigned char *b_addr,|                unsigned char *e_addr)||  ARGUMENTS  :  wChannel_Id    -  the channel id as returned from the|                                 xp0_channel_allocate().|                mode          -  LOCK the record or SKIP the record|                b_addr        -  starting address of the region|                e_addr        -  ending address+1 of the region||  RETURNS    :||  COMMENTS   :  This function processes requests to lock or skip records|                The SKIP records only update the address of the last|                data address processed.  LOCK records are added in sorted|                order to the lock list. mine whether the end of the|                this region is the same as the start of the region to|                reserve and the mode is equivalent.|+----------------------------------------------------------------------------*/SHORT xp_osi_queue_lock_data(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId,                        /* channel to lock region in        */XP_QUEUE_MODE_TYPE Mode,                 /* LOCK or SKIP                     */UCHAR *ppBAddr,                   /* start of region to lock          */UCHAR *ppEAddr)                   /* end of region to lock            */{    short rc=0;    SHORT wIndex;                         /* location to add new node         */    short i, j;    SHORT wLockAlloc;    QUEUE_LOCK_TYPE *pLockData;    QUEUE_PTR pChannel;//    xp_os_semaphore_wait();    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];    /*------------------------------------------------------------------------+    |  Save the address of the most recent data processed. This gets used    |  when the last 'lock' record is unlocked and determines where the    |  hardware read pointer is moved.    +------------------------------------------------------------------------*/    pChannel->ppProcessAddr = ppEAddr;    /*------------------------------------------------------------------------+    |  If we've used all the available records allocate more space    +------------------------------------------------------------------------*/    if(Mode == XP_QUEUE_MODE_LOCK)    {        if(pChannel->wLockInuse >= pChannel->wLockAlloc)        {            if (pChannel->wLockAlloc == 0)            {                wLockAlloc = 128 / sizeof (QUEUE_LOCK_TYPE);                pLockData = MALLOC (wLockAlloc * sizeof (QUEUE_LOCK_TYPE));                if(pLockData == NULL)                {                    pChannel->Errors.uwInternal++;                    rc = XP_ERROR_INTERNAL;                }                else                {                    pChannel->pLockData  = pLockData;                    pChannel->wLockAlloc = wLockAlloc;                }            }            else            {                   /* we can not realloc it */                pChannel->Errors.uwInternal++;                rc = XP_ERROR_INTERNAL;            }        }        if(rc == 0)        {            if(pChannel->wLockInuse == 0)            {                pChannel->ppLockAddr = ppBAddr;                wIndex = 0;            }            /*----------------------------------------------------------------+            |  Find the location to insert a new node.  Since the list is            |  in sorted order, the node which wraps is always the last one            |  in the list            +----------------------------------------------------------------*/            else            {                for(wIndex=0; wIndex<pChannel->wLockInuse; wIndex++)                {                    if(ppBAddr < pChannel->pLockData[wIndex].ppBAddr)                    {                        break;                    }                }                if(wIndex < pChannel->wLockInuse)                {    /* 05/16/98 */                    /*--------------------------------------------------------+                    |  Shift all the records down to make room for the node                    |  to insert at index location 'i'.                    +--------------------------------------------------------*/                    for(i=pChannel->wLockInuse, j=i-1; i>wIndex; i--, j--)                    {                        pChannel->pLockData[i] = pChannel->pLockData[j];                    }                }            }            pChannel->pLockData[wIndex].ppBAddr = ppBAddr;            pChannel->pLockData[wIndex].ppEAddr = ppEAddr;            pChannel->wLockInuse++;        }    }    /*------------------------------------------------------------------------+    |  If there are no locked records, then move the read pointer to the    |  end of the skip    +------------------------------------------------------------------------*/    else if(pChannel->wLockInuse == 0)    {        update_read_pointer(pGlobal,wChannelId, ppEAddr);    }//    xp_os_semaphore_signal();    return(rc);}/*----------------------------------------------------------------------------+|  xp0_queue_reset_errors+----------------------------------------------------------------------------*/SHORT xp_osi_queue_reset_errors(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId){    short rc;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc)    {        return(rc);    }    memset(&pChannel->Errors, 0,  sizeof(XP_QUEUE_ERROR_TYPE));    return(0);}/*----------------------------------------------------------------------------+|  xp0_queue_unlock+----------------------------------------------------------------------------*/SHORT xp_osi_queue_unlock(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                          SHORT wBIndex, SHORT wEIndex){    short rc;    short i;    ULONG ulBytes;    QUEUE_PTR pChannel;    pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];    for(i=wEIndex; i>=wBIndex; i--)    {        if(pChannel->pLockData[i].ppBAddr <= pChannel->pLockData[i].ppEAddr)        {            ulBytes = pChannel->pLockData[i].ppEAddr -                    pChannel->pLockData[i].ppBAddr;        }        else        {            ulBytes = pChannel->ulQueueSize -                    (pChannel->pLockData[i].ppBAddr -                    pChannel->pLockData[i].ppEAddr);        }        if ((rc = xp_osi_queue_unlock_data(pGlobal,wChannelId,                  pChannel->pLockData[i].ppBAddr, ulBytes)) != 0)        {           return(rc);        }    }    return(0);}/*----------------------------------------------------------------------------+|  xp0_queue_unlock_data+-----------------------------------------------------------------------------+||   DESCRIPTION:  define a queue for data unloaded on this channel||   PROTOTYPE  :  short xp0_queue_unlock_data(|                 short wChannel_Id,|                 unsigned char *buffer,|                 unsigned long length)||   ARGUMENTS  :  wChannel_Id    -  the channel id as returned from the|                                  xp0_channel_allocate().|                 buffer        -  address of data being unlocked|                 length        -  number of bytes to unlock||   RETURNS    :  0 if successful, nonzero otherwise.||   COMMENTS   :  This function notifies the driver when the application|                 has finished using the space (buffer [ 0..length-1].|                 The buffer address always observes the data bounaries|                 provided during the notification phase.  Locked sections|                 may be unlocked in any order.|                     NOTE:  locked regions are not released when a queue|                 is disabled but are released upon a queue reset.  A queue|                 may be disabled, and re-enabled without disturbing any|                 locked sections.|+----------------------------------------------------------------------------*/SHORT xp_osi_queue_unlock_data(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId,                               UCHAR *ppBAddr, ULONG ulLength){    short rc;    UCHAR *ppEAddr;    ULONG ulAddr;    ULONG ulBQueue=0;    ULONG ulEQueue=0;    QUEUE_PTR pChannel=NULL;          /* pointer to channel record            *///    xp_os_semaphore_wait();    rc = xp_osi_channel_valid(pGlobal,wChannelId);    if(rc == 0)    {        pChannel = &pGlobal->QueueInfo.XpQueueChData[wChannelId];        /*--------------------------------------------------------------------+        |  Check if queue is currently active        +--------------------------------------------------------------------*/        switch(pChannel->State)        {            case XP_QUEUE_STATUS_ENABLED:            case XP_QUEUE_STATUS_DISABLED:            case XP_QUEUE_STATUS_RPI:                break;            case XP_QUEUE_STATUS_UNDEFINED:                rc = XP_ERROR_QUEUE_UNDEFINED;                break;            default:                rc = XP_ERROR_INTERNAL;                break;        }    }    /*------------------------------------------------------------------------+    |  if we don't have any locked record, then we cannot unlock any records    +------------------------------------------------------------------------*/    if(rc == 0)    {        if(pChannel->wLockInuse == 0)        {            rc = XP_ERROR_QUEUE_ADDRESS;        }        else if(ulLength == 0)        {            rc = XP_ERROR_QUEUE_REGION_SIZE;        }    }    /*------------------------------------------------------------------------+    |  Determine the start and end address of the space being freed    +------------------------------------------------------------------------*/    if(rc == 0)    {        ulAddr    = (ULONG)ppBAddr;         //lingh        ulBQueue = pChannel->ulQueueAddr;        ulEQueue = ulBQueue + pChannel->ulQueueSize;    if(ulAddr < ulBQueue)        {            pChannel->Errors.uwQueueAddress++;            rc = XP_ERROR_QUEUE_ADDRESS;        }    }    if(rc == 0)    {        if(ulLength > pChannel->ulQueueSize)        {            pChannel->Errors.uwQueueAddress++;            rc = XP_ERROR_QUEUE_ADDRESS;        }    }    /*------------------------------------------------------------------------+    |  Adjust address to end of space to unlock.  Watch for the queue wrap.    +------------------------------------------------------------------------*/    if(rc == 0)    {        ulAddr += ulLength;        if(ulAddr >= ulEQueue)        {            ulAddr = (unsigned long) ulBQueue + (ulAddr - ulEQueue);        }        ppEAddr = MAKE_PLB_ADDR(ulAddr);        rc = unlock_data(pGlobal,wChannelId, ppBAddr, ppEAddr);    }//    xp_os_semaphore_signal();    return(rc);}

⌨️ 快捷键说明

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