IPC_SmQ IPC_QCreate(void) { IPC_SmQ Queue = IPC_SmAlloc(sizeof(IPC_QHead_T)); if (Queue == 0) { IPC_TRACE(IPC_Channel_Error, "IPC_QCreate", "IPC_SmAlloc failed", 0, 0, 0, 0); return 0; } return IPC_QInitialise(Queue, Queue); }
//************************************************** 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; }