示例#1
0
IPC_U32 IPC_BufferSetDataSize(IPC_Buffer Buffer, IPC_U32 Length)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_U32 MaxDataSize;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferSetDataSize",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	MaxDataSize = IPC_PoolMaxDataSize(BufferPtr->Pool);

	if (Length > MaxDataSize) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferSetDataSize",
			  "Buffer %08X, Length %d too big", Buffer, Length, 0,
			  0);
		return 0;
	} else {
		IPC_TRACE(IPC_Channel_Data, "IPC_BufferSetDataSize",
			  "Buffer %08X, Length %d", Buffer, Length, 0, 0);
		BufferPtr->DataSize = Length;
		return Length;
	}
}
示例#2
0
void IPC_FreeBuffer(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_CPU_ID_T OwningCpu;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_FreeBuffer",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return;
	}

	if (BufferPtr->StatusCode == IPC_BUFFER_STATUS_FREE) {
		IPC_TRACE(IPC_Channel_Error, "IPC_FreeBuffer",
			  "Repeated Free Buffer %08X", Buffer, 0, 0, 0);
		return;
	}

	OwningCpu = IPC_PoolOwningCpu(BufferPtr->Pool);
	BufferPtr->TimeStampFree = TIMER_GetValue();
	BufferPtr->StatusCode = IPC_BUFFER_STATUS_FREE;

	if (OwningCpu == IPC_SM_CURRENT_CPU) {
		IPC_TRACE(IPC_Channel_Buffer, "IPC_FreeBuffer",
			  "Buffer %08X, ID %d Same CPU ", Buffer,
			  BufferPtr->BufferId, 0, 0);
		IPC_BufferReturn(Buffer, BufferPtr->Pool);
	} else {
		IPC_TRACE(IPC_Channel_Buffer, "IPC_FreeBuffer",
			  "Buffer %08X, ID %d Other CPU", Buffer,
			  BufferPtr->BufferId, 0, 0);
		IPC_SmFreeBuffer(Buffer, OwningCpu);
	}
}
示例#3
0
IPC_ReturnCode_T IPC_SendBuffer(IPC_Buffer Buffer, IPC_Priority_T Priority)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	IPC_TRACE(IPC_Channel_Buffer, "IPC_SendBuffer",
		  "Buffer %d (%08X), Priority %d", BufferPtr->BufferId, Buffer,
		  Priority, 0);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_SendBuffer",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return IPC_ERROR;
	}

	BufferPtr->TimeStampSend = TIMER_GetValue();
	BufferPtr->StatusCode = IPC_BUFFER_STATUS_SENT;

	IPC_PoolAddBytesSent(BufferPtr->Pool,
			     BufferPtr->DataSize + BufferPtr->HeaderSize);

#ifdef IPC_BUFFER_STATS
	/* Debug output - turned off by default for performance */
	if (BufferPtr->BufferId == 0 && 0 == LISR_Active)
		IPC_PoolDumpStats(BufferPtr->Pool);
#endif

	IPC_SmSendBuffer(Buffer);

	return IPC_OK;
}
示例#4
0
void *IPC_BufferFill(IPC_Buffer Buffer, void *SourcePtr, IPC_U32 SourceLength)
{
	IPC_Buffer_T *BufferPtr;
	IPC_U32 MaxDataSize;

	if (SourceLength == 0)
		return NULL;

	BufferPtr = IPC_BufferToPtr(Buffer);
	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferFill",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return NULL;
	}

	MaxDataSize = IPC_PoolMaxDataSize(BufferPtr->Pool);

	if (MaxDataSize < SourceLength) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferFill",
			  "Buffer %08X, Length %d too big", Buffer,
			  SourceLength, 0, 0);
		return NULL;
	}

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferFill",
		  "Buffer %08X, From %08P, Length %d", Buffer, SourcePtr,
		  SourceLength, 0);

	BufferPtr->DataSize = SourceLength;

	return memcpy(IPC_SmAddress(BufferPtr->DataOffset), SourcePtr,
		      SourceLength);
}
示例#5
0
void IPC_DecrementBufferDataPointer(IPC_Buffer Buffer, IPC_U32 offset)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_SmPtr DataOffset = 0;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_MoveBufferDataPointer ",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return;
	}
	DataOffset = BufferPtr->DataOffset - offset;

	IPC_TRACE(IPC_Channel_Data, "IPC_MoveBufferDataPointer ",
		  "Buffer %08X, Ptr %08X", Buffer, DataOffset, 0, 0);

	if (DataOffset <
	    (BufferPtr->DataBufferStart) + IPC_BufferHeaderSizeGet(Buffer)) {
		IPC_TRACE(IPC_Channel_Error, "IPC_MoveBufferDataPointer ",
			  "Invalid Pointer %08X", BufferPtr->DataOffset, 0, 0,
			  0);
		return;
	}
	BufferPtr->DataOffset = DataOffset;
	BufferPtr->DataSize += offset;
	BufferPtr->HeaderSize -= offset;
}
示例#6
0
void *IPC_BufferHeaderRemove(IPC_Buffer Buffer, IPC_U32 HeaderSize)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferHeaderRemove",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	if (HeaderSize > BufferPtr->HeaderSize) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferHeaderRemove",
			  "Buffer %08X, HeaderSize %d too big", Buffer,
			  HeaderSize, 0, 0);
		return 0;
	} else {

		IPC_TRACE(IPC_Channel_Data, "IPC_BufferHeaderRemove",
			  "Buffer %08X, HeaderSize %d", Buffer, HeaderSize, 0,
			  0);
		BufferPtr->HeaderSize -= HeaderSize;
		return IPC_SmAddress(BufferPtr->DataOffset -
				     BufferPtr->HeaderSize);
	}
}
示例#7
0
void *IPC_BufferLocalDescriptor(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferLocalDescriptorl",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return 0;
	}

	return (void *)BufferPtr->LocalData;
}
示例#8
0
IPC_BufferPool IPC_BufferOwningPool(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferOwningPool",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return 0;
	}

	return BufferPtr->Pool;
}
示例#9
0
void IPC_PoolDump(IPC_BufferPool Pool)
{
	IPC_BufferPool_T *PoolPtr = IPC_PoolToPtr(Pool);
	IPC_U32 Id;
	IPC_SmPtr Buffer;
	IPC_U32 BufferSize;
	IPC_Buffer_T *BufferPtr;

	IPC_TRACE(IPC_Channel_General, "----- IPC_PoolDump -----", "", 0, 0, 0,
		  0);

	if (!PoolPtr) {
		IPC_TRACE(IPC_Channel_General, "IPC_PoolDump",
			  "Pool %08X Invalid", Pool, 0, 0, 0);
		return;
	};

	IPC_TRACE(IPC_Channel_General, "IPC_PoolDump",
		  "Pool %08X, CPU %s, SrcEp %02X, DestEp %02X", Pool,
		  (IPC_U32)IPC_GetCpuName(PoolPtr->Cpu),
		  PoolPtr->SourceEndpointId, PoolPtr->DestinationEndpointId);
	IPC_TRACE(IPC_Channel_General, "            ",
		  "SrcEp Id=%02X Name=%s, DestEp Id=%02X Name=%s",
		  PoolPtr->SourceEndpointId,
		  (IPC_U32)IPC_GetEndPointName(PoolPtr->SourceEndpointId),
		  PoolPtr->DestinationEndpointId,
		  (IPC_U32)IPC_GetEndPointName(PoolPtr->DestinationEndpointId));

	IPC_TRACE(IPC_Channel_General, "            ",
		  "BufCount %d, Free  %d, FlowState %01d, Param %08X",
		  PoolPtr->MaxBuffers, PoolPtr->FreeBuffers,
		  PoolPtr->FlowControlState, PoolPtr->UserParameter);

	IPC_PoolDumpStats(Pool);

	/* Dump IPC buffer not consumed by receiver to debug
	   IPC memory depletion issue */
	if (PoolPtr->MaxBuffers == PoolPtr->FreeBuffers)
		return;

	Buffer = Pool + sizeof(IPC_BufferPool_T);
	BufferSize =
	    IPC_BufferOverhead() + PoolPtr->MaxHeaderSize +
	    PoolPtr->MaxDataSize;
	IPC_TRACE(IPC_Channel_General, "IPC_PoolDump", "Allocated Buffers:", 0,
		  0, 0, 0);
	for (Id = 0; Id < PoolPtr->MaxBuffers; Id++) {
		BufferPtr = IPC_BufferToPtr(Buffer);
		if (BufferPtr->StatusCode != IPC_BUFFER_STATUS_FREE)
			IPC_BufferDump(Buffer);
		Buffer += BufferSize;
	}
}
示例#10
0
IPC_EndpointId_T IPC_BufferSourceEndpointId(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferSourceEndpoint",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return IPC_EP_None;
	}

	return IPC_PoolSourceEndpointId(BufferPtr->Pool);
}
示例#11
0
IPC_U32 IPC_BufferUserParameterGet(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferUserParameterGet",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	return BufferPtr->UserParameter;
}
示例#12
0
IPC_U32 IPC_BufferPoolUserParameter(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_U32 Parameter;

	Parameter = IPC_PoolUserParameterGet(BufferPtr->Pool);

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferPoolUserParameter",
		  "Buffer %08X, Parameter %08X", Buffer, Parameter, 0, 0);

	return Parameter;
}
示例#13
0
IPC_Boolean IPC_BufferUserParameterSet(IPC_Buffer Buffer, IPC_U32 Value)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferUserParameterSet",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return IPC_FALSE;
	}

	BufferPtr->UserParameter = Value;

	return IPC_TRUE;
}
示例#14
0
void *IPC_BufferHeaderPointer(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferHeaderPointer",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferHeaderPointer", "Buffer %08X",
		  Buffer, 0, 0, 0);

	return IPC_SmAddress(BufferPtr->DataOffset - BufferPtr->HeaderSize);
}
示例#15
0
IPC_U32 IPC_BufferDataSize(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferDataSize",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferDataSize",
		  "Buffer %08X, Size %d", Buffer, BufferPtr->DataSize, 0, 0);

	return BufferPtr->DataSize;
}
示例#16
0
void *IPC_BufferFillByLinkList(IPC_Buffer Buffer,
				IPC_LinkList_T *LinkListPtr,
				IPC_U32 LinkListLength)
{
	IPC_Buffer_T *BufferPtr;
	IPC_U32 MaxDataSize;
	IPC_U32 SourceLength;
	IPC_U32 i;
	unsigned char *p;
	unsigned char *q;

	SourceLength = 0;
	for (i = 0; i < LinkListLength; i++)
		SourceLength += LinkListPtr[i].size;

	if (SourceLength == 0)
		return NULL;

	BufferPtr = IPC_BufferToPtr(Buffer);
	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferFillByLinkList",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return NULL;
	}

	MaxDataSize = IPC_PoolMaxDataSize(BufferPtr->Pool);

	if (MaxDataSize < SourceLength) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferFillByLinkList",
			  "Buffer %08X, Length %d too big", Buffer,
			  SourceLength, 0, 0);
		return NULL;
	}

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferFillByLinkList",
		  "Buffer %08X, LinkListPtr %08X, Length %d", Buffer,
		  LinkListPtr, SourceLength, 0);

	BufferPtr->DataSize = SourceLength;

	p = q = IPC_SmAddress(BufferPtr->DataOffset);
	for (i = 0; i < LinkListLength; i++) {
		memcpy(p, LinkListPtr[i].byte_array, LinkListPtr[i].size);
		p += LinkListPtr[i].size;
	}
	return (void *)q;
}
示例#17
0
IPC_U32 IPC_BufferHeaderSizeGet(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_U32 HeaderSize;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferHeaderSizeGet",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}

	HeaderSize = BufferPtr->HeaderSize;

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferHeaderSizeGet",
		  "Buffer %08X, HeaderSize %d", Buffer, HeaderSize, 0, 0);

	return HeaderSize;
}
示例#18
0
IPC_EndpointId_T IPC_BufferDestinationEndpointId(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_EndpointId_T DestinationEndpointId;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferDestinationEndpoint",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return IPC_EP_None;
	}

	DestinationEndpointId = IPC_PoolDestinationEndpointId(BufferPtr->Pool);

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferDestinationEndpoint",
		  "Buffer %08X, EpId %08X", Buffer, DestinationEndpointId, 0,
		  0);

	return DestinationEndpointId;

}
示例#19
0
void *IPC_BufferDataPointer(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	IPC_SmPtr DataOffset = 0;

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferDataPointer",
			  "Invalid Buffer %d", Buffer, 0, 0, 0);
		return 0;
	}
	DataOffset = BufferPtr->DataOffset;

	IPC_TRACE(IPC_Channel_Data, "IPC_BufferDataPointer",
		  "Buffer %08X, Ptr %08X", Buffer, DataOffset, 0, 0);

	if (DataOffset >= ((IPC_SmControl) SmBase)->Size) {
		IPC_TRACE(IPC_Channel_Error, "IPC_BufferDataPointer",
			  "Invalid Pointer %08X", DataOffset, 0, 0, 0);
		return 0;
	}

	return IPC_SmAddress(DataOffset);
}
示例#20
0
void IPC_BufferDump(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);
	/**
	 * DataPtr is used to dump the contents of the first 4 U32s
	 * of the memory location
	 *
	 * coverity[returned_pointer]
	 */
	IPC_U32 *DataPtr = IPC_BufferDataPointer(Buffer);
	IPC_BufferPool_T *PoolPtr = IPC_PoolToPtr(BufferPtr->Pool);

	if (BufferPtr == 0) {
		IPC_TRACE(IPC_Channel_General, "IPC_BufferDump",
			  "Invalid Buffer %08X", Buffer, 0, 0, 0);
		return;
	}

	IPC_TRACE(IPC_Channel_General, "IPC_BufferDump",
		  "Id %d, Pool %08X, Next %08X, Prev %08X", BufferPtr->BufferId,
		  BufferPtr->Pool, BufferPtr->Q.Next, BufferPtr->Q.Previous);

	IPC_TRACE(IPC_Channel_General, "              ",
		  "Buffer %08X, DataOffset %08X, DataSize %d, HeaderSize %d",
		  BufferPtr->DataBufferStart, BufferPtr->DataOffset,
		  BufferPtr->DataSize, BufferPtr->HeaderSize);

	if (BufferPtr->StatusCode == IPC_BUFFER_STATUS_FREE) {
		IPC_TRACE(IPC_Channel_General, "              ",
			  "Free  FreeTime %d, prevAllocTime %d, prevSendTime %d",
			  BufferPtr->TimeStampFree, BufferPtr->TimeStampAlloc,
			  BufferPtr->TimeStampSend, 0);
	} else if (BufferPtr->StatusCode == IPC_BUFFER_STATUS_ALLOC) {
		IPC_TRACE(IPC_Channel_General, "              ",
			  "Alloc  AllocTime %d, prevSendTime %d, prevFreeTime %d",
			  BufferPtr->TimeStampAlloc, BufferPtr->TimeStampSend,
			  BufferPtr->TimeStampFree, 0);
	} else if (BufferPtr->StatusCode == IPC_BUFFER_STATUS_SENT) {
		IPC_TRACE(IPC_Channel_General, "              ",
			  "Sent  SendTime %d, AllocTime %d, prevFreeTime %d",
			  BufferPtr->TimeStampSend, BufferPtr->TimeStampAlloc,
			  BufferPtr->TimeStampFree, 0);
	} else {
		IPC_TRACE(IPC_Channel_General, "              ",
			  "Invalid Status", 0, 0, 0, 0);
	}

	IPC_TRACE(IPC_Channel_General, "              ",
		  "Data 0..3 %08X %08X %08X %08X", DataPtr[0], DataPtr[1],
		  DataPtr[2], DataPtr[3]);

	IPC_TRACE(IPC_Channel_General, "              ",
		  "Data 4..7 %08X %08X %08X %08X", DataPtr[4], DataPtr[5],
		  DataPtr[6], DataPtr[7]);

	/* Print RPC message ID located at byte 18-19 of IPC buffer */
	if (PoolPtr->SourceEndpointId == IPC_EP_Capi2Cp ||
	    PoolPtr->DestinationEndpointId == IPC_EP_Capi2Cp) {
		UInt8 *rpcDataPtr = (UInt8 *)DataPtr;
		UInt32 rpcMsgId;
		rpcMsgId =
		    ((UInt32)(rpcDataPtr[19])) | ((UInt32)(rpcDataPtr[18]) <<
						  8);
		IPC_TRACE(IPC_Channel_General, "              ",
			  "RPC message ID %08X", rpcMsgId, 0, 0, 0);
	}

}
示例#21
0
//**************************************************
IPC_BufferPool IPC_CreateBufferPoolWithDescriptor
(
	IPC_EndpointId_T		SourceEndpointId,
	IPC_EndpointId_T		DestinationEndpointId,
	IPC_U32					NumberOfBuffers,
	IPC_U32					BufferSize,
	IPC_U32					FlowStartLimit,
	IPC_U32					FlowStopLimit,
	IPC_U32					LocalDescriptorSize
)
{
	IPC_U32				MaxDataSize		= ALIGN4 (BufferSize);
	IPC_BufferPool		Pool;
	IPC_BufferPool_T *	PoolPtr;
	IPC_Endpoint		DestinationEpPtr;
	IPC_SmPtr			Buffer;
	IPC_U32				Id;
	char *				LocalData;

	IPC_TRACE (IPC_Channel_Pool, "IPC_CreateBufferPool",
				"Source %02X, Destination %02X, Buffer Count %d, Buffer Size %d",
				SourceEndpointId, DestinationEndpointId, NumberOfBuffers, BufferSize);

	// Sanity Checks
	if (NumberOfBuffers == 0)
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "Invalid NumberOfBuffers %d", NumberOfBuffers, 0, 0, 0);
		return 0;
	}

	if (!IPC_SmEndpointInfo (SourceEndpointId))
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "Invalid Source Endpoint %d", SourceEndpointId, 0, 0, 0);
		return 0;
	}

	if (0 == (DestinationEpPtr = IPC_SmEndpointInfo (DestinationEndpointId)))
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "Invalid Destination Endpoint %d", DestinationEndpointId, 0, 0, 0);
		return 0;
	}

	if (FlowStartLimit > NumberOfBuffers)
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "Invalid FlowStartLimit %d", FlowStartLimit, 0, 0, 0);
		return 0;
	}

	if (FlowStopLimit >= NumberOfBuffers)
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "Invalid FlowStopLimit %d", FlowStopLimit, 0, 0, 0);
		return 0;
	}

	// Allocate Sm For Pool
	Pool = IPC_SmPoolAlloc (sizeof (IPC_BufferPool_T), DestinationEpPtr->MaxHeaderSize, MaxDataSize, NumberOfBuffers);

	if (!Pool)
	{
		IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "IPC_SmPoolAlloc Failed", 0, 0, 0, 0);
		return 0;
	}

	if (LocalDescriptorSize != 0)
	{
#ifdef UNDER_LINUX
        // Use kmalloc instead of OSHEAP_Alloc in Linux platform
		LocalData = kmalloc ((LocalDescriptorSize * NumberOfBuffers), GFP_KERNEL);
#else
		LocalData = (char *) OSHEAP_Alloc (LocalDescriptorSize * NumberOfBuffers);
#endif  // UNDER_LINUX

		if (!LocalData)
		{
			IPC_TRACE (IPC_Channel_Error, "IPC_CreateBufferPool", "LocalData OSHEAP_Alloc Failed", 0, 0, 0, 0);
			return 0;
		}
	} else {
		LocalData = 0;
	}

	// Initialise Pool
	PoolPtr	= IPC_PoolPtr(Pool);

	PoolPtr->Cpu					= IPC_SM_CURRENT_CPU;
	PoolPtr->SourceEndpointId		= SourceEndpointId;
	PoolPtr->DestinationEndpointId	= DestinationEndpointId;
	PoolPtr->MaxDataSize			= MaxDataSize;
	PoolPtr->MaxHeaderSize			= DestinationEpPtr->MaxHeaderSize;
	PoolPtr->FlowStartLimit			= FlowStartLimit;
	PoolPtr->FlowStopLimit			= FlowStopLimit;
	PoolPtr->FlowControlState		= IPC_FLOW_START;
	PoolPtr->FlowControlCallPending	= IPC_FALSE;
	PoolPtr->FreeBuffers			= NumberOfBuffers;
	PoolPtr->MaxBuffers				= NumberOfBuffers;
	PoolPtr->LowWaterMark			= NumberOfBuffers;
	PoolPtr->NextPool				= 0;
	PoolPtr->BufferFreeFunction		= NULL;
	PoolPtr->AllocationFailures		= 0;
	PoolPtr->Allocations			= 0;
	PoolPtr->BytesSent				= 0;
	PoolPtr->FlowStopCalls			= 0;
	PoolPtr->FlowStartCalls			= 0;

	PoolPtr->EmptyEvent				= IPC_EVENT_CREATE;

	IPC_QInitialise			(IPC_SmOffset(&PoolPtr->FreeBufferQ), Pool);
	IPC_QInitialise			(IPC_SmOffset(&PoolPtr->AllocatedBufferQ), Pool);



	// Initialise Buffers in pool
	Buffer = Pool + sizeof (IPC_BufferPool_T);

	for (Id = 0; Id < NumberOfBuffers; Id++)
	{
		IPC_BufferToPtr (Buffer)->LocalData = LocalData;

		LocalData += LocalDescriptorSize;

		IPC_QAddBack (Buffer, IPC_POOLFreeQ(Pool));
		Buffer = IPC_BufferInitialise (Pool, Buffer, Id, PoolPtr->MaxHeaderSize, MaxDataSize);

	}

	// For Debug
	{
		IPC_PoolList_T * EpPools = &PoolList [PoolPtr->SourceEndpointId];

		if (EpPools->Count < IPC_POOLLIST_LENGTH)
		{
			EpPools->Pool [EpPools->Count++] = PoolPtr;
		}
	}

	IPC_TRACE (IPC_Channel_Pool, "IPC_CreateBufferPool", "Pool %08X", Pool, 0, 0, 0);

	return Pool;
}
示例#22
0
void IPC_BufferDone(IPC_Buffer Buffer)
{
	IPC_Buffer_T *BufferPtr = IPC_BufferToPtr(Buffer);

	IPC_BufferReturnToPool(Buffer, BufferPtr->Pool);
}