📄 tmmsg.c
字号:
/*----------------------------------------------------------------------------
COPYRIGHT (c) 1995 by Philips Semiconductors
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED AND COPIED IN
ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH A LICENSE AND WITH THE
INCLUSION OF THE THIS COPY RIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES
OF THIS SOFTWARE MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
PERSON. THE OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor.
PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE
ON PLATFORMS OTHER THAN THE ONE ON WHICH THIS SOFTWARE IS FURNISHED.
----------------------------------------------------------------------------*/
/*
HISTORY
#define TR Tilakraj Roy
960530 TR Created
960815 TR Pulled in from tmchnl sources
960827 TR Removed all references to tmclnt
*/
/*----------------------------------------------------------------------------
SYSTEM INCLUDE FILES
----------------------------------------------------------------------------*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <vxdwraps.h>
#undef MSG_DEBUG
/*----------------------------------------------------------------------------
DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "vxstd.h"
#include "vxwin.h"
#include "vxdbg.h"
#include "tmwincom.h"
#include "tmman32.h"
#include "tmif.h"
#include "tmshare.h"
#include "tmmsg.h"
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
STATUS msgOnMsgSend (
PVOID pvContext ) /* handle to the task */
{
return TMOK;
}
/*
msgOnRecv
Task packet receive advise notification
DWORD dwHandle - Handle to the open message|stream|buffer channel
*/
STATUS msgOnMsgRecv (
PVOID pvContext, /* handle to the task */
PVOID pPacket ) /* pointer to the TMSTD_PACKET structure */
{
PTMMSG_OBJECT this = ( PTMMSG_OBJECT)pvContext;
TMIF_ADVISORY_REQUEST Advise;
STATUS Status;
Advise.dwMessage = TMMAN_ADVISE_MSG_RECV;
Advise.dwObjHandle = (DWORD)this;
Advise.pContext = this->pContext;
Advise.dwCallback = this->Callback;
Advise.Packet = *(PTMSTD_PACKET)pPacket;
DP( 4,"TM:[ADVQ|CM:%x|A0:%x|A1:%x|A2:%x|A3:%x|A4:%x]\n",
Advise.Packet.dwCommand,
Advise.Packet.dwArgument[0],
Advise.Packet.dwArgument[1],
Advise.Packet.dwArgument[2],
Advise.Packet.dwArgument[3],
Advise.Packet.dwArgument[4] );
#ifdef MSG_DEBUG
if ( ((PTMSTD_PACKET)pPacket)->dwArgument[4] != this->PacketRecvCounter )
{
DP(0,"TM:msgOnMsgRecv:Packet Expected[%x]:Received[%x]:ERROR\n",
this->PacketRecvCounter, ((PTMSTD_PACKET)pPacket)->dwArgument[4] );
}
#endif
if ( ( Status = clntAdvise ( (DWORD)this->pClient, &Advise ) ) != TMOK )
{
DP(0,"TM:msgOnMsgRecv:clntAdvise:FAIL[%x]\n", Status );
DP( 7,"TM:[ADVQ|CM:%x|A0:%x|A1:%x|A2:%x|A3:%x|A4:%x:FAIL]\n",
Advise.Packet.dwCommand,
Advise.Packet.dwArgument[0],
Advise.Packet.dwArgument[1],
Advise.Packet.dwArgument[2],
Advise.Packet.dwArgument[3],
Advise.Packet.dwArgument[4] );
return Status;
}
this->PacketRecvCounter++;
return TMOK;
}
/*
msgInit
Initialize all the channel data structures
*/
STATUS msgmCreate (
PVOID pvContainer,
DWORD MessageCount, /* number of message queues that will be supported */
PVOID *ppMsgMgr )
{
PTMMSG_MGR_OBJECT this;
STATUS Status;
DWORD IdxMessage;
if ( ( this = (PTMMSG_MGR_OBJECT)vxdMalloc (
sizeof ( TMMSG_MGR_OBJECT ) ) ) == NULL )
{
Status = TM_STATUS ( TMMSG_ERR_MGROBJALLOCFAIL );
goto msgmCreate_fail1;
}
if ( ( this->pMessageTab =
(PVOID)vxdMalloc ( sizeof ( PVOID ) * MessageCount ) ) == NULL )
{
Status = TM_STATUS ( TMMSG_ERR_OBJPTRTABMALLOCFAIL );
goto msgmCreate_fail2;
}
for ( IdxMessage = 0 ; IdxMessage < MessageCount ; IdxMessage ++ )
{
this->pMessageTab[IdxMessage] = NULL;
}
this->Flags = 0;
this->Size = sizeof (TMMSG_MGR_OBJECT);
this->pContainer = pvContainer;
this->MessageCount = MessageCount;
this->AllocatedCount = 0;
FlagSet ( this->Flags, TMMSG_MGR_FLAGINITIALIZED);
*ppMsgMgr = this;
return TMOK;
/*
msgmCreate_fail3:
vxdFree ( this->pMessageTab );
*/
msgmCreate_fail2:
vxdFree ( this );
msgmCreate_fail1:
return Status;
}
/*
msgmOpen
Opens a bidirectional message channel between the host and the DSP.
It uses two channel objects, one for sending and one for receiving
*/
STATUS msgmCreateMsg (
PVOID pvObject,
PVOID pMsgCreateArg,
PVOID *ppMsg )
{
PTMMSG_MGR_OBJECT this = (PTMMSG_MGR_OBJECT)pvObject;
PTMMSG_OBJECT pMessage;
PTMIF_STRUCT_MSGCREATE pMsgCreate =
(PTMIF_STRUCT_MSGCREATE)pMsgCreateArg;
DWORD dwIdx;
STATUS Status;
if ( this->AllocatedCount > this->MessageCount )
{
return TM_STATUS(TMMSG_ERR_ALLOCMSGOBJFAIL);
}
if ( ( pMessage = vxdMalloc ( sizeof ( TMMSG_OBJECT ) * 1 ) ) == NULL )
{
return TM_STATUS ( TMMSG_ERR_OBJALLOCFAIL );
}
if ( pMsgCreate->ChannelID == TMMAN_DEFAULT )
{
/* choose the next available message Q */
/*
message channel 0 is not used for legacy reasons
tmtask uses channel 0 & 1 without using messages above it
since there is a one to one mapping between messages and
channels , the next TMMAN_DEFAULT selects channel 0 and
channel allocation fails
*/
for ( dwIdx = 1 ; dwIdx < this->MessageCount ; dwIdx ++ )
{
if ( ! this->pMessageTab[dwIdx] )
{
this->pMessageTab[dwIdx] = pMessage;
this->AllocatedCount++;
FlagSet ( pMessage->Flags, TMMSG_MSG_FLAGALLOCATED );
pMessage->ID = dwIdx;
break;
}
}
/* mo more queues available */
if ( dwIdx == this->MessageCount )
{
Status = TM_STATUS(TMMSG_ERR_OUTOFMESSAGES);
goto msgmOpen_fail1;
}
}
else /* use the id to offset into message queues */
{
if ( pMsgCreate->ChannelID > this->MessageCount )
{
Status = TM_STATUS(TMMSG_ERR_IDOUTOFLIMIT);
goto msgmOpen_fail1;
}
else /*use the ID to offset into the Message Q array */
{
if ( ! this->pMessageTab[pMsgCreate->ChannelID] )
{
this->pMessageTab[pMsgCreate->ChannelID] = pMessage;
this->AllocatedCount++;
FlagSet ( pMessage->Flags, TMMSG_MSG_FLAGALLOCATED );
pMessage->ID = pMsgCreate->ChannelID;
}
else /* this channel has been already allocated */
{
Status = TM_STATUS ( TMMSG_ERR_MSGALREADYALLOCATED );
goto msgmOpen_fail1;
}
}
}
pMessage->Size = sizeof (TMMSG_OBJECT);
pMessage->pContainer = this->pContainer;
pMessage->pContext = (PVOID)pMsgCreate->CallbackContext;
pMessage->Callback = pMsgCreate->CallbackFunction;
pMessage->pClient = (PVOID)pMsgCreate->ClientHandle;
pMessage->QueueSize = pMsgCreate->Slots;
pMessage->PacketSendCounter = 0;
pMessage->PacketRecvCounter = 0;
pMsgCreate->MsgHandle = (DWORD)pMessage;
/*
every message channel can send and receive messages
we use two channels - one for sending and one for receiving since
channels are unidirectional
*/
if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(this->pContainer),
TMCHNL_DIRECTION_RECV, ( pMessage->ID * 2), pMessage->QueueSize,
(PVOID)msgOnMsgRecv, pMessage, &pMessage->pChnlRecv ) ) != TMOK )
{
goto msgmOpen_fail2;
}
if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(this->pContainer),
TMCHNL_DIRECTION_SEND, ((pMessage->ID * 2) + 1), pMessage->QueueSize,
(PVOID)msgOnMsgSend, pMessage, &pMessage->pChnlSend ) ) != TMOK )
{
goto msgmOpen_fail3;
}
*ppMsg = pMessage;
return TMOK;
/*
msgmOpen_fail4:
chnlDestroy ( pMessage->pChnlSend );
*/
msgmOpen_fail3:
chnlDestroy ( pMessage->pChnlRecv );
msgmOpen_fail2:
this->AllocatedCount--;
this->pMessageTab[pMessage->ID] = NULL;
FlagClr ( pMessage->Flags, TMMSG_MSG_FLAGALLOCATED );
msgmOpen_fail1:
vxdFree ( pMessage );
return Status;
}
STATUS msgDestroy ( PVOID pMsg )
{
PTMMSG_OBJECT this = (PTMMSG_OBJECT)pMsg;
STATUS Status;
if ( ( Status = msgValidateHandle ( this )) != TMOK )
{
return Status;
}
chnlDestroy ( this->pChnlSend );
chnlDestroy ( this->pChnlRecv );
((PTMMSG_MGR_OBJECT)GetMsgMgrObject(this->pContainer))->AllocatedCount--;
((PTMMSG_MGR_OBJECT)GetMsgMgrObject(this->pContainer))->pMessageTab[this->ID] = NULL;
this->Size = 0;
FlagClr ( this->Flags, TMMSG_MSG_FLAGALLOCATED );
vxdFree ( this );
return TMOK;
}
STATUS msgmDestroy (PVOID pMsgMgr )
{
PTMMSG_MGR_OBJECT this = (PTMMSG_MGR_OBJECT)pMsgMgr;
FlagClr ( this->Flags, TMMSG_MGR_FLAGINITIALIZED);
this->Size = 0;
vxdFree ( this->pMessageTab );
vxdFree ( this );
return TMOK;
}
STATUS msgSend ( PVOID pMsg, PVOID pvPacket )
{
PTMMSG_OBJECT this = (PTMMSG_OBJECT)pMsg;
STATUS Status;
if ( ( Status = msgValidateHandle ( pMsg ) ) != TMOK )
{
return Status;
}
#ifdef MSG_DEBUG
((PTMSTD_PACKET)pvPacket)->dwArgument[4] = this->PacketSendCounter;
#endif
if ( ( Status = chnlPacketSend ( this->pChnlSend,
pvPacket )) != TMOK )
{
return Status;
}
this->PacketSendCounter++;
return TMOK;
}
STATUS msgValidateHandle ( PVOID pMsg )
{
PTMMSG_OBJECT this = (PTMMSG_OBJECT)pMsg;
if ( ! pMsg )
goto msgValidateHandle_fail;
if ( this->Size != sizeof(TMMSG_OBJECT) )
goto msgValidateHandle_fail;
if ( ! FlagGet ( this->Flags, TMMSG_MSG_FLAGALLOCATED ) )
goto msgValidateHandle_fail;
return TMOK;
msgValidateHandle_fail :
DP(0,"TM:msgValidateHandle:pMsg[%x]:FAIL\n",pMsg);
return TMMSG_ERR_INVALIDHANDLE;
}
STATUS msgmDestroyMsgByClnt ( PVOID pMsgMgr, DWORD dwClientHandle )
{
PTMMSG_MGR_OBJECT this = ( PTMMSG_MGR_OBJECT )pMsgMgr;
DWORD IdxMsg;
for ( IdxMsg = 0 ; IdxMsg < this->MessageCount ; IdxMsg ++ )
{
if ( ! this->pMessageTab[IdxMsg] )
continue;
if ( ((PTMMSG_OBJECT)this->pMessageTab[IdxMsg])->pClient != (PVOID)dwClientHandle )
continue;
msgDestroy ( this->pMessageTab[IdxMsg] );
}
return TMOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -