enum PVRSRV_ERROR PVRSRVAllocDeviceMemKM(void *hDevCookie,
				     struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				     void *hDevMemHeap, u32 ui32Flags,
				     u32 ui32Size, u32 ui32Alignment,
				     struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
{
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
	enum PVRSRV_ERROR eError;
	struct BM_HEAP *psBMHeap;
	void *hDevMemContext;

	if (!hDevMemHeap || (ui32Size == 0))
		return PVRSRV_ERROR_INVALID_PARAMS;

	eError = AllocDeviceMem(hDevCookie, hDevMemHeap, ui32Flags, ui32Size,
				ui32Alignment, &psMemInfo);

	if (eError != PVRSRV_OK)
		return eError;

	if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) {
		psMemInfo->psKernelSyncInfo = NULL;
	} else {
		psBMHeap = (struct BM_HEAP *)hDevMemHeap;
		hDevMemContext = (void *) psBMHeap->pBMContext;
		eError = PVRSRVAllocSyncInfoKM(hDevCookie,
					       hDevMemContext,
					       &psMemInfo->psKernelSyncInfo);
		if (eError != PVRSRV_OK)
			goto free_mainalloc;
	}

	*ppsMemInfo = psMemInfo;

	if (ui32Flags & PVRSRV_MEM_NO_RESMAN) {
		psMemInfo->sMemBlk.hResItem = NULL;
	} else {
		psMemInfo->sMemBlk.hResItem =
		    ResManRegisterRes(psPerProc->hResManContext,
				      RESMAN_TYPE_DEVICEMEM_ALLOCATION,
				      psMemInfo, 0, FreeDeviceMemCallBack);
		if (psMemInfo->sMemBlk.hResItem == NULL) {
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto free_mainalloc;
		}
	}

	psMemInfo->ui32RefCount++;

	return PVRSRV_OK;

free_mainalloc:
	FreeDeviceMem(psMemInfo);

	return eError;
}
static inline
enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
		    void *mem_context_handle,
		    struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
		    struct IMG_SYS_PHYADDR *phys_addr)
{
	enum PVRSRV_ERROR error;
	struct PVRSRV_DEVICE_NODE *dev;

	dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;

	*syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
					HASH_Retrieve(dev->sync_table,
						      phys_addr->uiAddr);

	if (!*syncinfo) {
		/* Dont' have one so create one */
		error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
					       syncinfo);

		if (error != PVRSRV_OK)
			return error;

		/* Setup our extra data */
		(*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
		(*syncinfo)->dev_cookie = dev_cookie;
		(*syncinfo)->refcount = 1;

		if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
			    (u32) *syncinfo)) {
			PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
				"Failed to add syncobject to hash table");
			return PVRSRV_ERROR_GENERIC;
		}
	} else
		get_syncinfo(*syncinfo);

	return PVRSRV_OK;
}
Beispiel #3
0
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVWrapExtMemoryKM(IMG_HANDLE				hDevCookie,
												PVRSRV_PER_PROCESS_DATA	*psPerProc,
												IMG_HANDLE				hDevMemContext,
												IMG_SIZE_T 				ui32ByteSize,
												IMG_SIZE_T				ui32PageOffset,
												IMG_BOOL				bPhysContig,
												IMG_SYS_PHYADDR	 		*psExtSysPAddr,
												IMG_VOID 				*pvLinAddr,
												IMG_UINT32				ui32Flags,
												PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo)
{
	PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
	DEVICE_MEMORY_INFO  *psDevMemoryInfo;
	IMG_SIZE_T			ui32HostPageSize = HOST_PAGESIZE();
	IMG_HANDLE			hDevMemHeap = IMG_NULL;
	PVRSRV_DEVICE_NODE* psDeviceNode;
	BM_HANDLE 			hBuffer;
	PVRSRV_MEMBLK		*psMemBlock;
	IMG_BOOL			bBMError;
	BM_HEAP				*psBMHeap;
	PVRSRV_ERROR		eError;
	IMG_VOID 			*pvPageAlignedCPUVAddr;
	IMG_SYS_PHYADDR	 	*psIntSysPAddr = IMG_NULL;
	IMG_HANDLE			hOSWrapMem = IMG_NULL;
	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;	
	IMG_UINT32		i;
        IMG_SIZE_T              ui32PageCount = 0;
	
	
	psDeviceNode = (PVRSRV_DEVICE_NODE*)hDevCookie;
	PVR_ASSERT(psDeviceNode != IMG_NULL);

	if (psDeviceNode == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: invalid parameter"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if(pvLinAddr)
	{
		
		ui32PageOffset = (IMG_UINTPTR_T)pvLinAddr & (ui32HostPageSize - 1);

		
		ui32PageCount = HOST_PAGEALIGN(ui32ByteSize + ui32PageOffset) / ui32HostPageSize;
		pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvLinAddr - ui32PageOffset);

		
		if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
						ui32PageCount * sizeof(IMG_SYS_PHYADDR),
						(IMG_VOID **)&psIntSysPAddr, IMG_NULL,
						"Array of Page Addresses") != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}

		eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
										ui32PageCount * ui32HostPageSize,
										psIntSysPAddr,
										&hOSWrapMem);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto ErrorExitPhase1;
		}

		
		psExtSysPAddr = psIntSysPAddr;

		

		bPhysContig = IMG_FALSE;
	}
	else
	{
		
	}
	
	
	psDevMemoryInfo = &((BM_CONTEXT*)hDevMemContext)->psDeviceNode->sDevMemoryInfo;
	psDeviceMemoryHeap = psDevMemoryInfo->psDeviceMemoryHeap;
	for(i=0; i<PVRSRV_MAX_CLIENT_HEAPS; i++)
	{
		if(HEAP_IDX(psDeviceMemoryHeap[i].ui32HeapID) == psDevMemoryInfo->ui32MappingHeapID)
		{
			if(psDeviceMemoryHeap[i].DevMemHeapType == DEVICE_MEMORY_HEAP_PERCONTEXT)
			{
				
				hDevMemHeap = BM_CreateHeap(hDevMemContext, &psDeviceMemoryHeap[i]);
			}
			else
			{
				hDevMemHeap = psDevMemoryInfo->psDeviceMemoryHeap[i].hDevMemHeap;
			}
			break;
		}
	}

	if(hDevMemHeap == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: unable to find mapping heap"));
		eError = PVRSRV_ERROR_UNABLE_TO_FIND_MAPPING_HEAP;
		goto ErrorExitPhase2;
	}

	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					sizeof(PVRSRV_KERNEL_MEM_INFO),
					(IMG_VOID **)&psMemInfo, IMG_NULL,
					"Kernel Memory Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: Failed to alloc memory for block"));
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExitPhase2;
	}

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));
	psMemInfo->ui32Flags = ui32Flags;

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap,
					   ui32ByteSize,
					   ui32PageOffset,
					   bPhysContig,
					   psExtSysPAddr,
					   IMG_NULL,
					   &psMemInfo->ui32Flags,
					   &hBuffer);
	if (!bBMError)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapExtMemoryKM: BM_Wrap Failed"));
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExitPhase3;
	}

	
	psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
	psMemBlock->hOSMemHandle = BM_HandleToOSMemHandle(hBuffer);
	psMemBlock->hOSWrapMem = hOSWrapMem;
	psMemBlock->psIntSysPAddr = psIntSysPAddr;

	
	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;

	
	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);
	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;

	

	psMemInfo->pvSysBackupBuffer = IMG_NULL;

	


	psBMHeap = (BM_HEAP*)hDevMemHeap;
	hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
	eError = PVRSRVAllocSyncInfoKM(hDevCookie,
									hDevMemContext,
									&psMemInfo->psKernelSyncInfo);
	if(eError != PVRSRV_OK)
	{
		goto ErrorExitPhase4;
	}

	psMemInfo->psKernelSyncInfo->ui32RefCount++;

	
	psMemInfo->ui32RefCount++;

	psMemInfo->memType = PVRSRV_MEMTYPE_WRAPPED;

	
	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
													RESMAN_TYPE_DEVICEMEM_WRAP,
													psMemInfo,
													0,
													&UnwrapExtMemoryCallBack);

	
	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;

	

ErrorExitPhase4:
	if(psMemInfo)
	{
		FreeDeviceMem(psMemInfo);
		


		psMemInfo = IMG_NULL;
	}

ErrorExitPhase3:
	if(psMemInfo)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
		
	}

ErrorExitPhase2:
	if(psIntSysPAddr)
	{
		OSReleasePhysPageAddr(hOSWrapMem);
	}

ErrorExitPhase1:
	if(psIntSysPAddr)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageCount * sizeof(IMG_SYS_PHYADDR), psIntSysPAddr, IMG_NULL);
		
	}
	
	return eError;
}
Beispiel #4
0
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV _PVRSRVAllocDeviceMemKM(IMG_HANDLE					hDevCookie,
												 PVRSRV_PER_PROCESS_DATA	*psPerProc,
												 IMG_HANDLE					hDevMemHeap,
												 IMG_UINT32					ui32Flags,
												 IMG_SIZE_T					ui32Size,
												 IMG_SIZE_T					ui32Alignment,
												 PVRSRV_KERNEL_MEM_INFO		**ppsMemInfo)
{
	PVRSRV_KERNEL_MEM_INFO	*psMemInfo;
	PVRSRV_ERROR 			eError;
	BM_HEAP					*psBMHeap;
	IMG_HANDLE				hDevMemContext;

	if (!hDevMemHeap ||
		(ui32Size == 0))
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	
	if (ui32Flags & PVRSRV_HAP_CACHETYPE_MASK)
	{
		 
		if (((ui32Size % HOST_PAGESIZE()) != 0) ||
			((ui32Alignment % HOST_PAGESIZE()) != 0))
		{
			return PVRSRV_ERROR_INVALID_PARAMS;
		}
	}

	eError = AllocDeviceMem(hDevCookie,
							hDevMemHeap,
							ui32Flags,
							ui32Size,
							ui32Alignment,
							&psMemInfo);

	if (eError != PVRSRV_OK)
	{
		return eError;
	}

#if defined(PVRSRV_RESOURCE_PROFILING)
	psBMHeap = (BM_HEAP*)hDevMemHeap;
	if (psBMHeap->pBMContext->psDeviceNode->pfnResProfCB)
		psBMHeap->pBMContext->psDeviceNode->pfnResProfCB(hDevCookie, psMemInfo->ui32AllocSize, IMG_TRUE);
#endif

	if (ui32Flags & PVRSRV_MEM_NO_SYNCOBJ)
	{
		psMemInfo->psKernelSyncInfo = IMG_NULL;
	}
	else
	{
		


		psBMHeap = (BM_HEAP*)hDevMemHeap;
		hDevMemContext = (IMG_HANDLE)psBMHeap->pBMContext;
		eError = PVRSRVAllocSyncInfoKM(hDevCookie,
									   hDevMemContext,
									   &psMemInfo->psKernelSyncInfo);
		if(eError != PVRSRV_OK)
		{
			goto free_mainalloc;
		}
		psMemInfo->psKernelSyncInfo->ui32RefCount++;
#if defined(PVRSRV_RESOURCE_PROFILING)
		if (psBMHeap->pBMContext->psDeviceNode->pfnResProfCB)
			psBMHeap->pBMContext->psDeviceNode->pfnResProfCB(hDevCookie,
						psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize, IMG_TRUE);
#endif
	}

	
	*ppsMemInfo = psMemInfo;

	if (ui32Flags & PVRSRV_MEM_NO_RESMAN)
	{
		psMemInfo->sMemBlk.hResItem = IMG_NULL;
	}
	else
	{
		
		psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
														RESMAN_TYPE_DEVICEMEM_ALLOCATION,
														psMemInfo,
														0,
														&FreeDeviceMemCallBack);
		if (psMemInfo->sMemBlk.hResItem == IMG_NULL)
		{
			
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto free_mainalloc;
		}
	}

	
	psMemInfo->ui32RefCount++;

	psMemInfo->memType = PVRSRV_MEMTYPE_DEVICE;

	
	return (PVRSRV_OK);

free_mainalloc:
#if defined(PVRSRV_RESOURCE_PROFILING)
	if (psBMHeap->pBMContext->psDeviceNode->pfnResProfCB)
		psBMHeap->pBMContext->psDeviceNode->pfnResProfCB(hDevCookie,
					psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->ui32AllocSize, IMG_FALSE);
#endif
	FreeDeviceMem(psMemInfo);

	return eError;
}
Beispiel #5
0
enum PVRSRV_ERROR PVRSRVCreateDCSwapChainKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				void *hDeviceKM, u32 ui32Flags,
				struct DISPLAY_SURF_ATTRIBUTES *psDstSurfAttrib,
				struct DISPLAY_SURF_ATTRIBUTES *psSrcSurfAttrib,
				u32 ui32BufferCount, u32 ui32OEMFlags,
				void **phSwapChain, u32 *pui32SwapChainID)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DC_SWAPCHAIN *psSwapChain = NULL;
	struct PVRSRV_SYNC_DATA *apsSyncData[PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS];
	struct PVRSRV_QUEUE_INFO *psQueue = NULL;
	enum PVRSRV_ERROR eError;
	u32 i;

	if (!hDeviceKM || !psDstSurfAttrib || !psSrcSurfAttrib ||
	    !phSwapChain || !pui32SwapChainID) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (ui32BufferCount > PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Too many buffers");
		return PVRSRV_ERROR_TOOMANYBUFFERS;
	}

	if (ui32BufferCount < 2) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Too few buffers");
		return PVRSRV_ERROR_TOO_FEW_BUFFERS;
	}

	psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM);

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_DC_SWAPCHAIN),
		       (void **) &psSwapChain, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVCreateDCSwapChainKM: Failed psSwapChain alloc");
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExit;
	}
	OSMemSet(psSwapChain, 0, sizeof(struct PVRSRV_DC_SWAPCHAIN));

	eError = PVRSRVCreateCommandQueueKM(1024, &psQueue);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			"PVRSRVCreateDCSwapChainKM: Failed to create CmdQueue");
		goto ErrorExit;
	}

	psSwapChain->psQueue = psQueue;

	for (i = 0; i < ui32BufferCount; i++) {
		eError = PVRSRVAllocSyncInfoKM(NULL,
					       psDCInfo->hDevMemContext,
					       &psSwapChain->asBuffer[i].
						       sDeviceClassBuffer.
							      psKernelSyncInfo);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
				"Failed to alloc syninfo for psSwapChain");
			goto ErrorExit;
		}

		psSwapChain->asBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr =
		    psDCInfo->psFuncTable->pfnGetBufferAddr;
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hDevMemContext =
		    psDCInfo->hDevMemContext;
		psSwapChain->asBuffer[i].sDeviceClassBuffer.hExtDevice =
		    psDCInfo->hExtDevice;

		psSwapChain->asBuffer[i].psDCInfo = psDCInfo;
		psSwapChain->asBuffer[i].psSwapChain = psSwapChain;

		apsSyncData[i] =
		    (struct PVRSRV_SYNC_DATA *)psSwapChain->asBuffer[i].
			    sDeviceClassBuffer.psKernelSyncInfo->
					psSyncDataMemInfoKM->pvLinAddrKM;
	}

	psSwapChain->ui32BufferCount = ui32BufferCount;
	psSwapChain->psDCInfo = psDCInfo;

	eError =
	    psDCInfo->psFuncTable->pfnCreateDCSwapChain(psDCInfo->hExtDevice,
						ui32Flags,
						psDstSurfAttrib,
						psSrcSurfAttrib,
						ui32BufferCount,
						apsSyncData,
						ui32OEMFlags,
						&psSwapChain->hExtSwapChain,
						pui32SwapChainID);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVCreateDCSwapChainKM: "
				"Failed to create 3rd party SwapChain");
		goto ErrorExit;
	}

	*phSwapChain = (void *) psSwapChain;

	psSwapChain->hResItem = ResManRegisterRes(psPerProc->hResManContext,
					  RESMAN_TYPE_DISPLAYCLASS_SWAPCHAIN,
					  psSwapChain, 0,
					  DestroyDCSwapChainCallBack);

	return eError;

ErrorExit:

	for (i = 0; i < ui32BufferCount; i++) {
		if (psSwapChain->asBuffer[i].sDeviceClassBuffer.
		    psKernelSyncInfo) {
			PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i].
						     sDeviceClassBuffer.
							     psKernelSyncInfo);
		}
	}

	if (psQueue)
		PVRSRVDestroyCommandQueueKM(psQueue);

	if (psSwapChain) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain,
			  NULL);
	}

	return eError;
}
Beispiel #6
0
enum PVRSRV_ERROR PVRSRVOpenDCDeviceKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				u32 ui32DeviceID, void *hDevCookie,
				void **phDeviceKM)
{
	struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
	struct PVRSRV_DEVICE_NODE *psDeviceNode;
	struct SYS_DATA *psSysData;

	if (!phDeviceKM || !hDevCookie) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVOpenDCDeviceKM: Invalid params");
		return PVRSRV_ERROR_GENERIC;
	}

	if (SysAcquireData(&psSysData) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVOpenDCDeviceKM: Failed to get SysData");
		return PVRSRV_ERROR_GENERIC;
	}

	psDeviceNode = psSysData->psDeviceNodeList;
	while (psDeviceNode) {
		if ((psDeviceNode->sDevId.eDeviceClass ==
		     PVRSRV_DEVICE_CLASS_DISPLAY) &&
		     (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {

			psDCInfo = (struct PVRSRV_DISPLAYCLASS_INFO *)
							psDeviceNode->pvDevice;
			goto FoundDevice;
		}
		psDeviceNode = psDeviceNode->psNext;
	}

	PVR_DPF(PVR_DBG_ERROR,
		 "PVRSRVOpenDCDeviceKM: no devnode matching index %d",
		 ui32DeviceID);

	return PVRSRV_ERROR_GENERIC;

FoundDevice:

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo),
		       (void **)&psDCPerContextInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
					"Failed psDCPerContextInfo alloc");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));

	if (psDCInfo->ui32RefCount++ == 0) {
		enum PVRSRV_ERROR eError;
		struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl;

		psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;

		jtbl = psDCInfo->psFuncTable;
		if (!try_module_get(jtbl->owner)) {
			PVR_DPF(PVR_DBG_ERROR, "%s: can't get DC module");
			return PVRSRV_ERROR_INVALID_DEVICE;
		}

		psDCInfo->hDevMemContext =
		    (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext;

		eError = PVRSRVAllocSyncInfoKM(NULL,
				       (void *)psDeviceNode->
					       sDevMemoryInfo.pBMKernelContext,
				       &psDCInfo->sSystemBuffer.
					       sDeviceClassBuffer.
						       psKernelSyncInfo);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR,
			       "PVRSRVOpenDCDeviceKM: Failed sync info alloc");
			psDCInfo->ui32RefCount--;
			module_put(jtbl->owner);
			return eError;
		}

		eError = jtbl->pfnOpenDCDevice(ui32DeviceID,
			&psDCInfo->hExtDevice,
			(struct PVRSRV_SYNC_DATA *)psDCInfo->sSystemBuffer.
				sDeviceClassBuffer.psKernelSyncInfo->
					psSyncDataMemInfoKM->pvLinAddrKM);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenDCDeviceKM: "
					"Failed to open external DC device");
			psDCInfo->ui32RefCount--;
			module_put(jtbl->owner);
			PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.
					   sDeviceClassBuffer.psKernelSyncInfo);
			return eError;
		}
	}

	psDCPerContextInfo->psDCInfo = psDCInfo;
	psDCPerContextInfo->hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_DISPLAYCLASS_DEVICE,
			      psDCPerContextInfo, 0, CloseDCDeviceCallBack);

	*phDeviceKM = (void *) psDCPerContextInfo;

	return PVRSRV_OK;
}
Beispiel #7
0
enum PVRSRV_ERROR PVRSRVOpenBCDeviceKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				u32 ui32DeviceID, void *hDevCookie,
				void **phDeviceKM)
{
	struct PVRSRV_BUFFERCLASS_INFO *psBCInfo;
	struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo;
	struct PVRSRV_DEVICE_NODE *psDeviceNode;
	struct SYS_DATA *psSysData;
	u32 i;
	enum PVRSRV_ERROR eError;

	if (!phDeviceKM || !hDevCookie) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVOpenBCDeviceKM: Invalid params");
		return PVRSRV_ERROR_GENERIC;
	}

	if (SysAcquireData(&psSysData) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVOpenBCDeviceKM: Failed to get SysData");
		return PVRSRV_ERROR_GENERIC;
	}

	psDeviceNode = psSysData->psDeviceNodeList;
	while (psDeviceNode) {
		if ((psDeviceNode->sDevId.eDeviceClass ==
		     PVRSRV_DEVICE_CLASS_BUFFER) &&
		      (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) {

			psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *)
							psDeviceNode->pvDevice;
			goto FoundDevice;
		}
		psDeviceNode = psDeviceNode->psNext;
	}

	PVR_DPF(PVR_DBG_ERROR,
		 "PVRSRVOpenBCDeviceKM: No devnode matching index %d",
		 ui32DeviceID);

	return PVRSRV_ERROR_GENERIC;

FoundDevice:

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(*psBCPerContextInfo),
		       (void **)&psBCPerContextInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
					"Failed psBCPerContextInfo alloc");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));

	if (psBCInfo->ui32RefCount++ == 0) {
		struct BUFFER_INFO sBufferInfo;

		psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;

		psBCInfo->hDevMemContext =
		    (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext;

		eError =
		    psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->
							   hExtDevice);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
					"Failed to open external BC device");
			return eError;
		}

		eError =
		    psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice,
							&sBufferInfo);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR,
				"PVRSRVOpenBCDeviceKM : Failed to get BC Info");
			return eError;
		}

		psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;

		eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				    sizeof(struct PVRSRV_BC_BUFFER) *
				    sBufferInfo.ui32BufferCount,
				    (void **) &psBCInfo->psBuffer,
				    NULL);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
					"Failed to allocate BC buffers");
			return eError;
		}
		OSMemSet(psBCInfo->psBuffer, 0,
			 sizeof(struct PVRSRV_BC_BUFFER) *
			 sBufferInfo.ui32BufferCount);

		for (i = 0; i < psBCInfo->ui32BufferCount; i++) {

			eError = PVRSRVAllocSyncInfoKM(NULL,
				      psBCInfo->hDevMemContext,
				      &psBCInfo->psBuffer[i].sDeviceClassBuffer.
							psKernelSyncInfo);
			if (eError != PVRSRV_OK) {
				PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
						"Failed sync info alloc");
				goto ErrorExit;
			}

			eError = psBCInfo->psFuncTable->pfnGetBCBuffer(
				    psBCInfo->hExtDevice, i,
				    psBCInfo->psBuffer[i].sDeviceClassBuffer.
							  psKernelSyncInfo->
								     psSyncData,
				    &psBCInfo->psBuffer[i].sDeviceClassBuffer.
							  hExtBuffer);
			if (eError != PVRSRV_OK) {
				PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: "
						"Failed to get BC buffers");
				goto ErrorExit;
			}

			psBCInfo->psBuffer[i].sDeviceClassBuffer.
			    pfnGetBufferAddr =
				    psBCInfo->psFuncTable->pfnGetBufferAddr;
			psBCInfo->psBuffer[i].sDeviceClassBuffer.
			    hDevMemContext = psBCInfo->hDevMemContext;
			psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice =
			    psBCInfo->hExtDevice;
		}
	}

	psBCPerContextInfo->psBCInfo = psBCInfo;
	psBCPerContextInfo->hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_BUFFERCLASS_DEVICE,
			      psBCPerContextInfo, 0, CloseBCDeviceCallBack);

	*phDeviceKM = (void *)psBCPerContextInfo;

	return PVRSRV_OK;

ErrorExit:

	for (i = 0; i < psBCInfo->ui32BufferCount; i++) {
		if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) {
			PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].
						     sDeviceClassBuffer.
							     psKernelSyncInfo);
		}
	}

	if (psBCInfo->psBuffer) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_BC_BUFFER), psBCInfo->psBuffer,
			  NULL);
	}

	return eError;
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA	*psPerProc,
								   IMG_UINT32				ui32DeviceID,
								   IMG_HANDLE				hDevCookie,
								   IMG_HANDLE				*phDeviceKM)
{
	PVRSRV_DISPLAYCLASS_INFO *psDCInfo;
	PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo;
	PVRSRV_DEVICE_NODE	*psDeviceNode;
	SYS_DATA			*psSysData;
	PVRSRV_ERROR eError;

	if(!phDeviceKM || !hDevCookie)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params"));
		return PVRSRV_ERROR_GENERIC;
	}

	SysAcquireData(&psSysData);
	
	
	psDeviceNode = (PVRSRV_DEVICE_NODE*)
			List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
										   MatchDeviceKM_AnyVaCb,
										   ui32DeviceID,
										   IMG_FALSE,
										   PVRSRV_DEVICE_CLASS_DISPLAY);
	if (!psDeviceNode)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID));
		return PVRSRV_ERROR_GENERIC;
	}
	psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice;

	


	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				  sizeof(*psDCPerContextInfo),
				  (IMG_VOID **)&psDCPerContextInfo, IMG_NULL,
				  "Display Class per Context Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo));

	if(psDCInfo->ui32RefCount++ == 0)
	{

		psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;

		
		psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;

		
		eError = PVRSRVAllocSyncInfoKM(IMG_NULL, 
									(IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext,
									&psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc"));
			psDCInfo->ui32RefCount--;
			return eError;
		}

		
		eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID,
                                                        	&psDCInfo->hExtDevice,
								(PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device"));
			psDCInfo->ui32RefCount--;
			PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo);
			return eError;
		}
	}

	psDCPerContextInfo->psDCInfo = psDCInfo;
	psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
													 RESMAN_TYPE_DISPLAYCLASS_DEVICE,
													 psDCPerContextInfo,
													 0,
													 CloseDCDeviceCallBack);

	
	*phDeviceKM = (IMG_HANDLE)psDCPerContextInfo;

	return PVRSRV_OK;
}
IMG_EXPORT
PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA	*psPerProc,
								   IMG_UINT32				ui32DeviceID,
								   IMG_HANDLE				hDevCookie,
								   IMG_HANDLE				*phDeviceKM)
{
	PVRSRV_BUFFERCLASS_INFO	*psBCInfo;
	PVRSRV_BUFFERCLASS_PERCONTEXT_INFO	*psBCPerContextInfo;
	PVRSRV_DEVICE_NODE		*psDeviceNode;
	SYS_DATA 				*psSysData;
	IMG_UINT32 				i;
	PVRSRV_ERROR			eError;

	if(!phDeviceKM || !hDevCookie)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params"));
		return PVRSRV_ERROR_GENERIC;
	}

	SysAcquireData(&psSysData);

	
	psDeviceNode = (PVRSRV_DEVICE_NODE*)
			List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
										   MatchDeviceKM_AnyVaCb,
										   ui32DeviceID,
										   IMG_FALSE,
										   PVRSRV_DEVICE_CLASS_BUFFER);
	if (!psDeviceNode)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID));
		return PVRSRV_ERROR_GENERIC;
	}
	psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice;
	
	


	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				  sizeof(*psBCPerContextInfo),
				  (IMG_VOID **)&psBCPerContextInfo, IMG_NULL,
				  "Buffer Class per Context Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo));

	if(psBCInfo->ui32RefCount++ == 0)
	{
		BUFFER_INFO sBufferInfo;

		psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie;

		
		psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext;

		
		eError = psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->hExtDevice);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device"));
			return eError;
		}

		
		eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info"));
			return eError;
		}

		
		psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount;
		

		
		eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
							  sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount,
							  (IMG_VOID **)&psBCInfo->psBuffer, 
						 	  IMG_NULL,
							  "Array of Buffer Class Buffer");
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers"));
			return eError;
		}
		OSMemSet (psBCInfo->psBuffer,
					0,
					sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount);
	
		for(i=0; i<psBCInfo->ui32BufferCount; i++)
		{
			
			eError = PVRSRVAllocSyncInfoKM(IMG_NULL,
										psBCInfo->hDevMemContext,
										&psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
			if(eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc"));
				goto ErrorExit;
			}
			
			


			eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice,
															i,
															psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData,
															&psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer);
			if(eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers"));
				goto ErrorExit;
			}

			
			psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr;
			psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext;
			psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice;
		}
	}

	psBCPerContextInfo->psBCInfo = psBCInfo;
	psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext,
													 RESMAN_TYPE_BUFFERCLASS_DEVICE,
													 psBCPerContextInfo,
													 0,
													 CloseBCDeviceCallBack);
	
	
	*phDeviceKM = (IMG_HANDLE)psBCPerContextInfo;

	return PVRSRV_OK;

ErrorExit:

	
	for(i=0; i<psBCInfo->ui32BufferCount; i++)
	{
		if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo)
		{
			PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo);
		}
	}

	
	if(psBCInfo->psBuffer)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL);
		psBCInfo->psBuffer = IMG_NULL;
	}

	return eError;
}