Logo Search packages:      
Sourcecode: dahdi-linux version File versions  Download package

octapi_llman.c

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\

File:  octapi_llman.c

    Copyright (c) 2001-2007 Octasic Inc.
    
Description: 

      Library used to manage allocation tables and linked lists.  The library is
      made such that only a block of contiguous memory is needed for the
      management of the linked list/allocation table.

This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API  is 
free software; you can redistribute it and/or modify it under the terms of 
the GNU General Public License as published by the Free Software Foundation; 
either version 2 of the License, or (at your option) any later version.

The OCT6100 GPL API is distributed in the hope that it will be useful, but 
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
for more details. 

You should have received a copy of the GNU General Public License 
along with the OCT6100 GPL API; if not, write to the Free Software 
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.

$Octasic_Release: OCT612xAPI-01.00-PR49 $

$Octasic_Revision: 22 $

\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#include "octapi_llman_private.h"
#include "apilib/octapi_llman.h"
#include "apilib/octapi_largmath.h"


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctapiLlmAllocGetSize.
|
|     Description:      This function determines the amount of memory needed to
|                             manage the allocation of a fixed amount of resources.
|                             The memory is measured in bytes.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     number_of_items         UINT32                  The number of resources to be allocated.
|     *l_size     UINT32            UINT32                  The amount of memory needed, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctapiLlmAllocGetSize
UINT32 OctapiLlmAllocGetSize(UINT32 number_of_items,UINT32 * l_size)
{
      if (number_of_items == 0) return(GENERIC_BAD_PARAM);

      *l_size = (sizeof(LLM_ALLOC)) + (number_of_items * sizeof(UINT32));

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctapiLlmAllocInit.
|
|     Description:      This function intializes the LLM_ALLOC structure.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     **l                           void              The memory used by the LLM_ALLOC structure.
|     number_of_items         UINT32                  The number of resources to be allocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctapiLlmAllocInit
UINT32 OctapiLlmAllocInit(void ** l,UINT32 number_of_items)
{
      LLM_ALLOC* ls;
      UINT32 i;

      /* Check the number of items required.*/
      if (number_of_items == 0) return(GENERIC_BAD_PARAM);

      /* If no memory has been allocated yet:*/
      if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Build the structure before starting.*/
      ls = (LLM_ALLOC *)(*l);
      ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC));

      ls->number_of_items = number_of_items;

      /* Linked list links all structures in ascending order.*/
      for(i=0;i<number_of_items;i++)
      {
            ls->linked_list[i] = i+1;
      }

      ls->linked_list[number_of_items - 1] = 0xFFFFFFFF; /* Invalid link.*/

      /* Next avail is 0.*/
      ls->next_avail_num = 0;

      /* Number of allocated items is null.*/
      ls->allocated_items = 0;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctapiLlmAllocInfo.
|
|     Description:      This function returns the number of free and allocated
|                             block in the LLMAN list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     *allocated_items  UINT32                  Number of allocated items.
|     *available_items  UINT32                  Number of available items.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctapiLlmAllocInfo
UINT32 OctapiLlmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items)
{
      LLM_ALLOC* ls;

      /* Build the structure before starting.*/
      ls = (LLM_ALLOC *)l;
      ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC));

      *allocated_items = ls->allocated_items;
      *available_items = ls->number_of_items - ls->allocated_items;
      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctapiLlmAllocInfo.
|
|     Description:      This function allocates the resource indicated by blocknum.
|                             If the resource can be allocated then GENERIC_OK is returned.  
|                             Else an error.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     *block_num              UINT32                  The resource to be allocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctapiLlmAllocAlloc
UINT32 OctapiLlmAllocAlloc(void * l,UINT32 * blocknum)
{
      LLM_ALLOC* ls;
      UINT32 allocated_block;
      UINT32* node;

      /* Build the structure before starting.*/
      ls = (LLM_ALLOC *)l;
      ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC));

      /* Get next available block number.*/
      allocated_block = ls->next_avail_num;

      /* Check if block is invalid.*/
      if (allocated_block == 0xFFFFFFFF)
      {
            /* Make blocknum NULL.*/
            *blocknum = 0xFFFFFFFF;

            return(OCTAPI_LLM_NO_STRUCTURES_LEFT);
      }

      node = &ls->linked_list[allocated_block];

      /* Copy next block number.*/
      ls->next_avail_num = *node;

      /* Tag as used the current block number.*/
      *node = 0xFFFFFFFE;

      /* Return proper block number.*/
      *blocknum = allocated_block;

      /* Update block usage number.*/
      ls->allocated_items++;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctapiLlmAllocDealloc.
|
|     Description:      This function deallocates the resource indicated by blocknum.
|                             If the resource is not already allocated an error is returned.
|                             Else GENERIC_OK is returned.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     block_num               UINT32                  The resource to be deallocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctapiLlmAllocDealloc
UINT32 OctapiLlmAllocDealloc(void * l,UINT32 blocknum)
{
      LLM_ALLOC* ls;
      UINT32* node;

      /* Build the structure before starting.*/
      ls = (LLM_ALLOC *)l;
      ls->linked_list = (UINT32 *)((BYTE *)ls + sizeof(LLM_ALLOC));
      
      /* Check for null item pointer.*/
      if (blocknum == 0xFFFFFFFF) return(GENERIC_OK);

      /* Check if blocknum is within specified item range.*/
      if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);

      node = &ls->linked_list[blocknum];

      /* Check if block is really used as of now.*/
      if (*node != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Add link to list.*/
      *node = ls->next_avail_num;

      /* Point to returned block.*/
      ls->next_avail_num = blocknum;

      /* Update block usage number.*/
      ls->allocated_items--;

      return(GENERIC_OK);
}
#endif


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmAllocGetSize.
|
|     Description:      This function determines the amount of memory needed to
|                             manage the allocation of a fixed amount of resources.
|                             The memory is measured in bytes. 
|
|                             This version is a time manage version of llman.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     number_of_items         UINT32                  The number of resources to be allocated.
|     *l_size     UINT32            UINT32                  The amount of memory needed, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmAllocGetSize
UINT32 OctApiTllmAllocGetSize(UINT32 number_of_items,UINT32 * l_size)
{
      if (number_of_items == 0) return(GENERIC_BAD_PARAM);

      *l_size = (sizeof(TLLM_ALLOC)) + (number_of_items * sizeof(TLLM_ALLOC_NODE));

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmAllocInit.
|
|     Description:      This function intializes the TLLM_ALLOC structure.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     **l                           void              The memory used by the LLM_ALLOC structure.
|     number_of_items         UINT32                  The number of resources to be allocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmAllocInit
UINT32 OctApiTllmAllocInit(void ** l,UINT32 number_of_items)
{
      TLLM_ALLOC* ls;
      UINT32 i;

      /* Check the number of items required.*/
      if (number_of_items == 0) return(GENERIC_BAD_PARAM);

      /* If no memory has been allocated yet.*/
      if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Build the structure before starting.*/
      ls = (TLLM_ALLOC *)(*l);
      ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC));

      ls->number_of_items = number_of_items;

      /* Linked list links all structures in ascending order.*/
      for(i=0;i<number_of_items;i++)
      {
            ls->linked_list[i].value = i+1;
      }

      ls->linked_list[number_of_items - 1].value = 0xFFFFFFFF; /* Invalid link.*/

      /* Next avail is 0.*/
      ls->next_avail_num = 0;

      /* Number of allocated items is null.*/
      ls->allocated_items = 0;

      /* Set the number of timeout entry.*/
      ls->number_of_timeout = 0;

      /* Next timeout is 0.*/
      ls->next_timeout_num = 0xFFFFFFFF;
      ls->last_timeout_num = 0xFFFFFFFF;

      /* Set the known time to 0.*/
      ls->last_known_time[ 0 ] = 0;
      ls->last_known_time[ 1 ] = 0;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmAllocInfo.
|
|     Description:      This function returns the number of free and allocated
|                             block in the TLLMAN list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     *allocated_items  UINT32                  Number of allocated items.
|     *available_items  UINT32                  Number of available items.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmAllocInfo
UINT32 OctApiTllmAllocInfo(void * l,UINT32 * allocated_items,UINT32 * available_items)
{
      TLLM_ALLOC* ls;

      /* Build the structure before starting.*/
      ls = (TLLM_ALLOC *)l;
      *allocated_items = ls->allocated_items;
      *available_items = ls->number_of_items - ls->allocated_items;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmAllocAlloc.
|
|     Description:      This function allocates the resource indicated by blocknum.
|                             If the resource can be allocated then GENERIC_OK is returned.  
|                             Else an error.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     *block_num              UINT32                  The resource to be allocated.
|     *current_time           UINT32
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmAllocAlloc
UINT32 OctApiTllmAllocAlloc(void * l,UINT32 * blocknum, UINT32 *current_time)
{
      TLLM_ALLOC* ls;
      UINT32 allocated_block;
      TLLM_ALLOC_NODE* node;

      /* Build the structure before starting.*/
      ls = (TLLM_ALLOC *)l;
      ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC));
      
      if ( ls->allocated_items == ls->number_of_items  && 
             ls->next_timeout_num != 0xFFFFFFFF )
      {
            UINT32 l_ulResult;
            l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time );
            if ( l_ulResult != GENERIC_OK )
                  return l_ulResult;
      }
      
      /* Get next available block number.*/
      allocated_block = ls->next_avail_num;

      /* Check if block is invalid.*/
      if (allocated_block == 0xFFFFFFFF)
      {
            /* Make blocknum NULL.*/
            *blocknum = 0xFFFFFFFF;

            return(OCTAPI_LLM_NO_STRUCTURES_LEFT);
      }

      node = &ls->linked_list[allocated_block];

      /* Copy next block number.*/
      ls->next_avail_num = node->value;

      /* Tag as used the current block number.*/
      node->value = 0xFFFFFFFE;

      /* Return proper block number.*/
      *blocknum = allocated_block;

      /* Update block usage number.*/
      ls->allocated_items++;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmAllocDealloc.
|
|     Description:      This function deallocates the resource indicated by blocknum.
|                             If the resource is not already allocated an error is returned.
|                             Else GENERIC_OK is returned.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_ALLOC structure.
|     block_num               UINT32                  The resource to be deallocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmAllocDealloc
UINT32 OctApiTllmAllocDealloc(void * l,UINT32 blocknum, UINT32 timeout_value, UINT32 current_time[2])
{
      TLLM_ALLOC* ls;
      TLLM_ALLOC_NODE* node;
      UINT32      l_ulResult;

      /* Build the structure before starting.*/
      ls = (TLLM_ALLOC *)l;
      ls->linked_list = (TLLM_ALLOC_NODE *)((BYTE *)ls + sizeof(TLLM_ALLOC));
      
      /* Check for null item pointer.*/
      if (blocknum == 0xFFFFFFFF) return(GENERIC_OK);

      /* Check if blocknum is within specified item range.*/
      if (blocknum >= ls->number_of_items) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);

      if ( ls->next_timeout_num != 0xFFFFFFFF )
      {
            l_ulResult = OctApiTllmCheckTimeoutList( ls, current_time );
            if ( l_ulResult != GENERIC_OK )
                  return l_ulResult;
      }

      node = &ls->linked_list[blocknum];

      /* Check if block is really used as of now.*/
      if (node->value != 0xFFFFFFFE) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Add link to timeout list.*/
      if ( ls->last_timeout_num != 0xFFFFFFFF )
      {
            TLLM_ALLOC_NODE* last_node;

            /* insert the node at the end of the list.*/
            node->value = 0xFFFFFFFF;
            last_node = &ls->linked_list[ ls->last_timeout_num ];
            last_node->value = blocknum;
      }
      else
      {
            /* The node is alone in the list.*/
            node->value = 0xFFFFFFFF;
            ls->next_timeout_num = blocknum;
      }

      ls->last_timeout_num = blocknum;
      ls->number_of_timeout++;

      /* Set the timeout time of the node.*/
      l_ulResult = OctApiLmAdd( current_time, 1, &timeout_value, 0, node->timeout, 1 );
      if (l_ulResult != GENERIC_OK) 
            return(l_ulResult);

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiTllmCheckTimeoutList.
|
|     Description:      This function will verify if the timeout time 
|                             of all the node present in the timeout list are bigger
|                             then the current time.  If so the node will be returned
|                             ot the free node list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *ls                                 TLLM_ALLOC        The memory used by the TLLM_ALLOC structure.
|     current_time                  UINT32[2]         The current time in msec.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiTllmCheckTimeoutList
UINT32 OctApiTllmCheckTimeoutList(TLLM_ALLOC *ls, UINT32 current_time[2])
{
      UINT32      result;
      UINT32      fConditionFlag = TRUE;

      /* Free-up any pending memory before trying the allocation:*/
      if ((ls->last_known_time[0] != current_time[0] ||
            ls->last_known_time[1] != current_time[1]) && 
            (current_time[1] != 0 || current_time[0] != 0)) /* Time has changed.*/
      {
            TLLM_ALLOC_NODE *pcurrent_node;
            UINT32      current_num;
            USHORT      neg;

            /* Remember time for next time!*/
            ls->last_known_time[0] = current_time[0];
            ls->last_known_time[1] = current_time[1];

      
            while ( fConditionFlag == TRUE )
            {
                  /* Get a node from the timeout list.*/
                  pcurrent_node = &ls->linked_list[ ls->next_timeout_num ];
                  current_num = ls->next_timeout_num;
      
                  /* Check if first node has timeout.*/
                  result = OctApiLmCompare(current_time,1,pcurrent_node->timeout ,1,&neg);
                  if (result != GENERIC_OK) return(result);
                  
                  /* if the timeout tiem was exceeded, set the block as free.*/
                  if ( neg == FALSE )
                  {
                        /* set the next node pointer.*/
                        ls->next_timeout_num = pcurrent_node->value;
                        ls->number_of_timeout--;

                        /* reset the last pointer of the timeout list.*/
                        if ( ls->number_of_timeout == 0 )
                              ls->last_timeout_num = 0xFFFFFFFF;

                        /* return the node the free list.*/
                        pcurrent_node->value = ls->next_avail_num;
                        ls->next_avail_num = current_num;
                        ls->allocated_items--;
                  }
                  else  /* node not in timeout */
                  {
                        fConditionFlag = FALSE;
                        break;
                  }

                  if ( ls->next_timeout_num == 0xFFFFFFFF )
                  {
                        fConditionFlag = FALSE;
                        break;      /* end of timeout list.*/
                  }
            }
      }

      return(GENERIC_OK);
}
#endif
/**************************************** llm_alloc section **********************************************/







/**************************************** llm_list section **********************************************/
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListGetSize
|
|     Description:      This function determines the amount of memory needed by
|                             the LLM_LIST structure to manage the allocation of
|                             number_of_items number of resources.  The memory is
|                             measured in bytes.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     number_of_items         UINT32                  The number of resources to be allocated
|                                                           amongst all linked-lists.
|     number_of_lists         UINT32                  The maximum number of linked-lists that
|                                                           can be allocated.
|     *l_size     UINT32            UINT32                  The amount of memory needed, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListGetSize
UINT32 OctApiLlmListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size)
{
      UINT32 head_alloc_size;
      UINT32 result;
      UINT32 user_info_size_roundup;

      if (number_of_items == 0) return(GENERIC_BAD_PARAM);
      if (number_of_lists == 0) return(GENERIC_BAD_PARAM);
      if (user_info_size == 0) return(GENERIC_BAD_PARAM);

      user_info_size_roundup = ((user_info_size + 3) / 4) * 4;

      result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size);
      if(result != GENERIC_OK) return(result);

      *l_size = sizeof(LLM_LIST) + (number_of_lists * sizeof(LLM_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4));

      return(GENERIC_OK);
}
#endif

#if !SKIP_OctApiLlmListGetItemPointer
LLM_LIST_ITEM * OctApiLlmListGetItemPointer(LLM_LIST * ls, UINT32 item_number)
{
      return (LLM_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ;
}
#endif


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListInit.
|
|     Description:      This function intializes the LLM_TALLOC structure.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     number_of_items         UINT32                  The number of resources to be allocated
|                                                           amongst all linked-lists.
|     number_of_lists         UINT32                  The maximum number of linked-lists that
|                                                           can be allocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListInit
UINT32 OctApiLlmListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size)
{
      LLM_LIST* ls;
      LLM_LIST_ITEM* item;
      UINT32 i;
      UINT32 head_alloc_size;
      UINT32 result;
      UINT32 user_info_size_roundup;
      UINT32 total_lists;
      BYTE* lsbyte;


      if (number_of_items == 0) return(GENERIC_BAD_PARAM);
      if (number_of_lists == 0) return(GENERIC_BAD_PARAM);
      if (user_info_size == 0) return(GENERIC_BAD_PARAM);

      user_info_size_roundup = ((user_info_size + 3) / 4) * 4;

      /* Get the size of the Alloc structure used to manage head of list structures.*/
      result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size);
      if(result != GENERIC_OK) return(result);

      if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)(*l);
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      /* Initialize parameters in the structure.*/
      ls->head_alloc_size = head_alloc_size;
      ls->user_info_bytes = user_info_size;
      ls->user_info_size = user_info_size_roundup;
      ls->total_items = number_of_items;
      ls->assigned_items = 0;
      ls->total_lists = number_of_lists;
      ls->assigned_lists = 0;
      ls->next_empty_item = 0;
      ls->item_size = sizeof(LLM_LIST_ITEM) + user_info_size_roundup - 4;

      /* Complete the build!*/
      ls = (LLM_LIST *)(*l);
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      /* Initialize the head of queue Alloc structure.*/
      result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists);
      if(result != GENERIC_OK) return(result);

      /* Initialize the linked list of the items:*/
      for(i=0; i<number_of_items; i++)
      {
            item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * i);

            if (i == (number_of_items - 1))
                  item->forward_link = 0xFFFFFFFF;
            else
                  item->forward_link = i + 1;
      }

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListInfo.
|
|     Description:      This function returns the status of the LLM_LIST structure.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *allocated_lists  UINT32                  The number of linked_lists allocated.
|     *free_lists             UINT32                  The number of linked_lists still free.
|     *allocated_items  UINT32                  The number of items allocated to lists.
|     *free_items             UINT32                  The number of items still free.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListInfo
UINT32 OctApiLlmListInfo(void * l,UINT32 * allocated_lists,UINT32 * allocated_items,
                                                      UINT32 * free_lists,UINT32 * free_items)
{
      LLM_LIST* ls;
      BYTE* lsbyte;
      UINT32 total_lists;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      *allocated_items = ls->assigned_items;
      *free_items = ls->total_items - ls->assigned_items;

      *allocated_lists = ls->assigned_lists;
      *free_lists = ls->total_lists - ls->assigned_lists;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListCreate.
|
|     Description:      This function creates a linked list.  The target which is
|                             allocated the newly created list can request additions
|                             or removals from the list later on.  To target identifies
|                             its list with the returned list handle.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the new list, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListCreate
UINT32 OctApiLlmListCreate(void * l,UINT32 * list_handle)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      UINT32 blocknum;
      UINT32 total_lists;
      UINT32 result;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      /* Get a list using the list head alloc structure.*/
      result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum);
      if (result != GENERIC_OK) return(result);

      /* The handle is the block number.*/
      *list_handle = blocknum;

      /* Initialize the list head structure.*/
      lh = &ls->lh[blocknum];
      lh->list_length = 0;
      lh->head_pointer = 0xFFFFFFFF;
      lh->tail_pointer = 0xFFFFFFFF;
      lh->cache_item_number = 0xFFFFFFFF;
      lh->cache_item_pointer = 0xFFFFFFFF;

      ls->assigned_lists++;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListDelete.
|
|     Description:      This function deletes the linked list indicated by the
|                             handle list_handle.  Any items which are still allocated
|                             to the list are first deallocated.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListDelete
UINT32 OctApiLlmListDelete(void * l,UINT32 list_handle)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      UINT32 total_lists;
      UINT32 result;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      /* Release internal list header handle...*/
      result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle);
      if (result != GENERIC_OK) return(result);

      lh = &ls->lh[list_handle];

      /* Deallocate all items in the list!*/
      if (lh->list_length != 0)
      {
            LLM_LIST_ITEM * item;

            item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer);

            /* Release the items using only the links.*/
            item->forward_link = ls->next_empty_item;
            ls->next_empty_item = lh->head_pointer;

            /* Remove items from item counter.*/
            ls->assigned_items -= lh->list_length;
      }

      lh->list_length = 0xFFFFFFFF;
      lh->head_pointer = 0xFFFFFFFF;
      lh->tail_pointer = 0xFFFFFFFF;
      lh->cache_item_number = 0xFFFFFFFF;
      lh->cache_item_pointer = 0xFFFFFFFF;

      ls->assigned_lists--;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListLength.
|
|     Description:      This function returns the number of items allocated to the
|                             list indicated by the handle list_handle.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     *number_of_items  UINT32                  The number of items in the list, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListLength
UINT32 OctApiLlmListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      UINT32 total_lists;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      *number_of_items_in_list = lh->list_length;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListItemData
|
|     Description:      This function returns a pointer to the user data associated
|                             with an item.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     item_number             UINT32                  The number of the list node in question.
|     **item_data_pnt         void              The pointer to the user data, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListItemData
UINT32 OctApiLlmListItemData(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* item;
      UINT32      cur_list_pnt;
      UINT32      cur_list_num;
      UINT32      total_lists;
      UINT32      list_length;
      BYTE* lsbyte;
      UINT32      fConditionFlag = TRUE;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      list_length = lh->list_length;
      
      *item_data_pnt = NULL;
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      if (list_length <= item_number)     return(OCTAPI_LLM_ELEMENT_NOT_FOUND);

      /* Determine where the search will start.*/
      if (list_length == (item_number + 1))     /* Last item in list:*/
      {
            cur_list_pnt = lh->tail_pointer;
            cur_list_num = item_number;
      }
      else if (lh->cache_item_number <= item_number)  /* Start at cache:*/
      {
            cur_list_pnt = lh->cache_item_pointer;
            cur_list_num = lh->cache_item_number;
      }
      else  /* Start at beginning:*/
      {
            cur_list_pnt = lh->head_pointer;
            cur_list_num = 0;
      }

      /* Start search from cur_list_pnt and cur_list_num.*/
      while ( fConditionFlag == TRUE )
      {
            item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);

            if (cur_list_num == item_number) /* Item number found.*/
            {
                  /* Write new cache entry.*/
                  lh->cache_item_pointer = cur_list_pnt;
                  lh->cache_item_number = cur_list_num;

                  /* Get item info.*/
                  *item_data_pnt = (void *)item->user_info;

                  return(GENERIC_OK);
            }
            else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/
            {
                  return(OCTAPI_LLM_INTERNAL_ERROR0);
            }
            else /* Item was not found, but continue searching.*/
            {
                  cur_list_pnt = item->forward_link;
            }

            cur_list_num++;
      }

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListInsertItem.
|
|     Description:      This function allocates a node to the linked list specified
|                             by the handle list_handle.  The position of the new item
|                             can be specified. A position of 0xFFFFFFFF means append to the 
|                             list( use the OCTAPI_LLM_LIST_APPEND define for clarity); 
|                   a position of 0 mean insert at the begining of the list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|     **item_data             void              Address of the user data space for this item.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListInsertItem
UINT32 OctApiLlmListInsertItem(void * l,UINT32 list_handle,UINT32 item_number,void ** item_data_pnt)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* free_item;
      UINT32 free_item_pnt;
      UINT32 total_lists;
      BYTE* lsbyte;
      UINT32      fConditionFlag = TRUE;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      *item_data_pnt = NULL;
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      if (lh->list_length < item_number && item_number != 0xFFFFFFFF)   
            return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM_NO_STRUCTURES_LEFT);

      /* Get a free item from the free item list!*/
      free_item_pnt = ls->next_empty_item;
      free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt);
      ls->next_empty_item = free_item->forward_link;

      if (item_number == 0xFFFFFFFF)
            item_number = lh->list_length;

      if (lh->list_length == 0)     /* First item and only item:*/
      {
            free_item->forward_link = 0xFFFFFFFF;
            lh->tail_pointer = free_item_pnt;
            lh->head_pointer = free_item_pnt;
      }
      else if (item_number == 0)    /* First item and but list not empty:*/
      {
            free_item->forward_link = lh->head_pointer;
            lh->head_pointer = free_item_pnt;
      }
      else if (item_number == lh->list_length)  /* Append:*/
      {
            LLM_LIST_ITEM * last_item;
            last_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer);

            last_item->forward_link = free_item_pnt;
            free_item->forward_link = 0xFFFFFFFF;
            lh->tail_pointer = free_item_pnt;
      }
      else  /* Insert:*/
      {
            LLM_LIST_ITEM * last_item = NULL;
            LLM_LIST_ITEM * item;
            UINT32 last_list_pnt;
            UINT32 cur_list_pnt;
            UINT32 cur_list_num;

            if (lh->cache_item_number < item_number)  /* Start at cache:*/
            {
                  cur_list_pnt = lh->cache_item_pointer;
                  cur_list_num = lh->cache_item_number;
            }
            else /* Start at beginning:*/
            {
                  cur_list_pnt = lh->head_pointer;
                  cur_list_num = 0;
            }

            last_list_pnt = 0xFFFFFFFF;

            /* Start search from cur_list_pnt and cur_list_num.*/
            while ( fConditionFlag == TRUE )
            {
                  item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);

                  if (cur_list_num == item_number) /* Item number found.*/
                  {
                        if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1);

                        free_item->forward_link = cur_list_pnt;
                        last_item->forward_link = free_item_pnt;
                        
                        fConditionFlag = FALSE;
                        break;
                  }
                  else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/
                  {
                        return(OCTAPI_LLM_INTERNAL_ERROR0);
                  }
                  else /* Item was not found, but continue searching.*/
                  {
                        last_item = item;
                        last_list_pnt = cur_list_pnt;
                        cur_list_pnt = item->forward_link;
                  }

                  cur_list_num++;
            }
      }

      /* Increase the list length.*/
      lh->list_length++;
      ls->assigned_items++;
      *item_data_pnt = (void *)free_item->user_info;

      /* Write new cache entry.*/
      lh->cache_item_pointer = free_item_pnt;
      lh->cache_item_number = item_number;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListCreateFull.
|
|     Description:      This function allocates the desired number of nodes to
|                             the linked list specified by the handle list_handle.
|                             The position of the new item can be specified. A
|                             position of 0xFFFFFFFF means append to the list (use the
|                             OCTAPI_LLM_LIST_APPEND define for clarity); a position
|                             of 0 means insert at the begining of the list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|     **item_data             void              Address of the user data space for this item.
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListCreateFull
UINT32 OctApiLlmListCreateFull(void* l, UINT32 list_length, UINT32* plist_handle)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* free_item;
      LLM_LIST_ITEM* last_item = NULL;
      UINT32 free_item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      UINT32 list_handle;
      UINT32 list_length_m1;
      UINT32 next_empty_item;
      UINT32 result;
      UINT32 i;
      BYTE* lsbyte;


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Build the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Make sure another list can be created.*/
      if (ls->assigned_lists == ls->total_lists)
            return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED);

      /* Make sure there are enough free nodes to fill the new list.*/
      if (list_length > (ls->total_items - ls->assigned_items))
            return(OCTAPI_LLM_ELEMENT_ALREADY_ASSIGNED);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Create list (i.e. get a list using the list head alloc structure.*/
      result = OctapiLlmAllocAlloc(ls->list_head_alloc, &list_handle);
      if (result != GENERIC_OK) return(result);

      /* Initialize the list head structure.*/
      lh = &ls->lh[list_handle];
      lh->list_length = 0;
      lh->head_pointer = 0xFFFFFFFF;
      lh->tail_pointer = 0xFFFFFFFF;
      lh->cache_item_number = 0xFFFFFFFF;
      lh->cache_item_pointer = 0xFFFFFFFF;

      ls->assigned_lists++;
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Add the number of requested nodes to the list.*/
      lh = &ls->lh[list_handle];
      list_length_m1 = list_length - 1;
      next_empty_item = ls->next_empty_item;

      for (i=0; i<list_length; i++)
      {
            /* Get a free item from the free item list!*/
            free_item_pnt = next_empty_item;
            free_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt);
            next_empty_item = free_item->forward_link;

            /* Branch according to whether the node is the first in list, last, or in
                  the middle.*/
            if (i == 0) 
            {
                  /* First item.*/
                  free_item->forward_link = 0xFFFFFFFF;
                  lh->head_pointer = free_item_pnt;
                  lh->tail_pointer = free_item_pnt;
            }
            else if (i == list_length_m1) 
            {
                  /* Last item.*/
                  last_item->forward_link = free_item_pnt;
                  free_item->forward_link = 0xFFFFFFFF;
                  lh->tail_pointer = free_item_pnt;
            }
            else
            {
                  /* Node somewhere in the middle.*/
                  last_item->forward_link = free_item_pnt;
            }

            /* Store pointer to free item as pointer to last item (for next iteration).*/
            last_item = free_item;
      }

      /* Store new value of next_empty_item.*/
      ls->next_empty_item = next_empty_item;

      /* Write new cache entry.*/
      lh->cache_item_pointer = free_item_pnt;
      lh->cache_item_number = list_length_m1;

      /* Set the list length.*/
      lh->list_length = list_length;
      ls->assigned_items += list_length;

      /* Return pointer to new list.*/
      *plist_handle = list_handle;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListAppendItems.
|
|     Description:      This function allocates the desired number of nodes to
|                             the linked list specified by the handle list_handle.
|                             The position of the new item can be specified. A
|                             position of 0xFFFFFFFF means append to the list (use the
|                             OCTAPI_LLM_LIST_APPEND define for clarity); a position
|                             of 0 means insert at the begining of the list.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|     **item_data             void              Address of the user data space for this item.
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListAppendItems
UINT32 OctApiLlmListAppendItems(void* l, UINT32 list_handle, UINT32 num_items)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* item_list;
      LLM_LIST_ITEM* curr_item = NULL;
      LLM_LIST_ITEM* free_item;
      UINT32 curr_item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      UINT32 next_empty_item;
      UINT32 item_size;
      UINT32 i;
      BYTE* lsbyte;


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Build the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Make sure list handle is valid.*/
      if (list_handle >= ls->total_lists)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      /* Make sure there is at least one item.*/
      if (num_items == 0)
            return(OCTAPI_LLM_INVALID_PARAMETER);

      /* Make sure there are enough free nodes.*/
      if (num_items > (ls->total_items - ls->assigned_items))
            return(OCTAPI_LLM_NO_STRUCTURES_LEFT);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Get pointer to list structure.*/
      lh = &ls->lh[list_handle];
      if (lh->list_length == 0xFFFFFFFF)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Add the number of requested nodes to the list.*/
      item_list = ls->li;
      item_size = ls->item_size;
      next_empty_item = ls->next_empty_item;

      for (i=0; i<num_items; i++)
      {
            if (i == 0)
            {
                  if (lh->head_pointer == 0xFFFFFFFF)
                  {
                        /* Current and next items are one and the same!*/
                        curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                        /* Set new head and tail pointers.*/
                        lh->head_pointer = next_empty_item;
                        lh->tail_pointer = next_empty_item;

                        /* Update current item pnt.*/
                        curr_item_pnt = next_empty_item;

                        /* Update next item.*/
                        next_empty_item = curr_item->forward_link;

                        /* Set first item to be only item in list.*/
                        curr_item->forward_link = 0xFFFFFFFF;
                  }
                  else
                  {
                        /* Get a free item from the free item list!*/
                        curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer);
                        free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                        /* Have current item point to next empty item.*/
                        curr_item->forward_link = next_empty_item;

                        /* Update current item pnt.*/
                        curr_item_pnt = next_empty_item;

                        /* Update next_empty_item.*/
                        next_empty_item = free_item->forward_link;

                        /* Update pointers to current item and free item.*/
                        curr_item = free_item;
                  }
            }
            else
            {
                  /* Update pointers to current item and free item.*/
                  free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                  /* Have current item point to next empty item.*/
                  curr_item->forward_link = next_empty_item;

                  /* Update current item pnt.*/
                  curr_item_pnt = next_empty_item;

                  /* Update next_empty_item.*/
                  next_empty_item = free_item->forward_link;

                  /* Update pointers to current item and free item.*/
                  curr_item = free_item;
            }
      }

      /* Terminate list.*/
      if ( curr_item != NULL )
            curr_item->forward_link = 0xFFFFFFFF;

      /* Update llman structure variables.*/
      ls->next_empty_item = next_empty_item;
      ls->assigned_items += num_items;

      /* Update list variables.*/
      lh->list_length += num_items;
      lh->cache_item_pointer = curr_item_pnt;
      lh->cache_item_number = lh->list_length - 1;
      lh->tail_pointer = curr_item_pnt;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListAppendAndSetItems.
|
|     Description:
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListAppendAndSetItems
UINT32 OctApiLlmListAppendAndSetItems(void* l, UINT32 list_handle, UINT32 num_items, void* data_list)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* item_list;
      LLM_LIST_ITEM* curr_item = NULL;
      LLM_LIST_ITEM* free_item;
      UINT32 curr_item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      UINT32 next_empty_item;
      UINT32 user_info_bytes;
      UINT32 item_size;
      UINT32 i;
      BYTE* lsbyte;
      void* data_item;


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Build the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Make sure list handle is valid.*/
      if (list_handle >= ls->total_lists)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      /* Make sure there is at least one item.*/
      if (num_items == 0)
            return(OCTAPI_LLM_INVALID_PARAMETER);

      /* Make sure there are enough free nodes.*/
      if (num_items > (ls->total_items - ls->assigned_items))
            return(OCTAPI_LLM_NO_STRUCTURES_LEFT);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Get pointer to list structure.*/
      lh = &ls->lh[list_handle];
      if (lh->list_length == 0xFFFFFFFF)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Add the number of requested nodes to the list.*/
      item_list = ls->li;
      user_info_bytes = ls->user_info_bytes;
      item_size = ls->item_size;
      next_empty_item = ls->next_empty_item;
      data_item = data_list;

      for (i=0; i<num_items; i++)
      {
            if (i == 0)
            {
                  if (lh->head_pointer == 0xFFFFFFFF)
                  {
                        /* Current and next items are one and the same!*/
                        curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                        /* Set new head and tail pointers.*/
                        lh->head_pointer = next_empty_item;
                        lh->tail_pointer = next_empty_item;

                        /* Update current item pnt.*/
                        curr_item_pnt = next_empty_item;

                        /* Update next item.*/
                        next_empty_item = curr_item->forward_link;

                        /* Set first item to be only item in list.*/
                        curr_item->forward_link = 0xFFFFFFFF;
                  }
                  else
                  {
                        /* Get a free item from the free item list!*/
                        curr_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * lh->tail_pointer);
                        free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                        /* Have current item point to next empty item.*/
                        curr_item->forward_link = next_empty_item;

                        /* Update current item pnt.*/
                        curr_item_pnt = next_empty_item;

                        /* Update next_empty_item.*/
                        next_empty_item = free_item->forward_link;

                        /* Update pointers to current item and free item.*/
                        curr_item = free_item;
                  }
            }
            else
            {
                  /* Update pointers to current item and free item.*/
                  free_item = (LLM_LIST_ITEM *)((BYTE *)item_list + item_size * next_empty_item);

                  /* Have current item point to next empty item.*/
                  curr_item->forward_link = next_empty_item;

                  /* Update current item pnt.*/
                  curr_item_pnt = next_empty_item;

                  /* Update next_empty_item.*/
                  next_empty_item = free_item->forward_link;

                  /* Update pointers to current item and free item.*/
                  curr_item = free_item;
            }

            /* Copy data to new item.*/
            OctApiLlmMemCpy(curr_item->user_info, data_item, user_info_bytes);

            /* Update data_item pointer for next iteration (item).*/
            data_item = (void *)((BYTE *)data_item + user_info_bytes);
      }


      /* Terminate list.*/
      if ( curr_item != NULL )
            curr_item->forward_link = 0xFFFFFFFF;

      /* Update llman structure variables.*/
      ls->next_empty_item = next_empty_item;
      ls->assigned_items += num_items;

      /* Update list variables.*/
      lh->list_length += num_items;
      lh->cache_item_pointer = curr_item_pnt;
      lh->cache_item_number = lh->list_length - 1;
      lh->tail_pointer = curr_item_pnt;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListSetItems.
|
|     Description:      This function takes a start entry (0 to length - 1),
|                             a pointer to a list of data (each item of list is the
|                             size of one data unit, specified at init), and the
|                             length of the data list.  From this, the data will be
|                             copied from the data list to the linked list, from
|                             entry start_entry to (start_entry + data_length - 1).
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListSetItems
UINT32 OctApiLlmListSetItems(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* item = NULL;
      UINT32 total_lists;
      UINT32 item_pnt = 0xFFFFFFFF;
      UINT32 i, j;
      BYTE* lsbyte;
      void* pdata_item = NULL;


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Build the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Make sure list handle is valid.*/
      if (list_handle >= ls->total_lists)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      lh = &ls->lh[list_handle];
      if (lh->list_length == 0xFFFFFFFF)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      /* Make sure the start_entry is within limits.*/
      if (start_item >= lh->list_length)
            return(OCTAPI_LLM_INVALID_PARAMETER);

      /* Make sure the end_entry is within limits.*/
      lh = &ls->lh[list_handle];
      if ((start_item + data_length) > lh->list_length)
            return(OCTAPI_LLM_INVALID_PARAMETER);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Set the data of each node.*/
      for (i=0; i<data_length; i++)
      {
            /* Obtain pointer to current item.*/
            if (i == 0) 
            {
                  /* Check if location of start item is already cached.  If not, must search
                        for it manually.*/
                  if (start_item == (lh->cache_item_number + 1))
                  {
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer);
                        item_pnt = item->forward_link;
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);
                  }
                  else
                  {
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer);
                        item_pnt = lh->head_pointer;
                        for (j=0; j<start_item; j++)
                        {
                              item_pnt = item->forward_link;
                              item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);
                        }
                  }

                  pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes));
            }
            else
            {
                  item_pnt = item->forward_link;
                  item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);

                  pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes);
            }

            /* Set the value of the item's user data.*/
            OctApiLlmMemCpy(item->user_info, pdata_item, ls->user_info_bytes);
      }

      /* Write new cache entry.*/
      lh->cache_item_pointer = item_pnt;
      lh->cache_item_number = start_item + data_length - 1;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListCopyData.
|
|     Description:      This function takes a start entry (0 to length - 1),
|                             a pointer to a list of data (each item of list is the
|                             size of one data unit, specified at init), and the
|                             length of the data list.  From this, the data will be
|                             copied from the linked list to the data list, from
|                             entry start_entry of the linked list to
|                             (start_entry + data_length - 1).
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListCopyData
UINT32 OctApiLlmListCopyData(void* l, UINT32 list_handle, UINT32 start_item, UINT32 data_length, void* pdata_list)
{
      LLM_LIST* ls;
      LLM_LIST_HEAD* lh;
      LLM_LIST_ITEM* item = NULL;
      UINT32 item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      UINT32 i, j;
      BYTE* lsbyte;
      void* pdata_item = NULL;


      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Build the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Make sure list handle is valid.*/
      if (list_handle >= ls->total_lists)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      lh = &ls->lh[list_handle];
      if (lh->list_length == 0xFFFFFFFF)
            return(OCTAPI_LLM_INVALID_LIST_HANDLE);

      /* Make sure the start_entry is within limits.*/
      if (start_item >= lh->list_length)
            return(OCTAPI_LLM_INVALID_PARAMETER);

      /* Make sure the end_entry is within limits.*/
      lh = &ls->lh[list_handle];
      if ((start_item + data_length) > lh->list_length)
            return(OCTAPI_LLM_INVALID_PARAMETER);
      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/



      /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
      /* Set the data of each node.*/
      for (i=0; i<data_length; i++)
      {
            /* Obtain pointer to current item.*/
            if (i == 0) 
            {
                  /* Check if location of start item is already cached.  If not, must search
                        for it manually.*/
                  if (start_item == (lh->cache_item_number + 1))
                  {
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->cache_item_pointer);
                        item_pnt = item->forward_link;
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);
                  }
                  else
                  {
                        item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->head_pointer);
                        for (j=0; j<start_item; j++)
                        {
                              item_pnt = item->forward_link;
                              item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);
                        }
                  }

                  pdata_item = (void *)((BYTE *)pdata_list + (i * ls->user_info_bytes));
            }
            else
            {
                  item_pnt = item->forward_link;
                  item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * item_pnt);

                  pdata_item = (void *)((BYTE *)pdata_item + ls->user_info_bytes);
            }

            /* Set the value of the item's user data.*/
            OctApiLlmMemCpy(pdata_item, item->user_info, ls->user_info_bytes);
      }

      /* Write new cache entry.*/
      lh->cache_item_pointer = item_pnt;
      lh->cache_item_number = start_item + data_length - 1;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListRemoveItem.
|
|     Description:      This function deallocates a node of the linked list specified
|                             by the handle list_handle.  
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     item_number             UINT32                  The number of the item to be removed.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmListRemoveItem
UINT32 OctApiLlmListRemoveItem(void * l,UINT32 list_handle,UINT32 item_number)
{
      LLM_LIST* ls;
      LLM_LIST_ITEM* freed_item = NULL;
      LLM_LIST_HEAD* lh;
      UINT32 freed_item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      BYTE* lsbyte;
      UINT32      fConditionFlag = TRUE;

      /* Built the structure based on the base address:*/
      ls = (LLM_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM_LIST_HEAD *)(lsbyte + sizeof(LLM_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)));
      ls->li = (LLM_LIST_ITEM *)(lsbyte + sizeof(LLM_LIST) + (total_lists * sizeof(LLM_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM_INVALID_LIST_HANDLE);
      if (lh->list_length <= item_number) return(OCTAPI_LLM_BLOCKNUM_OUT_OF_RANGE);

      if (item_number == 0 && lh->list_length == 1)/* First item and only item:*/
      {
            freed_item_pnt = lh->head_pointer;
            freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt);

            lh->head_pointer = 0xFFFFFFFF;
            lh->tail_pointer = 0xFFFFFFFF;

            lh->cache_item_number = 0xFFFFFFFF;
            lh->cache_item_pointer = 0xFFFFFFFF;
      }
      else if (item_number == 0)    /* First item and but list not empty:*/
      {
            freed_item_pnt = ls->lh[list_handle].head_pointer;
            freed_item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt);

            lh->head_pointer = freed_item->forward_link;

            lh->cache_item_number = 0;
            lh->cache_item_pointer = freed_item->forward_link;
      }
      else  /* Discard non-first item! (Caution: this could be the last item!)*/
      {
            LLM_LIST_ITEM * last_item = NULL;
            LLM_LIST_ITEM * item;
            UINT32 last_list_pnt;
            UINT32 cur_list_pnt;
            UINT32 cur_list_num;

            if (lh->cache_item_number < item_number)  /* Start at cache:*/
            {
                  cur_list_pnt = lh->cache_item_pointer;
                  cur_list_num = lh->cache_item_number;
            }
            else /* Start at beginning:*/
            {
                  cur_list_pnt = lh->head_pointer;
                  cur_list_num = 0;
            }

            last_list_pnt = 0xFFFFFFFF;

            /* Start search from cur_list_pnt and cur_list_num.*/
            while( fConditionFlag == TRUE )
            {
                  item = (LLM_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);

                  if (cur_list_num == item_number) /* Item number found.*/
                  {
                        if (last_list_pnt == 0xFFFFFFFF) return(OCTAPI_LLM_INTERNAL_ERROR1);

                        if ((item_number + 1) == lh->list_length)
                        {
                              lh->tail_pointer = last_list_pnt;
                              last_item->forward_link = 0xFFFFFFFF;
                        }
                        else
                        {
                              last_item->forward_link = item->forward_link;
                        }
                        freed_item_pnt = cur_list_pnt;
                        freed_item = item;

                        /* Reset cache entry.*/
                        lh->cache_item_pointer = last_list_pnt;
                        lh->cache_item_number = cur_list_num - 1;

                        fConditionFlag = FALSE;
                        break;
                  }
                  else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/
                  {
                        return(OCTAPI_LLM_INTERNAL_ERROR0);
                  }
                  else /* Item was not found, but continue searching.*/
                  {
                        last_item = item;
                        last_list_pnt = cur_list_pnt;
                        cur_list_pnt = item->forward_link;
                  }

                  cur_list_num++;
            }
      }

      /* Decrease the list length.*/
      lh->list_length--;
      ls->assigned_items--;

      /* Return free block to free block list:*/
      freed_item->forward_link = ls->next_empty_item;
      ls->next_empty_item = freed_item_pnt;

      return(GENERIC_OK);
}
#endif

/**************************************** llm2 function section *****************************************/


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListGetSize
|
|     Description:      This function determines the amount of memory needed by
|                             the LLM2_LIST structure to manage the allocation of
|                             number_of_items number of resources.  The memory is
|                             measured in bytes.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     number_of_items         UINT32                  The number of resources to be allocated
|                                                           amongst all linked-lists.
|     number_of_lists         UINT32                  The maximum number of linked-lists that
|                                                           can be allocated.
|     *l_size     UINT32            UINT32                  The amount of memory needed, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListGetSize
UINT32 OctApiLlm2ListGetSize(UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size,UINT32 * l_size)
{
      UINT32 head_alloc_size;
      UINT32 result;
      UINT32 user_info_size_roundup;

      if (number_of_items == 0) return(GENERIC_BAD_PARAM);
      if (number_of_lists == 0) return(GENERIC_BAD_PARAM);
      if (user_info_size == 0) return(GENERIC_BAD_PARAM);

      user_info_size_roundup = ((user_info_size + 3) / 4) * 4;

      result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size);
      if(result != GENERIC_OK) return(result);

      *l_size = sizeof(LLM2_LIST) + (number_of_lists * sizeof(LLM2_LIST_HEAD)) + head_alloc_size + (number_of_items * (sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4));

      return(GENERIC_OK);
}
#endif

#if !SKIP_OctApiLlm2ListGetItemPointer
LLM2_LIST_ITEM * OctApiLlm2ListGetItemPointer(LLM2_LIST * ls, UINT32 item_number)
{
      return (LLM2_LIST_ITEM *) (((BYTE *)ls->li) + (ls->item_size * item_number)) ;
}
#endif


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListInit.
|
|     Description:      This function intializes the LLM2_TALLOC structure.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     number_of_items         UINT32                  The number of resources to be allocated
|                                                           amongst all linked-lists.
|     number_of_lists         UINT32                  The maximum number of linked-lists that
|                                                           can be allocated.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListInit
UINT32 OctApiLlm2ListInit(void ** l,UINT32 number_of_items,UINT32 number_of_lists,UINT32 user_info_size)
{
      LLM2_LIST* ls;
      LLM2_LIST_ITEM* item;
      UINT32 i;
      UINT32 head_alloc_size;
      UINT32 result;
      UINT32 user_info_size_roundup;
      UINT32 total_lists;
      BYTE* lsbyte;


      if (number_of_items == 0) return(GENERIC_BAD_PARAM);
      if (number_of_lists == 0) return(GENERIC_BAD_PARAM);
      if (user_info_size == 0) return(GENERIC_BAD_PARAM);

      user_info_size_roundup = ((user_info_size + 3) / 4) * 4;

      /* Get the size of the Alloc structure used to manage head of list structures.*/
      result = OctapiLlmAllocGetSize(number_of_lists,&head_alloc_size);
      if(result != GENERIC_OK) return(result);

      if (*l == NULL) return(OCTAPI_LLM_MEMORY_NOT_ALLOCATED);

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)(*l);
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      /* Initialize parameters in the structure.*/
      ls->head_alloc_size = head_alloc_size;
      ls->user_info_bytes = user_info_size;
      ls->user_info_size = user_info_size_roundup;
      ls->total_items = number_of_items;
      ls->assigned_items = 0;
      ls->total_lists = number_of_lists;
      ls->assigned_lists = 0;
      ls->next_empty_item = 0;
      ls->item_size = sizeof(LLM2_LIST_ITEM) + user_info_size_roundup - 4;

      /* Complete the build!*/
      ls = (LLM2_LIST *)(*l);
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      /* Initialize the head of queue Alloc structure.*/
      result = OctapiLlmAllocInit(&(ls->list_head_alloc),number_of_lists);
      if(result != GENERIC_OK) return(result);

      /* Initialize the linked list of the items:*/
      for(i=0; i<number_of_items; i++)
      {
            item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * i);

            if (i == (number_of_items - 1))
                  item->forward_link = 0xFFFFFFFF;
            else
                  item->forward_link = i + 1;
      }

      return(GENERIC_OK);
}
#endif


/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListCreate.
|
|     Description:      This function creates a linked list.  The target which is
|                             allocated the newly created list can request additions
|                             or removals from the list later on.  To target identifies
|                             its list with the returned list handle.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM_LIST structure.
|     *list_handle            UINT32                  The handle to the new list, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListCreate
UINT32 OctApiLlm2ListCreate(void * l,UINT32 * list_handle)
{
      LLM2_LIST* ls;
      LLM2_LIST_HEAD* lh;
      UINT32 blocknum;
      UINT32 total_lists;
      UINT32 result;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      /* Get a list using the list head alloc structure.*/
      result = OctapiLlmAllocAlloc(ls->list_head_alloc, &blocknum);
      if (result != GENERIC_OK) return(result);

      /* The handle is the block number.*/
      *list_handle = blocknum;

      /* Initialize the list head structure.*/
      lh = &ls->lh[blocknum];
      lh->list_length = 0;
      lh->head_pointer = 0xFFFFFFFF;
      lh->tail_pointer = 0xFFFFFFFF;

      ls->assigned_lists++;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListDelete.
|
|     Description:      This function deletes the linked list indicated by the
|                             handle list_handle.  Any items which are still allocated
|                             to the list are first deallocated.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListDelete
UINT32 OctApiLlm2ListDelete(void * l,UINT32 list_handle)
{
      LLM2_LIST* ls;
      LLM2_LIST_HEAD* lh;
      UINT32 total_lists;
      UINT32 result;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE);
      if (ls->lh[list_handle].list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE);

      /* Release internal list header handle...*/
      result = OctapiLlmAllocDealloc(ls->list_head_alloc,list_handle);
      if (result != GENERIC_OK) return(result);

      lh = &ls->lh[list_handle];

      /* Deallocate all items in the list!*/
      if (lh->list_length != 0)
      {
            LLM2_LIST_ITEM * item;

            item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * lh->tail_pointer);

            /* Release the items using only the links.*/
            item->forward_link = ls->next_empty_item;
            ls->next_empty_item = lh->head_pointer;

            /* Remove items from item counter.*/
            ls->assigned_items -= lh->list_length;
      }

      lh->list_length = 0xFFFFFFFF;
      lh->head_pointer = 0xFFFFFFFF;
      lh->tail_pointer = 0xFFFFFFFF;

      ls->assigned_lists--;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmListLength.
|
|     Description:      This function returns the number of items allocated to the
|                             list indicated by the handle list_handle.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     *number_of_items  UINT32                  The number of items in the list, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListLength
UINT32 OctApiLlm2ListLength(void * l,UINT32 list_handle, UINT32 * number_of_items_in_list)
{
      LLM2_LIST* ls;
      LLM2_LIST_HEAD* lh;
      UINT32 total_lists;
      BYTE* lsbyte;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE);

      *number_of_items_in_list = lh->list_length;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListItemData
|
|     Description:      This function returns a pointer to the user data associated
|                             with an item.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     item_number             UINT32                  The number of the list node in question.
|     **item_data_pnt         void              The pointer to the user data, returned.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListItemData
UINT32 OctApiLlm2ListItemData(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, PUINT32 item_number_pnt)
{
      LLM2_LIST* ls;
      LLM2_LIST_HEAD* lh;
      LLM2_LIST_ITEM* item;
      UINT32 cur_list_pnt;
      UINT32 cur_list_key = 0xFFFFFFFF;
      UINT32 total_lists;
      UINT32 list_length;
      BYTE* lsbyte;
      UINT32      fConditionFlag = TRUE;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      list_length = lh->list_length;
      
      *item_data_pnt = NULL;
      *item_number_pnt = 0;
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE);
      if (list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE);

      /* Determine where the search will start.*/
      /* Start at beginning:*/
      cur_list_pnt = lh->head_pointer;
      item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
      cur_list_key = item->key;
      
      /* Start search from cur_list_pnt and cur_list_num.*/
      while ( fConditionFlag == TRUE )
      {
            if (cur_list_key == item_key) /* Item key found.*/
            {
                  /* Get item info.*/
                  *item_data_pnt = (void *)item->user_info;

                  return(GENERIC_OK);
            }
            else if(item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/
            {
                  return(OCTAPI_LLM2_INTERNAL_ERROR0);
            }
            else /* Item was not found, but continue searching.*/
            {
                  cur_list_pnt = item->forward_link;
            }

            item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
            cur_list_key = item->key;
            (*item_number_pnt)++;
      }

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListInsertItem.
|
|     Description:      This function allocates a node to the linked list specified
|                             by the handle list_handle.  The position of the new item
|                             will be defined based on the key value.  All entry are inserted
|                             in the list in incremental Key value.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     *list_handle            UINT32                  The handle to the list.
|     **item_data             void              Address of the user data space for this item.
|     **prev_item_data  void              Address of the user data space for the previous item.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListInsertItem
UINT32 OctApiLlm2ListInsertItem(void * l,UINT32 list_handle,UINT32 item_key,void ** item_data_pnt, void ** prev_item_data_pnt, void ** prev_prev_item_data_pnt, PUINT32 insert_status_pnt )
{
      LLM2_LIST* ls;
      LLM2_LIST_HEAD* lh;
      LLM2_LIST_ITEM* free_item;
      UINT32 free_item_pnt;
      UINT32 total_lists;
      BYTE* lsbyte;
      UINT32      ulPassCount = 0;
      UINT32      fConditionFlag = TRUE;

      /* Set the status of the insertion.*/
      *insert_status_pnt = OCTAPI_LLM2_INSERT_ERROR;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      *item_data_pnt = NULL;
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE);
      if (ls->next_empty_item == 0xFFFFFFFF) return(OCTAPI_LLM2_NO_STRUCTURES_LEFT);

      /* Get a free item from the free item list!*/
      free_item_pnt = ls->next_empty_item;
      free_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * free_item_pnt);
      free_item->key = item_key;
      ls->next_empty_item = free_item->forward_link;

      if (lh->list_length == 0)     /* First item and only item:*/
      {
            free_item->forward_link = 0xFFFFFFFF;
            lh->tail_pointer = free_item_pnt;
            lh->head_pointer = free_item_pnt;
            *insert_status_pnt = OCTAPI_LLM2_INSERT_FIRST_NODE;

            /* There is no previous node information to return.*/
            *prev_item_data_pnt = NULL;
            *prev_prev_item_data_pnt = NULL;
      }
      else  /* Insert:*/
      {
            LLM2_LIST_ITEM * last_last_item = NULL;
            LLM2_LIST_ITEM * last_item = NULL;
            LLM2_LIST_ITEM * item;
            UINT32 last_list_pnt;
            UINT32 cur_list_pnt;
            UINT32 cur_list_key = 0xFFFFFFFF;

            /* Start at beginning:*/
            cur_list_pnt = lh->head_pointer;
            item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
            cur_list_key = item->key;
            
            last_list_pnt = 0xFFFFFFFF;

            /* Start search from cur_list_pnt and cur_list_num.*/
            while ( fConditionFlag == TRUE )
            {
                  /* Increment the pass count to determine if the addition will happen next to last.*/
                  ulPassCount++;
      
                  if (cur_list_key >= item_key) /* Item new node between the last and the curent. */
                  {
                        if (last_list_pnt == 0xFFFFFFFF) /* Must insert at the head of the list.*/
                        {
                              free_item->forward_link = cur_list_pnt;
                              lh->head_pointer = free_item_pnt;
                        }
                        else                                                  /* Standard insertion.*/
                        {
                              free_item->forward_link = cur_list_pnt;
                              last_item->forward_link = free_item_pnt;
                        }
                  
                        /* Check if the entry was made before the last one.*/
                        if ( ulPassCount == lh->list_length )
                              *insert_status_pnt = OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE;
                        else
                              *insert_status_pnt = OCTAPI_LLM2_INSERT_LIST_NODE;

                        fConditionFlag = FALSE;
                        break;
                  }
                  else if (item->forward_link == 0xFFFFFFFF) /* End of list found, must insert at the end.*/
                  {
                        free_item->forward_link = 0xFFFFFFFF;
                        item->forward_link = free_item_pnt;
                        lh->tail_pointer = free_item_pnt;

                        *insert_status_pnt = OCTAPI_LLM2_INSERT_LAST_NODE;

                        fConditionFlag = FALSE;
                        break;
                  }
                  else /* Item was not found, but continue searching.*/
                  {
                        last_last_item = last_item;
                        last_item = item;
                        last_list_pnt = cur_list_pnt;
                        cur_list_pnt = item->forward_link;
                  }

                  item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
                  cur_list_key = item->key;

            }

            /* Return the previous node if possible.*/
            if ( *insert_status_pnt == OCTAPI_LLM2_INSERT_LIST_NODE ||
                 *insert_status_pnt == OCTAPI_LLM2_INSERT_BEFORE_LAST_NODE )
            {
                  if ( last_item != NULL )
                        *prev_item_data_pnt = (void *)last_item->user_info;

                  if ( last_last_item != NULL )
                        *prev_prev_item_data_pnt = (void *)last_last_item->user_info;
                  else
                        *prev_prev_item_data_pnt = NULL;
            }
            else
            {
                  *prev_item_data_pnt = (void *)item->user_info;

                  if ( ( last_last_item != NULL ) && ( last_item != NULL ) )
                        *prev_prev_item_data_pnt = (void *)last_item->user_info;
                  else
                        *prev_prev_item_data_pnt = NULL;
            }
      }

      /* Increase the list length.*/
      lh->list_length++;
      ls->assigned_items++;
      *item_data_pnt = (void *)free_item->user_info;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlm2ListRemoveItem.
|
|     Description:      This function deallocates a node of the linked list specified
|                             by the handle list_handle.  
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *l                            void              The memory used by the LLM2_LIST structure.
|     list_handle             UINT32                  The handle to the list.
|     item_key                UINT32                  The key of the item to be removed.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlm2ListRemoveItem
UINT32 OctApiLlm2ListRemoveItem(void * l,UINT32 list_handle,UINT32 item_key, PUINT32 prev_item_key_pnt, PUINT32 prev_prev_item_key_pnt, PUINT32 remove_status_pnt )
{
      LLM2_LIST* ls;
      LLM2_LIST_ITEM* freed_item = NULL;
      LLM2_LIST_HEAD* lh;
      UINT32 freed_item_pnt = 0xFFFFFFFF;
      UINT32 total_lists;
      BYTE* lsbyte;
      UINT32      fConditionFlag = TRUE;
      UINT32      ulPassCount = 0;

      /* Built the structure based on the base address:*/
      ls = (LLM2_LIST *)l;
      lsbyte = (BYTE *)ls;
      total_lists = ls->total_lists;

      /* Set the status of the removal to error as a default value.*/
      *remove_status_pnt = OCTAPI_LLM2_REMOVE_ERROR;
      
      ls->lh = (LLM2_LIST_HEAD *)(lsbyte + sizeof(LLM2_LIST));
      ls->list_head_alloc = (void *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)));
      ls->li = (LLM2_LIST_ITEM *)(lsbyte + sizeof(LLM2_LIST) + (total_lists * sizeof(LLM2_LIST_HEAD)) + ls->head_alloc_size);

      lh = &ls->lh[list_handle];
      
      if (list_handle >= ls->total_lists) return(OCTAPI_LLM2_BLOCKNUM_OUT_OF_RANGE);
      if (lh->list_length == 0xFFFFFFFF) return(OCTAPI_LLM2_INVALID_LIST_HANDLE);

      if (lh->list_length == 1)/* First item and only item if he matches.*/
      {
            freed_item_pnt = lh->head_pointer;
            freed_item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * freed_item_pnt);

            if ( freed_item->key == item_key )
            {
                  lh->head_pointer = 0xFFFFFFFF;
                  lh->tail_pointer = 0xFFFFFFFF;
            }
            else
                  return(OCTAPI_LLM2_INTERNAL_ERROR1);
            
            /* Indicate that there was no node prior to the one removed.*/
            *prev_item_key_pnt = 0xFFFFFFFF;
            *prev_prev_item_key_pnt = 0xFFFFFFFF;
            *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE;
      }
      else  /* Discard non-first item! (Caution: this could be the last item!)*/
      {
            LLM2_LIST_ITEM * last_last_item = NULL;
            LLM2_LIST_ITEM * last_item = NULL;
            LLM2_LIST_ITEM * item;
            UINT32 last_list_pnt;
            UINT32 cur_list_pnt;
            UINT32 cur_list_key;

            /* Start at beginning:*/
            cur_list_pnt = lh->head_pointer;
            item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
            cur_list_key = item->key;
            
            last_list_pnt = 0xFFFFFFFF;

            /* Start search from cur_list_pnt and cur_list_num.*/
            while( fConditionFlag == TRUE )
            {
                  ulPassCount++;
                  if (cur_list_key == item_key) /* Item number found.*/
                  {
                        if (last_list_pnt == 0xFFFFFFFF)    /* First item in the list.*/
                        {
                              lh->head_pointer = item->forward_link;
                              *remove_status_pnt = OCTAPI_LLM2_REMOVE_FIRST_NODE;
                        }
                        else if ( item->forward_link == 0xFFFFFFFF)     /* Last item of the list.*/
                        {
                              last_item->forward_link = 0xFFFFFFFF;
                              lh->tail_pointer = last_list_pnt;
                              *remove_status_pnt = OCTAPI_LLM2_REMOVE_LAST_NODE;
                        }
                        else
                        {
                              last_item->forward_link = item->forward_link;

                              if ( ulPassCount == ( lh->list_length - 1 ) )
                                    *remove_status_pnt = OCTAPI_LLM2_REMOVE_BEFORE_LAST_NODE;
                              else
                                    *remove_status_pnt = OCTAPI_LLM2_REMOVE_LIST_NODE;
                        }
                              
                        freed_item_pnt = cur_list_pnt;
                        freed_item = item;

                        fConditionFlag = FALSE;
                        break;
                  }
                  else if (item->forward_link == 0xFFFFFFFF) /* End of list found?!?*/
                  {
                        return(OCTAPI_LLM2_INTERNAL_ERROR0);
                  }
                  else /* Item was not found, but continue searching.*/
                  {
                        last_last_item = last_item;
                        last_item = item;
                        last_list_pnt = cur_list_pnt;
                        cur_list_pnt = item->forward_link;
                  }

                  item = (LLM2_LIST_ITEM *)((BYTE *)ls->li + ls->item_size * cur_list_pnt);
                  cur_list_key = item->key;
            }

            /* Return the key of the node before the node removed if possible.*/
            if ( last_list_pnt == 0xFFFFFFFF )
                  *prev_item_key_pnt = 0xFFFFFFFF;
            else if ( last_item != NULL )
                  *prev_item_key_pnt = last_item->key;

            /* Return the key of the node before before the node removed if possible.*/
            if ( last_last_item == NULL )
                  *prev_prev_item_key_pnt = 0xFFFFFFFF;
            else
                  *prev_prev_item_key_pnt = last_last_item->key;

      }

      /* Decrease the list length.*/
      lh->list_length--;
      ls->assigned_items--;

      /* Return free block to free block list:*/
      freed_item->forward_link = ls->next_empty_item;
      ls->next_empty_item = freed_item_pnt;

      return(GENERIC_OK);
}
#endif

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|     API UTILITIES
|
|     Function:         OctApiLlmMemCpy.
|
|     Description:      This function copies data from a source to a destination.
|
|  -----------------------------------------------------------------------  
|  |   Variable        |     Type     |          Description                
|  -----------------------------------------------------------------------  
|     *f_pvDestination  VOID              The destination where to copy the data.
|     *f_pvSource             VOID              The source where to copy the data from.
|     f_ulSize                UINT32                  The number of bytes to copy.
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if !SKIP_OctApiLlmMemCpy
VOID * OctApiLlmMemCpy( VOID *f_pvDestination, const VOID * f_pvSource, UINT32 f_ulSize )
{
    CHAR * pbyDst;
    const CHAR * pbySrc;
    UINT32 * f_pulAlignedDst;
    const UINT32 * f_pulAlignedSrc;
    
    pbyDst = (CHAR *)f_pvDestination;
    pbySrc = (const CHAR *)f_pvSource;

    /* 
     * If the size is small, or either SRC or DST is unaligned,
     * then punt into the byte copy loop.  This should be rare.
     */
    if ( ( f_ulSize < sizeof(UINT32) ) 
            || ( ( (unsigned long)( pbySrc ) & ( sizeof(UINT32) - 1 ) ) | ( (unsigned long)( pbyDst ) & ( sizeof(UINT32) - 1 ) ) ) )
    {
        while ( f_ulSize-- )
            *pbyDst++ = *pbySrc++;
        return f_pvDestination;
    }
    
    f_pulAlignedDst = (UINT32 *)pbyDst;
    f_pulAlignedSrc = (const UINT32 *)pbySrc;
    
    /* Copy 4X long words at a time if possible. */
    while ( f_ulSize >= 4 * sizeof(UINT32) )
    {
        *f_pulAlignedDst++ = *f_pulAlignedSrc++;
        *f_pulAlignedDst++ = *f_pulAlignedSrc++;
        *f_pulAlignedDst++ = *f_pulAlignedSrc++;
        *f_pulAlignedDst++ = *f_pulAlignedSrc++;
        f_ulSize -= 4 * sizeof(UINT32);
    } 
    
    /* Copy one long word at a time if possible. */
    while ( f_ulSize >= sizeof(UINT32) )
    {
        *f_pulAlignedDst++ = *f_pulAlignedSrc++;
        f_ulSize -= sizeof(UINT32);
    }
    
    /* Pick up any residual with a byte copier. */
    pbyDst = (CHAR *)f_pulAlignedDst;
    pbySrc = (const CHAR *)f_pulAlignedSrc;
    while ( f_ulSize-- )
        *pbyDst++ = *pbySrc++;
    
    return f_pvDestination;
}
#endif

/**************************************** llm_list section **********************************************/


Generated by  Doxygen 1.6.0   Back to index