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

📄 tmbuffer.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
	961205	TR	Pulled in from tmmsg sources

	COMMENTS
	This file manages the Scatter Gather Buffers required for doing 
	page locked dma.
*/

/*----------------------------------------------------------------------------
          SYSTEM INCLUDE FILES
----------------------------------------------------------------------------*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <vxdwraps.h>

/*----------------------------------------------------------------------------
          DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "vxstd.h"
#include "vxwin.h"
#include "vxdbg.h"
#include "tmwincom.h"
#include "tmhd.h"

#include "tmman32.h"
#include "tmif.h"

#include "tmshare.h"
#include "tmbuffer.h"



#pragma VxD_LOCKED_CODE_SEG
#pragma	VxD_LOCKED_DATA_SEG


/* 
	buffermCreate
	Create the buffer manager object and allocates entries for storing
	buffer objects
*/
STATUS	buffermCreate ( PVOID pvContainer, DWORD dwBufferObjectCount,
	PVOID *ppvObject )
{
	PTMBUFFER_MGR_OBJECT	this;
	DWORD	dwIdxBuffer;
	STATUS	Status;

	if ( *ppvObject )
	{
		this = *ppvObject;
		this->Flags = 0;
	}
	else
	{
		if ( ( this = vxdMalloc ( sizeof ( TMBUFFER_MGR_OBJECT ) ) ) == NULL )
		{
			Status =  TM_STATUS ( TMBUFFER_ERR_MGROBJALLOCFAIL );
			goto	buffermCreate_fail1;

		}
		this->Flags = 0;
		FlagSet ( this->Flags, TMBUFFER_FLAG_MGRDYNAMICOBJ);
	}

	if ( ( this->pBufferTab = 
		(PVOID)vxdMalloc ( sizeof ( PVOID ) * dwBufferObjectCount ) ) == NULL )
	{
		Status = TM_STATUS ( TMBUFFER_ERR_OBJPTRTABMALLOCFAIL );
		goto	buffermCreate_fail2;
	}

	for ( dwIdxBuffer = 0 ; dwIdxBuffer < dwBufferObjectCount; dwIdxBuffer ++ )
	{
		this->pBufferTab[dwIdxBuffer] = NULL;
	}

	this->Flags = 0;
	this->Size = sizeof (TMBUFFER_MGR_OBJECT);
	this->pContainer = pvContainer;
	this->BufferCount = dwBufferObjectCount;
	this->AllocatedCount = 0;
	
	FlagSet ( this->Flags, TMBUFFER_FLAG_MGRINITIALIZED);

	*ppvObject = this;
	return TMOK;


buffermCreate_fail2 :
	if ( FlagGet ( this->Flags, TMBUFFER_FLAG_MGRDYNAMICOBJ) )
	{
		vxdFree ( this );
	}
buffermCreate_fail1 :
	return Status;
}


/*
	buffermPrepare
	Page Locks a user supplied buffer, creates a page frame table,
	allocates page locked memory for the page frame table, copies
	the page frame table to the page locked memory, creates a 
	buffer object for storing all this info and returns it.
	
*/
STATUS	buffermPrepare ( PVOID pvObject, PVOID pvBufferPrepare,
	PVOID *ppvObject )
{
	PTMBUFFER_MGR_OBJECT	this = (PTMBUFFER_MGR_OBJECT)pvObject;
	PTMBUFFER_OBJECT		pBuffer;
	PTMIF_STRUCT_BUFFERPREPARE	pBufferPrepare =
		(PTMIF_STRUCT_BUFFERPREPARE)pvBufferPrepare;
	STATUS	Status;
	DWORD	dwIdxPTE, dwIdxBuffer;
	PTMHD_BUFFER_PTEHEADER	pPageTable;

	if ( this->AllocatedCount > this->BufferCount )
	{
		Status = TM_STATUS(TMBUFFER_ERR_MAXOBJCOUNTEXCEEDED);
		goto buffermPrepare_fail1;
	}

	pBuffer = NULL;

	

	// serch for a buffer that is available 
	for ( dwIdxBuffer = 0 ; dwIdxBuffer < this->BufferCount ; dwIdxBuffer ++ )
	{
		if ( this->pBufferTab[dwIdxBuffer] == NULL  )
		{
			if ( ( pBuffer = vxdMalloc ( sizeof ( TMBUFFER_OBJECT ) ) ) == NULL )
			{
				Status = TM_STATUS ( TMBUFFER_ERR_OBJALLOCFAIL );
				goto buffermPrepare_fail1;
			}
			this->pBufferTab[dwIdxBuffer] = pBuffer;
			break;
		}
	}

	if ( dwIdxBuffer == this->BufferCount  )
	{
		Status = TM_STATUS(TMBUFFER_ERR_NOOBJSFREE );
		goto buffermPrepare_fail1;
	}

	pBuffer->Size = sizeof (TMBUFFER_OBJECT);
	pBuffer->pContainer = this->pContainer;
	pBuffer->pClient = (PVOID)pBufferPrepare->ClientHandle;
	this->AllocatedCount++;

	FlagSet ( pBuffer->Flags, TMBUFFER_FLAG_OBJALLOCATED);

	if ( sgBufferLock ( (PVOID)pBufferPrepare->dwAddress, pBufferPrepare->dwSize,
		&pBuffer->pEDDS ) != TRUE )
	{
			Status = TM_STATUS(TMBUFFER_ERR_SGLOCKFAIL);
			goto	buffermPrepare_fail2;
	}
	

	if ( ( Status = shmemAllocate ( GetShMemObject(this->pContainer), 0 ,
		( pBuffer->pEDDS->wUsed  * sizeof ( TMHD_BUFFER_PTE ) ) +
		sizeof ( TMHD_BUFFER_PTEHEADER ), 
		&((PVOID)pBuffer->dwPTELinearAddress),
		&pBuffer->dwPTEPhysicalAddress ) ) != TMOK )
		goto	buffermPrepare_fail3;

	DP(7,"bufferPreapre:PTEHeaderLin[%x]:PTEHeaderPhys[%x]\n",
		pBuffer->dwPTELinearAddress, pBuffer->dwPTEPhysicalAddress );

	// this is what the TM1 side if going to see
	pPageTable = (PTMHD_BUFFER_PTEHEADER)pBuffer->dwPTELinearAddress;
	pPageTable->dwSize = sizeof ( TMHD_BUFFER_PTEHEADER );
	pPageTable->dwBufferSize = pBufferPrepare->dwSize;
	pPageTable->dwCurrentEntry = 0;
	pPageTable->dwCurrentLinearAddress =
		pPageTable->dwLinearAddress = pBufferPrepare->dwAddress;
	pPageTable->dwEntryCount = pBuffer->pEDDS->wUsed;

	// copy the PTE allocated by sgLock to the page locked buffer.
	for ( dwIdxPTE = 0; dwIdxPTE < pBuffer->pEDDS->wUsed ; dwIdxPTE++ )
	{
		pPageTable->Entries[dwIdxPTE].dwPhysicalAddress =
			pBuffer->pEDDS->PageTable[dwIdxPTE].dwPhysAddr;
		pPageTable->Entries[dwIdxPTE].dwSize =
			pBuffer->pEDDS->PageTable[dwIdxPTE].dwSize;
	}

	pBufferPrepare->dwPhysicalAddress = pBuffer->dwPTEPhysicalAddress;
	// this is done by the calling interface TMIF
	//pBufferPrepare->dwBufferHandle = (DWORD)pBuffer;
	

 
	*ppvObject = pBuffer;

	return TMOK;

buffermPrepare_fail3:
	sgBufferUnlock ( pBuffer->pEDDS );

buffermPrepare_fail2:
	this->Size = 0;
	this->AllocatedCount--;
	FlagClr ( pBuffer->Flags, TMBUFFER_FLAG_OBJALLOCATED );
	vxdFree ( pBuffer );

	
buffermPrepare_fail1:
	return Status;
}

STATUS	bufferUnprepare ( PVOID pObject )
{
	PTMBUFFER_OBJECT	this = (PTMBUFFER_OBJECT)pObject;
	PTMBUFFER_MGR_OBJECT	pBufferMgr;
	STATUS	Status;
	DWORD	dwIdxBuffer;

	if ( ( Status = bufferValidateHandle ( this )) != TMOK )
	{
		return Status;
	}

	DP(7,"bufferUnprepare:PTEHeaderLin[%x]:PTEHeaderPhys[%x]\n",
		this->dwPTELinearAddress, this->dwPTEPhysicalAddress );

	pBufferMgr = ((PTMBUFFER_MGR_OBJECT)GetBufferMgrObject(this->pContainer));

	for ( dwIdxBuffer = 0 ; dwIdxBuffer < pBufferMgr->BufferCount ; dwIdxBuffer ++ )
	{
		if ( pBufferMgr->pBufferTab[dwIdxBuffer] == this )
		{
			pBufferMgr->pBufferTab[dwIdxBuffer] = NULL;
			break;
		}
	}

	pBufferMgr->AllocatedCount--;
	this->Size = 0;
	

	shmemFree ( GetShMemObject(this->pContainer), (PEDDS)this->dwPTELinearAddress );

	sgBufferUnlock ( this->pEDDS );

	FlagClr ( this->Flags, TMBUFFER_FLAG_OBJALLOCATED );
	vxdFree ( this );

	return TMOK;
}

STATUS	buffermDestroy (PVOID pObject )
{
	PTMBUFFER_MGR_OBJECT	this = (PTMBUFFER_MGR_OBJECT)pObject;
	
	this->Size = 0;

	vxdFree ( this->pBufferTab );

	if ( FlagGet ( this->Flags, TMBUFFER_FLAG_MGRDYNAMICOBJ ) )
	{
		this->Flags = 0;
		vxdFree ( this );
	}
	else
	{
		this->Flags = 0;
	}
	
	return TMOK;
}



STATUS	bufferPhysicalAddress ( PVOID pvObject, PDWORD pdwPhysicalAddress ) 
{
	PTMBUFFER_OBJECT		this = (PTMBUFFER_OBJECT)pvObject;
	STATUS	Status;	

	if ( ( Status = bufferValidateHandle ( pvObject ) ) != TMOK )
	{
		return Status;
	}
	*pdwPhysicalAddress = this->dwPTEPhysicalAddress;
	return TMOK;
}


STATUS	bufferValidateHandle ( PVOID pvObject )
{
	PTMBUFFER_OBJECT this = (PTMBUFFER_OBJECT)pvObject;

	if ( ! pvObject )
		goto bufferValidateHandle_fail;

	if ( this->Size != sizeof(TMBUFFER_OBJECT) )
		goto bufferValidateHandle_fail;

	if ( ! FlagGet ( this->Flags, TMBUFFER_FLAG_OBJALLOCATED ) )
		goto bufferValidateHandle_fail;
	return TMOK;

bufferValidateHandle_fail :
	DP(0,"TM:bufferValidateHandle:pBuffer[%x]:FAIL\n",pvObject );
	return TMBUFFER_ERR_INVALIDHANDLE;
}


STATUS	buffermDestroyBufferByClnt  ( PVOID pBufferMgr, DWORD dwClientHandle )
{
	PTMBUFFER_MGR_OBJECT	this	=  ( PTMBUFFER_MGR_OBJECT )pBufferMgr;
	DWORD	dwIdxBuffer;

	for ( dwIdxBuffer = 0 ; dwIdxBuffer < this->BufferCount ; dwIdxBuffer ++ )
	{
		if ( ! FlagGet ( this->pBufferTab[dwIdxBuffer]->Flags, 
			TMBUFFER_FLAG_OBJALLOCATED ) )
			continue;

		if ( this->pBufferTab[dwIdxBuffer]->pClient != (PVOID)dwClientHandle )
			continue; 

		buffermDestroy ( &this->pBufferTab[dwIdxBuffer] );
	}
	
	return TMOK;
}

⌨️ 快捷键说明

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