view src/g23m-aci/uart/uart_drxs.c @ 223:740a8e8fc9d7

startup sync logic rework for the new PWON button boot scheme Previously we added logic to the MMI task to hold off PEI init until R2D is running, and then extended that condition to wait for FCHG init too. However, the dependencies of MMI upon R2D and FCHG don't start until mmiInit(), and that call is driven by Switch_ON() code, hence the wait for R2D and FCHG init can be made in that code path instead of the MMI task. Furthermore, with our new way of signaling PWON button boot to MMI, we need a new wait to ensure that the MMI task is up - previously this assurance was provided by the wait for Kp pointers to be set. Solution: revert our previous PEI init hold-off additions to MMI, add a new flag indicating MMI task init done, and put the combined wait for all needed conditions into our new PWON button boot code in power.c.
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 27 Apr 2021 06:24:52 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  
|  Modul   :  
+----------------------------------------------------------------------------- 
|  Copyright 2002 Texas Instruments Berlin, AG 
|                 All rights reserved. 
| 
|                 This file is confidential and a trade secret of Texas 
|                 Instruments Berlin, AG 
|                 The receipt of or possession of this file does not convey 
|                 any rights to reproduce or disclose its contents or to 
|                 manufacture, use, or sell anything it may describe, in 
|                 whole, or in part, without the specific written consent of 
|                 Texas Instruments Berlin, AG. 
+----------------------------------------------------------------------------- 
|  Purpose :  This modul is part of the entity UART and implements all 
|             functions to handles the incoming process internal signals as  
|             described in the SDL-documentation (DRX-statemachine)
+----------------------------------------------------------------------------- 
*/ 

#ifndef UART_DRXS_C
#define UART_DRXS_C
#endif /* !UART_DRXS_C */

#define ENTITY_UART

/*==== INCLUDES =============================================================*/

#ifdef WIN32
#include "nucleus.h"
#endif /* WIN32 */
#include "typedefs.h"   /* to get Condat data types */
#include "vsi.h"        /* to get a lot of macros */
#include "macdef.h"     /* to get a lot of macros */
#include "custom.h"
#include "gsm.h"        /* to get a lot of macros */
#include "cnf_uart.h"   /* to get cnf-definitions */
#include "mon_uart.h"   /* to get mon-definitions */
#include "prim.h"       /* to get the definitions of used SAP and directions */
#ifdef DTILIB
#include "dti.h"        /* to get dti lib */
#endif /* DTILIB */
#include "pei.h"        /* to get PEI interface */
#ifdef FF_MULTI_PORT
#include "gsi.h"        /* to get definitions of serial driver */
#else /* FF_MULTI_PORT */
#ifdef _TARGET_
#include "uart/serialswitch.h"
#include "uart/traceswitch.h"
#else /* _TARGET_ */
#include "serial_dat.h" /* to get definitions of serial driver */
#endif /* _TARGET_ */
#endif /* FF_MULTI_PORT */
#include "uart.h"       /* to get the global entity definitions */

#include "uart_drxf.h"  /* to get the DRX function declarations */
#include "uart_kers.h"  /* to get the KER signal declarations */
#ifdef FF_MULTI_PORT
#include "uart_ptxs.h"  /* to get signal definitions for service TX */
#else /* FF_MULTI_PORT */
#include "uart_txs.h"   /* to get signal definitions for service TX */
#endif /* FF_MULTI_PORT */

/*==== CONST ================================================================*/

/*==== LOCAL VARS ===========================================================*/

/*==== PRIVATE FUNCTIONS ====================================================*/

/*==== PUBLIC FUNCTIONS =====================================================*/



/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_ready_mode_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_READY_MODE_REQ
|
| Parameters  : dlc_instance - dlc instance wich belongs to this DRX instance
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_ready_mode_req (UBYTE dlc_instance)
{
  TRACE_ISIG( "sig_ker_drx_ready_mode_req" );

  uart_data->drx->dlc_instance = dlc_instance;

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_DEAD:
      /*
       * new DLC starts with enabled data flow
       */
      uart_data->drx->data_flow = UART_FLOW_ENABLED;

#ifdef DTILIB
      if((uart_data->drx->dti_drx_state NEQ DTI_CLOSED ) &&
         (uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING))
      {
        /*
         * signal availability to higher layer if currently not sending
         */
        SET_STATE( UART_SERVICE_DRX, DRX_READY );
#ifdef FLOW_TRACE
        sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
        dti_start(
          uart_hDTI, 
          uart_data->device, 
          UART_DTI_UP_INTERFACE, 
          uart_data->drx->dlc_instance);
      }
#else  /* DTILIB */
      if((uart_data->drx->hComm_DRX_UPLINK NEQ VSI_ERROR ) &&
         (uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING))
      {
        /*
         * signal availability to higher layer if currently not sending
         */
        PALLOC (dti_ready_ind, DTI_READY_IND);
        SET_STATE( UART_SERVICE_DRX, DRX_READY );
        dti_ready_ind->tui  = uart_data->tui_uart;
        dti_ready_ind->c_id = drx_get_channel_id();
#ifdef _SIMULATION_
        dti_ready_ind->op_ack = 0;
#endif /* _SIMULATION_ */
#ifdef FLOW_TRACE
        sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
        PSEND (uart_data->drx->hComm_DRX_UPLINK, dti_ready_ind);
      }
#endif /* DTILIB */
      else
      {
        /*
         * no peer yet, just switch to NOT READY and wait
         * for the signal SIG_KER_DRX_SET_DTI_PEER_REQ
         */
#ifdef DTILIB
        if(uart_data->drx->dti_drx_state NEQ DTI_CLOSED )
          dti_stop(
            uart_hDTI, 
            uart_data->device, 
            UART_DTI_UP_INTERFACE, 
            uart_data->drx->dlc_instance
            );
#endif /* DTILIB */
        SET_STATE( UART_SERVICE_DRX, DRX_NOT_READY );
      }
      break;

    case DRX_READY:
    case DRX_NOT_READY:
    case DRX_FLUSHING:
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_READY_MODE_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_ready_mode_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_dead_mode_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_DEAD_MODE_REQ
|
| Parameters  : none
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_dead_mode_req () 
{ 
  TRACE_ISIG( "sig_ker_drx_dead_mode_req" );
  
  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
      SET_STATE( UART_SERVICE_DRX, DRX_DEAD );
      /*
       * free all resources
       */
#ifdef DTILIB
      uart_data->drx->dti_drx_state = DTI_CLOSED;
#else  /* DTILIB */
      uart_data->drx->hComm_DRX_UPLINK = VSI_ERROR;
#endif /* DTILIB */
      drx_free_resources();
      break;

    case DRX_FLUSHING:
      sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
      /* fall through */
    case DRX_NOT_READY:
      SET_STATE( UART_SERVICE_DRX, DRX_DEAD );

#ifdef DTILIB
      uart_data->drx->dti_drx_state = DTI_CLOSED;
#else  /* DTILIB */
      uart_data->drx->hComm_DRX_UPLINK = VSI_ERROR;
#endif /* DTILIB */
      if(uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING)
      {
        /*
         * signal that there is not any more data available
         */
        sig_drx_tx_data_not_available_ind(uart_data->drx->dlc_instance);
        /*
         * free all resources:
         */
        drx_free_resources();
      }
      else
        uart_data->drx->sending_state = UART_DRX_INVALID;
      break;

    case DRX_DEAD:
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_DEAD_MODE_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_dead_mode_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_enable_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_ENABLE_REQ
|
| Parameters  : none
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_enable_req () 
{
  TRACE_ISIG( "sig_ker_drx_enable_req" );

  uart_data->drx->data_flow = UART_FLOW_ENABLED;

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
      break;

    case DRX_FLUSHING:
    case DRX_NOT_READY:
      /*
       * if DRX is not already sending and there is some data to be sent out,
       * notify service TX that there is data available
       */
      if(uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING)
      {
        if(uart_data->drx->received_data)
          sig_drx_tx_data_available_ind( uart_data->drx->dlc_instance,
                                         uart_data->drx->received_data, 
                                         uart_data->drx->read_pos);
        else
#ifdef DTILIB
          if( uart_data->drx->dti_drx_state NEQ DTI_CLOSED )
          {
            SET_STATE( UART_SERVICE_DRX, DRX_READY );
#ifdef FLOW_TRACE
            sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
            dti_start(
              uart_hDTI, 
              uart_data->device, 
              UART_DTI_UP_INTERFACE, 
              uart_data->drx->dlc_instance
              );
          }
#else  /* DTILIB */
          if(uart_data->drx->hComm_DRX_UPLINK NEQ VSI_ERROR)
        {
          /*
           * nothing more to send,
           * signal to higher layer that we are able to receive more data
           */
          PALLOC (dti_ready_ind, DTI_READY_IND);
          SET_STATE( UART_SERVICE_DRX, DRX_READY );
          dti_ready_ind->tui  = uart_data->tui_uart;
          dti_ready_ind->c_id = drx_get_channel_id();
#ifdef _SIMULATION_
          dti_ready_ind->op_ack = 0;
#endif /* _SIMULATION_ */
#ifdef FLOW_TRACE
          sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
          PSEND (uart_data->drx->hComm_DRX_UPLINK, dti_ready_ind);
        }
#endif /* DTILIB */
      }
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_ENABLE_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_enable_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_disable_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_DISABLE_REQ
|
| Parameters  : none
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_disable_req () 
{
  TRACE_ISIG( "sig_ker_drx_disable_req" );

  uart_data->drx->data_flow = UART_FLOW_DISABLED;

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
      break;

    case DRX_FLUSHING:
    case DRX_NOT_READY:
      /*
       * stop sending if possible
       */
      if(uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING)
        sig_drx_tx_data_not_available_ind(uart_data->drx->dlc_instance);
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_DISABLE_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_disable_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_tx_drx_sending_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_TX_DRX_SENDING_REQ
|
| Parameters  : dummy - description of parameter dummy
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_tx_drx_sending_req () 
{ 
  TRACE_ISIG( "sig_tx_drx_sending_req" );
  
  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_FLUSHING:
    case DRX_NOT_READY:
      uart_data->drx->sending_state = UART_DRX_SENDING;
      break;

    default:
      TRACE_ERROR( "SIG_TX_DRX_SENDING_REQ unexpected" );
      break;
  }
} /* sig_tx_drx_sending_req() */



/*
+------------------------------------------------------------------------------
| Function    : sig_tx_drx_data_sent_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_TX_DRX_DATA_SENT_REQ
|
| Parameters  : rest_data - generic data descriptor of "still to send" data
|                     pos - current position in first rest data buffer
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_tx_drx_data_sent_req ( T_desc2 *rest_data, USHORT pos ) 
{
  T_desc2 *next_desc;
  T_desc2 *desc;

  TRACE_ISIG( "sig_tx_drx_data_sent_req" );

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_DEAD:
      uart_data->drx->sending_state = UART_DRX_NOT_SENDING;
      /*
       * Since the service is dead, free all resources and the rest of data
       */
      drx_free_resources();
      break;

    case DRX_NOT_READY:
      if(uart_data->drx->sending_state EQ UART_DRX_INVALID)
      {
        /*
         * because we are in an invalid sending state, free all resources
         */
        drx_free_resources();
      }
      else
      {
        /*
         * free all data descriptors in front of the remaining data
         */
        desc = uart_data->drx->received_data;
        while((desc NEQ rest_data) && (desc NEQ NULL))
        {
          next_desc = (T_desc2 *)desc->next;           
          MFREE (desc);                               
          desc = next_desc;                            
        }
        /*
         * set received_data descriptor to remaining data, remember position
         */
        uart_data->drx->received_data = desc;
        uart_data->drx->read_pos      = pos;
      }

      uart_data->drx->sending_state = UART_DRX_NOT_SENDING;

      if(uart_data->drx->data_flow EQ UART_FLOW_ENABLED)
      {
        if(uart_data->drx->received_data)
        {
          /*
           * data flow is enabled and there is more data to send
           */
          sig_drx_tx_data_available_ind(uart_data->drx->dlc_instance,
                                        uart_data->drx->received_data, 
                                        uart_data->drx->read_pos);
        }
        else 
          /*
           * data flow is enabled but there is nothing more to send,
           * so do positive flow control
           */
#ifdef DTILIB
          if( uart_data->drx->dti_drx_state NEQ DTI_CLOSED )
          {
            SET_STATE( UART_SERVICE_DRX, DRX_READY );
#ifdef FLOW_TRACE
            sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
            dti_start(
              uart_hDTI, 
              uart_data->device, 
              UART_DTI_UP_INTERFACE, 
              uart_data->drx->dlc_instance
              );
          }
#else  /* DTILIB */
          if(uart_data->drx->hComm_DRX_UPLINK NEQ VSI_ERROR)
        {
          PALLOC (dti_ready_ind, DTI_READY_IND);
          SET_STATE( UART_SERVICE_DRX, DRX_READY );
          dti_ready_ind->tui  = uart_data->tui_uart;
          dti_ready_ind->c_id = drx_get_channel_id();
#ifdef _SIMULATION_
          dti_ready_ind->op_ack = 0;
#endif /* _SIMULATION_ */
#ifdef FLOW_TRACE
          sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
          PSEND (uart_data->drx->hComm_DRX_UPLINK, dti_ready_ind);
        }
#endif /* DTILIB */
      }
      break;

    case DRX_FLUSHING:
      /*
       * free all data descriptors in front of the remaining data
       */
      desc = uart_data->drx->received_data;
      while((desc NEQ rest_data) && (desc NEQ NULL))
      {
        next_desc = (T_desc2 *)desc->next;           
        MFREE (desc);                               
        desc = next_desc;                            
      }
      /*
       * set received_data descriptor to remaining data, remember position
       */
      uart_data->drx->received_data = desc;
      uart_data->drx->read_pos      = pos;

      uart_data->drx->sending_state = UART_DRX_NOT_SENDING;

      if(uart_data->drx->received_data)
      {
        if(uart_data->drx->data_flow EQ UART_FLOW_ENABLED)
          /*
           * data flow is enabled and there is more data to send
           */
          sig_drx_tx_data_available_ind(uart_data->drx->dlc_instance,
                                        uart_data->drx->received_data, 
                                        uart_data->drx->read_pos);
      }
      else 
#ifdef DTILIB
          if(( uart_data->drx->dti_drx_state NEQ DTI_CLOSED ) &&
              (uart_data->drx->data_flow EQ UART_FLOW_ENABLED))
          {
            SET_STATE( UART_SERVICE_DRX, DRX_READY );
            sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
#ifdef FLOW_TRACE
            sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
            dti_start(
              uart_hDTI, 
              uart_data->device, 
              UART_DTI_UP_INTERFACE, 
              uart_data->drx->dlc_instance
              );
          }
#else  /* DTILIB */
        if((uart_data->drx->hComm_DRX_UPLINK NEQ VSI_ERROR) &&
              (uart_data->drx->data_flow EQ UART_FLOW_ENABLED))
      {
        /*
         * data flow is enabled but there is nothing more to send,
         * so send flush signal and positive flow control
         */
        PALLOC (dti_ready_ind, DTI_READY_IND);
        SET_STATE( UART_SERVICE_DRX, DRX_READY );
        sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
        dti_ready_ind->tui  = uart_data->tui_uart;
        dti_ready_ind->c_id = drx_get_channel_id();
#ifdef _SIMULATION_
        dti_ready_ind->op_ack = 0;
#endif /* _SIMULATION_ */
#ifdef FLOW_TRACE
        sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
        PSEND (uart_data->drx->hComm_DRX_UPLINK, dti_ready_ind);
      }
#endif /* DTILIB */
      else
      {
        /*
         * data flushed
         */
        SET_STATE( UART_SERVICE_DRX, DRX_NOT_READY );
#ifdef DTILIB
        dti_stop(
          uart_hDTI, 
          uart_data->device, 
          UART_DTI_UP_INTERFACE, 
          uart_data->drx->dlc_instance
          );
#endif /* DTILIB */
        sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
      }
      break;

    default:
      TRACE_ERROR( "SIG_TX_DRX_DATA_SENT_REQ unexpected" );
      break;
  }
} /* sig_tx_drx_data_sent_req() */



#ifdef DTILIB

/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_disconnected_mode_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_DISCONNECTED_MODE_REQ
|
| Parameters  : none
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_disconnected_mode_req () 
{ 
  TRACE_ISIG( "sig_ker_drx_disconnected_mode_req" );
  
  uart_data->drx->dti_drx_state = DTI_CLOSED;

  switch(GET_STATE( UART_SERVICE_DRX) )
  {
    case DRX_READY:
      SET_STATE( UART_SERVICE_DRX, DRX_NOT_READY );
      break;
    case DRX_NOT_READY:
      break;
    default:
      TRACE_ERROR( "SIG_KER_DRX_DISCONNECTED_MODE_REQ unexpected" );
      break;
  }

} /* sig_ker_drx_disconnected_mode_req() */
    
  

/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_set_dtilib_peer_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_SET_DTI_PEER_REQ
|               which is used to inform the service DRX that from now on it
|               needs to communicate with a (new) peer
|
| Parameters  : -
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_set_dtilib_peer_req ()
{
  TRACE_ISIG( "sig_ker_drx_set_dtilib_peer_req" );

  uart_data->drx->dti_drx_state = DTI_IDLE;

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
    case DRX_NOT_READY:
      /*
       * signal availability to higher layer if currently not sending
       */
      if((uart_data->drx->received_data EQ NULL)          &&
         (uart_data->drx->data_flow EQ UART_FLOW_ENABLED) &&
         (uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING))
      {
        SET_STATE( UART_SERVICE_DRX, DRX_READY );
#ifdef FLOW_TRACE
        sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
        dti_start(
          uart_hDTI,
          uart_data->device,
          UART_DTI_UP_INTERFACE,
          uart_data->drx->dlc_instance
          );
      }
      else
      {
        SET_STATE( UART_SERVICE_DRX, DRX_NOT_READY );
        dti_stop(
          uart_hDTI, 
          uart_data->device, 
          UART_DTI_UP_INTERFACE,
          uart_data->drx->dlc_instance
          );
      }
      break;

    case DRX_FLUSHING:
    case DRX_DEAD:
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_SET_DTI_PEER_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_set_dtilib_peer_req() */


#else  /* DTILIB */

/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_set_dti_peer_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_SET_DTI_PEER_REQ
|               which is used to inform the service DRX that from now on it
|               needs to communicate with a (new) peer
|
| Parameters  : tui_peer    - transmission unit identifier of peer
|               peer_handle - VSI handle of peer (channel has to be opened)
|               c_id        - channel identifier of peer
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_set_dti_peer_req (USHORT tui_peer, 
                                          T_HANDLE peer_handle, 
                                          UBYTE c_id) 
{
  USHORT i,pos;

  TRACE_ISIG( "sig_ker_drx_set_dti_peer_req" );

  /*
   * set new vsi handle and
   */
  uart_data->drx->hComm_DRX_UPLINK = peer_handle;

  /* 
   * search position in table
   */
  pos = UART_INSTANCES * UART_MAX_NUMBER_OF_CHANNELS;
  for(i = 0; i < pos; i++)
  {
    if((uart_cid_table[i].drx EQ uart_data->drx) ||
       (uart_cid_table[i].c_id EQ c_id))
    {
      pos = i;
    }
  }

  if(pos < (UART_INSTANCES * UART_MAX_NUMBER_OF_CHANNELS))
  {
    /*
     * valid position in table, update entry
     */
    uart_cid_table[pos].c_id      = c_id;
    uart_cid_table[pos].drx       = uart_data->drx;
    uart_cid_table[pos].uart_data = uart_data;
  }
  else
  {
    /*
     * create new entry in table
     */
    for(i = 0; i < UART_INSTANCES * UART_MAX_NUMBER_OF_CHANNELS; i++)
    {
      if(uart_cid_table[i].dtx EQ NULL)
      {
        /*
         * free space found, insert data
         */ 
        uart_cid_table[i].c_id      = c_id;
        uart_cid_table[i].drx       = uart_data->drx;
        uart_cid_table[i].uart_data = uart_data;
        break;
      }
    }
  }

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
    case DRX_NOT_READY:
      /*
       * signal availability to higher layer if currently not sending
       */
      if((uart_data->drx->received_data EQ NULL)          &&
         (uart_data->drx->data_flow EQ UART_FLOW_ENABLED) &&
         (uart_data->drx->sending_state EQ UART_DRX_NOT_SENDING))
      {
        PALLOC (dti_ready_ind, DTI_READY_IND);
        SET_STATE( UART_SERVICE_DRX, DRX_READY );
        dti_ready_ind->tui  = uart_data->tui_uart;
        dti_ready_ind->c_id = drx_get_channel_id();
#ifdef _SIMULATION_
        dti_ready_ind->op_ack = 0;
#endif /* _SIMULATION_ */
#ifdef FLOW_TRACE
        sndcp_trace_flow_control(FLOW_TRACE_UART, FLOW_TRACE_DOWN, FLOW_TRACE_TOP, TRUE);
#endif /* FLOW_TRACE */
        PSEND (uart_data->drx->hComm_DRX_UPLINK, dti_ready_ind);
      }
      else
      {
        SET_STATE( UART_SERVICE_DRX, DRX_NOT_READY );
      }
      break;

    case DRX_FLUSHING:
    case DRX_DEAD:
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_SET_DTI_PEER_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_set_dti_peer_req() */

#endif /* DTILIB */


/*
+------------------------------------------------------------------------------
| Function    : sig_ker_drx_flush_req
+------------------------------------------------------------------------------
| Description : Handles the internal signal SIG_KER_DRX_FLUSH_REQ which is used
|               to trigger flushing of the service.
|
| Parameters  : no parameters
|
+------------------------------------------------------------------------------
*/
GLOBAL void sig_ker_drx_flush_req () 
{
  TRACE_ISIG( "sig_ker_drx_flush_req" );

  switch( GET_STATE( UART_SERVICE_DRX ) )
  {
    case DRX_READY:
      sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
      break;

    case DRX_NOT_READY:
      if((uart_data->drx->received_data) &&
         (uart_data->drx->sending_state NEQ UART_DRX_INVALID))
      {
        SET_STATE( UART_SERVICE_DRX, DRX_FLUSHING );
      }
      else
      {
        sig_any_ker_flushed_ind(uart_data->drx->dlc_instance);
      }
      break;

    case DRX_FLUSHING:
      break;

    default:
      TRACE_ERROR( "SIG_KER_DRX_FLUSH_REQ unexpected" );
      break;
  }
} /* sig_ker_drx_flush_req() */