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

📄 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
	960913	TR	Pulled in from host sources & got rid of client dependencies
*/

/*----------------------------------------------------------------------------
          SYSTEM INCLUDE FILES
----------------------------------------------------------------------------*/
#include "tmman.h"
#undef MSG_DEBUG
/*----------------------------------------------------------------------------
          DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "tmshare.h"
#include "tmmsg.h"
#include "stdio.h"
#include "AppModel.h"


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;
	STATUS	Status;

#ifdef MSG_DEBUG
	if ( ((PTMSTD_PACKET)pPacket)->dwArgument[4] != this->PacketRecvCounter )
	{
		DT(0,("TM:msgOnMsgRecv:Packet Expected[%x]:Received[%x]:ERROR\n", 
			this->PacketRecvCounter, ((PTMSTD_PACKET)pPacket)->dwArgument[4] ));
	}
#endif
	Status = ((TMMAN_MSGONRECV)this->Callback) (this->pContext, pPacket );
	this->PacketRecvCounter++;
	return Status;
}


/* 
	msgInit
	Initialize all the channel data structures 
*/
STATUS	msgmCreate (   PVOID pvContainer, DWORD MessageCount, PVOID *ppMsgMgr )
{
	PTMMSG_MGR_OBJECT	this;
	STATUS				Status;
	DWORD				MessageIdx;

	if ( ( this = (PTMMSG_MGR_OBJECT)malloc ( 
		sizeof ( TMMSG_MGR_OBJECT ) * 1 ) ) == NULL )
	{	
		DT(0,( "msgmCreate:MessageManagerObjectMalloc:FAIL\n"));
		Status = TM_STATUS ( TMMSG_ERR_MGROBJMALLOCFAIL );
		goto	msgmCreate_fail1;

	}

	if ( ( this->pMessageTab = 
		(PVOID)malloc ( sizeof ( PVOID ) * MessageCount ) ) == NULL )
	{
		DT(0, ("msgmCreate:ObjectPointerArrayMalloc:FAIL\n"));
		Status = TM_STATUS ( TMMSG_ERR_OBJPTRTABMALLOCFAIL );
		goto	msgmCreate_fail2;

	}

	this->Flags = 0;
	this->Size = sizeof (TMMSG_MGR_OBJECT);
	this->pContainer = pvContainer;
	this->MessageCount = MessageCount;
	this->AllocatedCount = 0;
	FlagSet ( this->Flags, TMMSG_MGR_FLAGINITIALIZED);

	for ( MessageIdx = 0 ; MessageIdx < MessageCount ; MessageIdx ++ )
	{
		this->pMessageTab[MessageIdx] = NULL;
	}


	*ppMsgMgr = this;
	return TMOK;

msgmCreate_fail3:
	free ( this->pMessageTab );
msgmCreate_fail2:
	free ( 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;
	PTMMAN_MESSAGE_DESC	pMsgCreate =
		(PTMMAN_MESSAGE_DESC)pMsgCreateArg;
	DWORD dwIdx;
	STATUS	Status;

	if ( this->AllocatedCount > this->MessageCount )
	{
		DT(0, ("msgmCreateMsg:AllocatedCount < TMMSG_MAX_COUNT:FAIL\n"));
		return TM_STATUS(TMMSG_ERR_ALLOCMSGOBJFAIL);
	}

	if ( ( pMessage = (PTMMSG_OBJECT)malloc ( 
		sizeof ( TMMSG_OBJECT ) * 1 ) ) == NULL )
	{
		DT(0, ("msgmCreateMsg:ObjectAlloc:FAIL\n"));
		return TM_STATUS ( TMMSG_ERR_OBJALLOCFAIL );
	}

	if ( pMsgCreate->ID == TMMAN_DEFAULT )
	{
		/* choose the next available message Q */
		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 )
		{
			DT(0, ("msgmCreateMsg:OutOfMessages:FAIL\n"));
			Status = TM_STATUS(TMMSG_ERR_OUTOFMESSAGES);
			goto	msgmOpen_fail1;
		}
	}
	else /* use the id to offset into message queues */
	{
		if ( pMsgCreate->ID > this->MessageCount )
		{
			DT(0, ("msgmCreateMsg:IDOutOfLimit:FAIL\n"));
			Status = TM_STATUS(TMMSG_ERR_IDOUTOFLIMIT);
			goto	msgmOpen_fail1;
		}
		else /*use the ID to offset into the Message Q array */
		{
		
			if ( ! this->pMessageTab[pMsgCreate->ID] )
			{
				this->pMessageTab[pMsgCreate->ID] = pMessage;
				this->AllocatedCount++;
				FlagSet ( pMessage->Flags, TMMSG_MSG_FLAGALLOCATED );
				pMessage->ID = pMsgCreate->ID;
			}
			else /* this channel has been already allocated */
			{
				DT(0, ("msgmCreateMsg:MessageAlreadyAllocated:FAIL[%x]\n",
					pMsgCreate->ID ));
				Status = TM_STATUS ( TMMSG_ERR_MSGALREADYALLOCATED );
				goto	msgmOpen_fail1;
			}

		}
	}

	pMessage->Size = sizeof (TMMSG_OBJECT);
	pMessage->pContainer = this->pContainer;
	pMessage->pContext = (PVOID)pMsgCreate->pContext;
	pMessage->Callback = pMsgCreate->Callback;
	pMessage->QueueSize = pMsgCreate->Slots;
	pMessage->PacketSendCounter = 0;
	pMessage->PacketRecvCounter = 0;
    pMessage->InmsgSend = 0;

	/*	
		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(), 
		TMCHNL_DIRECTION_SEND, ( pMessage->ID * 2), pMessage->QueueSize, 
		(PVOID)msgOnMsgSend, pMessage, &pMessage->pChnlSend ) ) != TMOK )
	{
		goto msgmOpen_fail2;
	}

	if ( ( Status = chnlmCreateChnl ( GetChnlMgrObject(), 
		TMCHNL_DIRECTION_RECV, ((pMessage->ID * 2) + 1), pMessage->QueueSize, 
		(PVOID)msgOnMsgRecv, pMessage, &pMessage->pChnlRecv ) ) != TMOK )
	{
		goto msgmOpen_fail3;
	}

	
	*ppMsg = pMessage;

	return TMOK;
/*
msgmOpen_fail4:
	chnlDestroy  ( pMessage->pChnlRecv );
*/
msgmOpen_fail3:
	chnlDestroy  ( pMessage->pChnlSend );

msgmOpen_fail2:
	this->AllocatedCount--;
	FlagClr ( pMessage->Flags, TMMSG_MSG_FLAGALLOCATED );
	
msgmOpen_fail1:
	free ( 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 );

	this->Size = 0;

	((PTMMSG_MGR_OBJECT)GetMsgMgrObject())->AllocatedCount--;
	((PTMMSG_MGR_OBJECT)GetMsgMgrObject())->pMessageTab[this->ID] = NULL;
	
	FlagClr ( this->Flags, TMMSG_MSG_FLAGALLOCATED );

	free ( this );

	return TMOK;

}

STATUS	msgmDestroy (PVOID pMsgMgr )
{
	PTMMSG_MGR_OBJECT	this = (PTMMSG_MGR_OBJECT)pMsgMgr;
	this->Size = 0;
	FlagClr ( this->Flags, TMMSG_MGR_FLAGINITIALIZED);
	free ( this->pMessageTab );
	free ( this );
	return TMOK;
}



STATUS	msgSend ( PVOID pMsg, PVOID pvPacket ) 
{
	PTMMSG_OBJECT		this = (PTMMSG_OBJECT)pMsg;
	PTMSTD_PACKET	pPacket = (PTMSTD_PACKET)pvPacket;

	STATUS	Status = TMOK;

	AppModel_suspend_scheduling();	if ( ( Status = msgValidateHandle ( pMsg ) ) != TMOK )
	{
		goto msgSend_exit;
	}

#ifdef MSG_DEBUG
	((PTMSTD_PACKET)pvPacket)->dwArgument[4] = this->PacketSendCounter;
	
#endif
	if ( this->InmsgSend )
	{
		DT( 0,("TM:msgSend:ReEntered:WARNING\n" ));
	}
	this->InmsgSend++;

	if ( ( Status = chnlPacketSend ( this->pChnlSend, 
		pvPacket )) != TMOK )
	{
		goto msgSend_exit;
	}
	this->PacketSendCounter++;

msgSend_exit:
	this->InmsgSend--;
	/*dbgOutTrace( pDBG,"tmman:msgSend:Exit\n");	*/
	AppModel_resume_scheduling();	return Status;
}


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 :
	DT(0, ("tmman:msgValidateHandle:FAIL[%x]\n",pMsg));
	return TMMSG_ERR_INVALIDHANDLE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -