www.pudn.com > drivers.rar > dma_handle_message.c
/**
* @file dma_handle_message.c
*
* DMA handle_msg function, which is called when the SWE
* receives a new message in its mailbox.
*
* @author ()
* @version 0.1
*/
/*
* History:
*
* Date Author Modification
* -------------------------------------------------------------------
* 7/2/2003 () Create.
*
* (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
*/
#include "rv/rv_general.h"
#include "rvf/rvf_api.h"
#include "rvm/rvm_gen.h"
#include "rvm/rvm_use_id_list.h"
#include "rvm/rvm_ext_use_id_list.h"
#include "dma/dma_env.h"
#include "dma/dma_api.h"
#include "dma/dma_message.h"
#include "dma/dma_i.h"
#ifdef _WINDOWS
#include "dma/pc/dma_pc_i.h"
#endif //_WINDOWS
extern T_DMA_CHANNEL_ARRAY dma_channel_array [DMA_MAX_NUMBER_OF_CHANNEL];
extern T_DMA_QUEUE_ARRAY dma_queue_array [DMA_MAX_QUEUED_REQUESTS];
extern UINT8 dma_function_status [DMA_MAX_NUMBER_OF_CHANNEL];
/**
* Called every time the SW entity is in WAITING state
* and get a new message in its mailbox.
*
* The message in parameter is freed in this function.
*
* @param msg_p Pointer on the header of the message.
* @return RVM_OK or RVM_MEMORY_ERR.
*/
T_RVM_RETURN dma_handle_message (T_RV_HDR *msg_p)
{
T_DMA_RET dma_status = DMA_RESERVE_OK;
//UINT8 dma_return_path_set = DMA_ZERO;
extern T_DMA_ENV_CTRL_BLK *dma_env_ctrl_blk_p;
/* Check if initialization has been correctly done */
if (dma_env_ctrl_blk_p == 0)
{
DMA_SEND_TRACE("DMA Initialization is not yet done or failed", DMA_TRACE_LEVEL);
return RV_INTERNAL_ERR;
}
else
{
switch (msg_p->msg_id)
{
case DMA_RESERVE_CHANNEL_REQ_MSG:
{
T_DMA_RESERVE_CHANNEL_REQ_MSG* dma_reserve_channel_req_msg_p =
(T_DMA_RESERVE_CHANNEL_REQ_MSG*) msg_p;
/* Check if parameters have a valid value */
if ((dma_queue_spec_prio_check
(dma_reserve_channel_req_msg_p->queue,
dma_reserve_channel_req_msg_p->specific,
dma_reserve_channel_req_msg_p->sw_priority)
!= DMA_PARAMS_OK) ||
((dma_reserve_channel_req_msg_p->specific==DMA_CHAN_SPECIFIC)&&
(dma_channel_check(dma_reserve_channel_req_msg_p->channel) !=
DMA_PARAMS_OK)))
{
/*
send a message back to the client informing that
the parameter was not correct
*/
dma_send_status_message(dma_reserve_channel_req_msg_p->channel,
DMA_INVALID_PARAMETER,
dma_reserve_channel_req_msg_p->return_path);
}
else
{
dma_internal_reserve_chan (msg_p);
}
}
break;
case DMA_REMOVE_FROM_QUEUE_REQ_MSG:
{
dma_internal_remove_from_queue (msg_p);
}
break;
case DMA_SET_CHANNEL_PARAMETERS_REQ_MSG:
{
T_DMA_SET_CHANNEL_PARAMETERS_REQ_MSG *dma_set_channel_parameters_req_msg_p =
(T_DMA_SET_CHANNEL_PARAMETERS_REQ_MSG*) msg_p;
/* Check if the channel is already reserved */
if (dma_function_status[dma_set_channel_parameters_req_msg_p->channel] >=
DMA_FUNCTION_RESERVED)
{
/* Check the given parameters */
if (dma_channel_check(
dma_set_channel_parameters_req_msg_p->channel) ==
DMA_PARAMS_OK)
{
if (dma_check_channel_info(
&dma_set_channel_parameters_req_msg_p->channel_info)
!= DMA_PARAMS_OK)
{
dma_send_status_message
(dma_set_channel_parameters_req_msg_p->channel,
DMA_INVALID_PARAMETER,
dma_channel_array[dma_set_channel_parameters_req_msg_p->
channel].return_path);
DMA_SEND_TRACE ("DMA Illegal channel information used",\
DMA_TRACE_LEVEL);
}
else
{
dma_internal_set_chan_params (msg_p);
}
}
}
else
{
/*
when a wrong sequence of API calls is done, no message is send back!
There is no return path known.
*/
DMA_SEND_TRACE ("DMA wrong sequence of API calls",\
DMA_TRACE_LEVEL);
}
}
break;
case DMA_ENABLE_TRANSFER_REQ_MSG:
{
/* Create a pointer to the message information */
T_DMA_ENABLE_TRANSFER_REQ_MSG* dma_enable_transfer_req_p =
(T_DMA_ENABLE_TRANSFER_REQ_MSG*) msg_p;
/* Check if channel is used (and thus has been assigned) */
if (dma_channel_array[dma_enable_transfer_req_p->channel].specific !=
DMA_CHANNEL_POS_FREE)
{
/* check if parameters have been set up */
if (dma_function_status[dma_enable_transfer_req_p->channel] >=
DMA_FUNCTION_PARAMS_SET_UP)
{
if (dma_channel_check (dma_enable_transfer_req_p->channel) !=
DMA_INVALID_PARAMETER)
/* when an illegal channel number is provided,
no message is send back ! */
{
DMA_SEND_TRACE_PARAM ("DMA Transfer started channel ",
dma_enable_transfer_req_p->channel, DMA_TRACE_LEVEL);
dma_status = DMA_CHANNEL_ENABLED;
dma_send_status_message (dma_enable_transfer_req_p->channel,
dma_status,
dma_channel_array[dma_enable_transfer_req_p->
channel].return_path);
f_dma_channel_enable (dma_enable_transfer_req_p->channel);
}
}
else
{
DMA_SEND_TRACE("DMA Illegal sequence of API call",
DMA_TRACE_LEVEL);
/* no message send back, as there is no known return path */
}
}
}
break;
case DMA_RELEASE_CHANNEL_REQ_MSG:
{
/* Create a pointer to the message information */
T_DMA_RELEASE_CHANNEL_REQ_MSG* dma_release_channel_req_p = (T_DMA_RELEASE_CHANNEL_REQ_MSG*) msg_p;
if (dma_channel_check (dma_release_channel_req_p->channel) !=
DMA_INVALID_PARAMETER)
/* when an illegal channel number is provided,
no message is send back ! */
{
dma_internal_rel_chan (dma_release_channel_req_p->channel);
}
}
break;
default:
{
/* Unknow message has been received */
DMA_SEND_TRACE("DMA Message received unknown",DMA_TRACE_LEVEL);
}
}
}
/* Free message */
if (rvf_free_buf(msg_p) != RVF_OK)
{
DMA_SEND_TRACE("DMA Unable to free message",
DMA_TRACE_LEVEL);
return RVM_MEMORY_ERR;
}
return RVM_OK;
}