/**
 * @file    IxQMgrQAccess.c
 *
 * @author Intel Corporation
 * @date    30-Oct-2001
 *
 * @brief   This file contains functions for putting entries on a queue and
 * removing entries from a queue.
 *
 * 
 * @par
 * IXP400 SW Release version 2.0
 * 
 * -- Copyright Notice --
 * 
 * @par
 * Copyright 2001-2005, Intel Corporation.
 * All rights reserved.
 * 
 * @par
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 * 
 * @par
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * @par
 * -- End of Copyright Notice --
*/

/*
 * Inlines are compiled as function when this is defined.
 * N.B. Must be placed before #include of "IxQMgr.h"
 */
#ifndef IXQMGR_H
#    define IXQMGRQACCESS_C
#else
#    error
#endif

/*
 * System defined include files.
 */

/*
 * User defined include files.
 */
#include "IxQMgr.h"
#include "IxQMgrAqmIf_p.h"
#include "IxQMgrQAccess_p.h"
#include "IxQMgrQCfg_p.h"
#include "IxQMgrDefines_p.h"

/*
 * Global variables and extern definitions
 */
extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];

/*
 * Function definitions.
 */
void
ixQMgrQAccessInit (void)
{   
}

IX_STATUS
ixQMgrQReadWithChecks (IxQMgrQId qId,
                       UINT32 *entry)
{
    IxQMgrQEntrySizeInWords entrySizeInWords;
    IxQMgrQInlinedReadWriteInfo *infoPtr;

    if (NULL == entry)
    {
	return IX_QMGR_PARAMETER_ERROR;
    }

    /* Check QId */
    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }

    /* Get the q entry size in words */
    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);

    ixQMgrAqmIfQPop (qId, entrySizeInWords, entry);	    

    /* reset the current read count if the counter wrapped around 
    * (unsigned arithmetic)
    */
    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    if (infoPtr->qReadCount-- > infoPtr->qSizeInEntries)
    {
	infoPtr->qReadCount = 0;
    }

    /* Check if underflow occurred on the read */
    if (ixQMgrAqmIfUnderflowCheck (qId))
    {
	return IX_QMGR_Q_UNDERFLOW;
    }
    
    return IX_SUCCESS;
}

/* this function reads the remaining of the q entry
 * for queues configured with many words.
 * (the first word of the entry is already read 
 * in the inlined function and the entry pointer already
 * incremented
 */
IX_STATUS
ixQMgrQReadMWordsMinus1 (IxQMgrQId qId,
			 UINT32 *entry)
{
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    UINT32 entrySize = infoPtr->qEntrySizeInWords;
    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
    
    while (--entrySize)
    {
	/* read the entry and accumulate the result */
	*(++entry) = IX_OSAL_READ_LONG(++qAccRegAddr);
    }
    /* underflow is available for lower queues only */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
	/* get the queue status */
	UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
	
	/* check the underflow status */
	if (status & infoPtr->qUflowStatBitMask)
	{
	    /* the queue is empty 
	     *  clear the underflow status bit if it was set 
	     */
	    IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
				 status & ~infoPtr->qUflowStatBitMask);
	    return IX_QMGR_Q_UNDERFLOW;
	}
    }
    return IX_SUCCESS;
}

IX_STATUS
ixQMgrQWriteWithChecks (IxQMgrQId qId,
                        UINT32 *entry)
{
    IxQMgrQEntrySizeInWords entrySizeInWords;
    IxQMgrQInlinedReadWriteInfo *infoPtr;

    if (NULL == entry)
    {
	return IX_QMGR_PARAMETER_ERROR;
    }

    /* Check QId */
    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }

    /* Get the q entry size in words */
    entrySizeInWords = ixQMgrQEntrySizeInWordsGet (qId);
    
    ixQMgrAqmIfQPush (qId, entrySizeInWords, entry);

    /* reset the current read count if the counter wrapped around 
    * (unsigned arithmetic)
    */
    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    if (infoPtr->qWriteCount++ >= infoPtr->qSizeInEntries)
    {
	infoPtr->qWriteCount = infoPtr->qSizeInEntries;
    }

    /* Check if overflow occurred on the write*/
    if (ixQMgrAqmIfOverflowCheck (qId))
    {
	return IX_QMGR_Q_OVERFLOW;
    }
         
    return IX_SUCCESS;
}

IX_STATUS
ixQMgrQPeek (IxQMgrQId qId,
	     unsigned int entryIndex,
	     UINT32 *entry)
{
    unsigned int numEntries;

#ifndef NDEBUG
    if ((NULL == entry) || (entryIndex >= IX_QMGR_Q_SIZE_INVALID))
    {
	return IX_QMGR_PARAMETER_ERROR;
    }

    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }
#endif
    
    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
    {
	return IX_FAIL;
    }

    if (entryIndex >= numEntries) /* entryIndex starts at 0 */
    {
	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
    }

    return ixQMgrAqmIfQPeek (qId, entryIndex, entry);
}

IX_STATUS
ixQMgrQPoke (IxQMgrQId qId,
	     unsigned entryIndex,
	     UINT32 *entry)
{
    unsigned int numEntries;

#ifndef NDEBUG
    if ((NULL == entry) || (entryIndex > 128))
    {
	return IX_QMGR_PARAMETER_ERROR;
    }

    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }
#endif
        
    if (IX_SUCCESS != ixQMgrQNumEntriesGet (qId, &numEntries))
    {
	return IX_FAIL;
    }

    if (numEntries < (entryIndex + 1)) /* entryIndex starts at 0 */
    {
	return IX_QMGR_ENTRY_INDEX_OUT_OF_BOUNDS;
    }

    return ixQMgrAqmIfQPoke (qId, entryIndex, entry);
}

IX_STATUS
ixQMgrQStatusGetWithChecks (IxQMgrQId qId,
                            IxQMgrQStatus *qStatus)
{
    if (NULL == qStatus)
    {
	return IX_QMGR_PARAMETER_ERROR;
    }
   
    if (!ixQMgrQIsConfigured (qId)) 
    {
        return IX_QMGR_Q_NOT_CONFIGURED;
    }

    ixQMgrAqmIfQueStatRead (qId, qStatus);

    return IX_SUCCESS;
}

IX_STATUS
ixQMgrQNumEntriesGet (IxQMgrQId qId,
		      unsigned *numEntriesPtr)
{
    UINT32 qPtrs;
    UINT32 qStatus;
    unsigned numEntries;
    IxQMgrQInlinedReadWriteInfo *infoPtr;


#ifndef NDEBUG
    if (NULL == numEntriesPtr)
    {
	return IX_QMGR_PARAMETER_ERROR;
    }

    /* Check QId */
    if (!ixQMgrQIsConfigured(qId))
    {
	return IX_QMGR_Q_NOT_CONFIGURED;
    }
#endif

    /* get fast access data */
    infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];

    /* get snapshot */
    qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);

    /* Mod subtraction of pointers to get number of words in Q. */
    numEntries = (qPtrs - (qPtrs >> 7)) & 0x7f;
  
    if (numEntries == 0)
    {
	/* 
	 * Could mean either full or empty queue
	 * so look at status
	 */
	ixQMgrAqmIfQueStatRead (qId, &qStatus);

	if (qId < IX_QMGR_MIN_QUEUPP_QID)
	{
	    if (qStatus & IX_QMGR_Q_STATUS_E_BIT_MASK)
	    {
		/* Empty */
		*numEntriesPtr = 0;
	    }
	    else if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
	    {
		/* Full */
		*numEntriesPtr = infoPtr->qSizeInEntries;
	    }
	    else
	    {	    
		/* 
		 * Queue status and read/write pointers are volatile.
		 * The queue state has changed since we took the
		 * snapshot of the read and write pointers.
		 * Client can retry if they wish
		 */
		*numEntriesPtr = 0;
		return IX_QMGR_WARNING;
	    }
	}
	else /* It is an upper queue which does not have an empty status bit maintained */
	{
	    if (qStatus & IX_QMGR_Q_STATUS_F_BIT_MASK)
	    {
		/* The queue is Full at the time of snapshot. */
		*numEntriesPtr = infoPtr->qSizeInEntries;
	    }
	    else
	    {
	       /* The queue is either empty, either moving,
	        * Client can retry if they wish
	        */
		*numEntriesPtr = 0;
	        return IX_QMGR_WARNING;
	    }
	}
    }
    else
    {
	*numEntriesPtr = (numEntries / infoPtr->qEntrySizeInWords) & (infoPtr->qSizeInEntries - 1);
    }
    
    return IX_SUCCESS;
}

#if defined(__wince) && defined(NO_INLINE_APIS)

PUBLIC IX_STATUS
ixQMgrQRead (IxQMgrQId qId,
      UINT32 *entryPtr)
{
    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    UINT32 entry, entrySize;

    /* get a new entry */
    entrySize = infoPtr->qEntrySizeInWords;
    entry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);

    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
    { 
    *entryPtr = entry;
  /* process the remaining part of the entry */
   return ixQMgrQReadMWordsMinus1(qId, entryPtr);
    }

    /* underflow is available for lower queues only */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
 /* the counter of queue entries is decremented. In happy 
    * day scenario there are many entries in the queue
  * and the counter does not reach zero.
  */
     if (infoPtr->qReadCount-- == 0)
 {
       /* There is maybe no entry in the queue
      * qReadCount is now negative, but will be corrected before
      * the function returns.
         */
     UINT32 qPtrs; /* queue internal pointers */

     /* when a queue is empty, the hw guarantees to return 
       * a null value. If the value is not null, the queue is
      * not empty.
        */
     if (entry == 0)
     {
       /* get the queue status */
      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);
   
        /* check the underflow status */
        if (status & infoPtr->qUflowStatBitMask)
        {
           /* the queue is empty 
          *  clear the underflow status bit if it was set 
            */
          IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
                    status & ~infoPtr->qUflowStatBitMask);
         *entryPtr = 0;
          infoPtr->qReadCount = 0;
            return IX_QMGR_Q_UNDERFLOW;
     }
       }
       /* store the result */
      *entryPtr = entry;

      /* No underflow occured : someone is filling the queue
       * or the queue contains null entries.
       * The current counter needs to be
       * updated from the current number of entries in the queue
       */

     /* get snapshot of queue pointers */
        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);

       /* Mod subtraction of pointers to get number of words in Q. */
      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 
  
       if (qPtrs == 0)
     {
       /* no entry in the queue */
     infoPtr->qReadCount = 0;
        }
       else
        {
       /* convert the number of words inside the queue
      * to a number of entries 
       */
     infoPtr->qReadCount = qPtrs & (infoPtr->qSizeInEntries - 1);
        }
       return IX_SUCCESS;
  }
    }
    *entryPtr = entry;
    return IX_SUCCESS;
}

PUBLIC IX_STATUS
ixQMgrQBurstRead (IxQMgrQId qId,
          UINT32 numEntries,
          UINT32 *entries)
{
    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    UINT32 nullCheckEntry;

    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
    {
    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;

    /* the code is optimized to take care of data dependencies:
  * Durig a read, there are a few cycles needed to get the 
   * read complete. During these cycles, it is poossible to
    * do some CPU, e.g. increment pointers and decrement 
   * counters.
     */

 /* fetch a queue entry */
   nullCheckEntry = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr);

 /* iterate the specified number of queue entries */ 
    while (--numEntries)
    {
       /* check the result of the previous read */
     if (nullCheckEntry == 0)
        {
       /* if we read a NULL entry, stop. We have underflowed */
        break;
      }
       else
        {
       /* write the entry */
       *entries = nullCheckEntry;
      /* fetch next entry */
      nullCheckEntry = IX_OSAL_READ_LONG(qAccRegAddr);
      /* increment the write address */
       entries++;
      }
   }
   /* write the pre-fetched entry */
   *entries = nullCheckEntry;
    }
    else
    {
    IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
  /* read the specified number of queue entries */
    nullCheckEntry = 0;
 while (numEntries--)
    {
       int i;

      for (i = 0; i < entrySizeInWords; i++)
      {
       *entries = IX_OSAL_READ_LONG(infoPtr->qAccRegAddr + i);
       nullCheckEntry |= *entries++;
       }

       /* if we read a NULL entry, stop. We have underflowed */
        if (nullCheckEntry == 0)
        {
       break;
      }
       nullCheckEntry = 0;
 }
    }

    /* reset the current read count : next access to the read function 
     * will force a underflow status check 
     */
    infoPtr->qWriteCount = 0;

    /* Check if underflow occurred on the read */
    if (nullCheckEntry == 0 && qId < IX_QMGR_MIN_QUEUPP_QID)
    {
  /* get the queue status */
  UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);

   if (status & infoPtr->qUflowStatBitMask)
    {
       /* clear the underflow status bit if it was set */
      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
                status & ~infoPtr->qUflowStatBitMask);
     return IX_QMGR_Q_UNDERFLOW;
 }
    }

    return IX_SUCCESS;
}

PUBLIC IX_STATUS
ixQMgrQWrite (IxQMgrQId qId,
         UINT32 *entry)
{
    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    UINT32 entrySize;

    /* write the entry */
    IX_OSAL_WRITE_LONG(infoPtr->qAccRegAddr, *entry);
    entrySize = infoPtr->qEntrySizeInWords;

    if (entrySize != IX_QMGR_Q_ENTRY_SIZE1)
    {   
    /* process the remaining part of the entry */
   volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
    while (--entrySize)
 {
       ++entry;
        IX_OSAL_WRITE_LONG(++qAccRegAddr, *entry);
    }
   entrySize = infoPtr->qEntrySizeInWords;
    }

    /* overflow is available for lower queues only */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {   
  UINT32 qSize = infoPtr->qSizeInEntries;
 /* increment the current number of entries in the queue
  * and check for overflow 
   */
 if (infoPtr->qWriteCount++ == qSize)
    {
       /* the queue may have overflow */
       UINT32 qPtrs; /* queue internal pointers */
  
       /* get the queue status */
      UINT32 status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);

       /* read the status twice because the status may 
         * not be immediately ready after the write operation
        */
     if ((status & infoPtr->qOflowStatBitMask) ||
        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
         & infoPtr->qOflowStatBitMask))
     {
       /* the queue is full, clear the overflow status
      *  bit if it was set 
       */
     IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
                    status & ~infoPtr->qOflowStatBitMask);
     infoPtr->qWriteCount = infoPtr->qSizeInEntries;
     return IX_QMGR_Q_OVERFLOW;
      }
       /* No overflow occured : someone is draining the queue
       * and the current counter needs to be
       * updated from the current number of entries in the queue
       */

     /* get q pointer snapshot */
        qPtrs = IX_OSAL_READ_LONG(infoPtr->qConfigRegAddr);

       /* Mod subtraction of pointers to get number of words in Q. */
      qPtrs = (qPtrs - (qPtrs >> 7)) & 0x7f; 

     if (qPtrs == 0)
     {
       /* the queue may be full at the time of the 
         * snapshot. Next access will check 
         * the overflow status again.
        */
     infoPtr->qWriteCount = qSize;
       }
       else 
       {
       /* convert the number of words to a number of entries */
        if (entrySize == IX_QMGR_Q_ENTRY_SIZE1)
     {
           infoPtr->qWriteCount = qPtrs & (qSize - 1);
     }
       else
        {
           infoPtr->qWriteCount = (qPtrs / entrySize) & (qSize - 1);
       }
       }
   }
    }
    return IX_SUCCESS;
}

PUBLIC IX_STATUS
ixQMgrQBurstWrite (IxQMgrQId qId,
          unsigned numEntries,
        UINT32 *entries)
{
    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
    UINT32 status;

    /* update the current write count */
    infoPtr->qWriteCount += numEntries;

    if (infoPtr->qEntrySizeInWords == IX_QMGR_Q_ENTRY_SIZE1)
    {
    volatile UINT32 *qAccRegAddr = infoPtr->qAccRegAddr;
    while (numEntries--)
    {
       IX_OSAL_WRITE_LONG(qAccRegAddr, *entries);
        entries++;
  }
    }
    else
    {
 IxQMgrQEntrySizeInWords entrySizeInWords = infoPtr->qEntrySizeInWords;
  int i;

  /* write each queue entry */
    while (numEntries--)
    {
       /* write the queueEntrySize number of words for each entry */
       for (i = 0; i < entrySizeInWords; i++)
      {
       IX_OSAL_WRITE_LONG((infoPtr->qAccRegAddr + i), *entries);
     entries++;
      }
   }
    }

    /* check if the write count overflows */
    if (infoPtr->qWriteCount > infoPtr->qSizeInEntries)
    {
  /* reset the current write count */
 infoPtr->qWriteCount = infoPtr->qSizeInEntries;
    }

    /* Check if overflow occurred on the write operation */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
   /* get the queue status */
  status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr);

  /* read the status twice because the status may 
     * not be ready at the time of the write
     */
 if ((status & infoPtr->qOflowStatBitMask) ||
        ((status = IX_OSAL_READ_LONG(infoPtr->qUOStatRegAddr))
         & infoPtr->qOflowStatBitMask))
 {
       /* clear the underflow status bit if it was set */
      IX_OSAL_WRITE_LONG(infoPtr->qUOStatRegAddr,
                status & ~infoPtr->qOflowStatBitMask);
     return IX_QMGR_Q_OVERFLOW;
  }
    }

    return IX_SUCCESS;
}

PUBLIC IX_STATUS
ixQMgrQStatusGet (IxQMgrQId qId,
          IxQMgrQStatus *qStatus)
{
    /* read the status of a queue in the range 0-31 */
    if (qId < IX_QMGR_MIN_QUEUPP_QID)
    {
  extern UINT32 ixQMgrAqmIfQueLowStatRegAddr[];
   extern UINT32 ixQMgrAqmIfQueLowStatBitsOffset[];
    extern UINT32 ixQMgrAqmIfQueLowStatBitsMask;
    extern IxQMgrQInlinedReadWriteInfo ixQMgrQInlinedReadWriteInfo[];
    IxQMgrQInlinedReadWriteInfo *infoPtr = &ixQMgrQInlinedReadWriteInfo[qId];
   volatile UINT32 *lowStatRegAddr = (UINT32*)ixQMgrAqmIfQueLowStatRegAddr[qId];
   volatile UINT32 *qUOStatRegAddr = infoPtr->qUOStatRegAddr;

  UINT32 lowStatBitsOffset = ixQMgrAqmIfQueLowStatBitsOffset[qId];
    UINT32 lowStatBitsMask   = ixQMgrAqmIfQueLowStatBitsMask;
   UINT32 underflowBitMask  = infoPtr->qUflowStatBitMask;
  UINT32 overflowBitMask   = infoPtr->qOflowStatBitMask;

  /* read the status register for this queue */
   *qStatus = IX_OSAL_READ_LONG(lowStatRegAddr);
 /* mask out the status bits relevant only to this queue */
  *qStatus = (*qStatus >> lowStatBitsOffset) & lowStatBitsMask;

   /* Check if the queue has overflowed */
 if (IX_OSAL_READ_LONG(qUOStatRegAddr) & overflowBitMask)
  {
       /* clear the overflow status bit if it was set */
       IX_OSAL_WRITE_LONG(qUOStatRegAddr,
                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
               ~overflowBitMask));
       *qStatus |= IX_QMGR_Q_STATUS_OF_BIT_MASK;
   }

   /* Check if the queue has underflowed */
        if (IX_OSAL_READ_LONG(qUOStatRegAddr) & underflowBitMask)
 {
       /* clear the underflow status bit if it was set */
      IX_OSAL_WRITE_LONG(qUOStatRegAddr,
                 (IX_OSAL_READ_LONG(qUOStatRegAddr) &
               ~underflowBitMask));
      *qStatus |= IX_QMGR_Q_STATUS_UF_BIT_MASK;
   }
    }
    else /* read status of a queue in the range 32-63 */
    {
 extern UINT32 ixQMgrAqmIfQueUppStat0RegAddr;
    extern UINT32 ixQMgrAqmIfQueUppStat1RegAddr;
    extern UINT32 ixQMgrAqmIfQueUppStat0BitMask[];
  extern UINT32 ixQMgrAqmIfQueUppStat1BitMask[];

  volatile UINT32 *qNearEmptyStatRegAddr = (UINT32*)ixQMgrAqmIfQueUppStat0RegAddr;
    volatile UINT32 *qFullStatRegAddr      = (UINT32*)ixQMgrAqmIfQueUppStat1RegAddr;
    int maskIndex = qId - IX_QMGR_MIN_QUEUPP_QID;
   UINT32 qNearEmptyStatBitMask = ixQMgrAqmIfQueUppStat0BitMask[maskIndex];
    UINT32 qFullStatBitMask      = ixQMgrAqmIfQueUppStat1BitMask[maskIndex];

    /* Reset the status bits */
 *qStatus = 0;

   /* Check if the queue is nearly empty */
    if (IX_OSAL_READ_LONG(qNearEmptyStatRegAddr) & qNearEmptyStatBitMask)
 {
       *qStatus |= IX_QMGR_Q_STATUS_NE_BIT_MASK;
   }

   /* Check if the queue is full */
    if (IX_OSAL_READ_LONG(qFullStatRegAddr) & qFullStatBitMask)
   {
       *qStatus |= IX_QMGR_Q_STATUS_F_BIT_MASK;
    }
    }
    return IX_SUCCESS;
}
#endif /* def NO_INLINE_APIS */
