⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmmsg.c

📁 wince host 和 target PCI驱动程序
💻 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 + -