Ejemplo n.º 1
0
IMG_INTERNAL
void PVRSRVBMXProcDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine, IMG_UINT32 ui32Index)
{
	if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_XPROC))
		goto skip;

	PVRSRV_LOCK_CCB();

	gsRefCountCCB[giOffset].pszFile = pszFile;
	gsRefCountCCB[giOffset].iLine = iLine;
	gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
	snprintf(gsRefCountCCB[giOffset].pcMesg,
			 PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
			 PVRSRV_REFCOUNT_CCB_FMT_STRING,
			 "BM_XPROC",
			 NULL,
			 NULL,
			 gXProcWorkaroundShareData[ui32Index].hOSMemHandle,
			 (IMG_VOID *) ui32Index,
			 gXProcWorkaroundShareData[ui32Index].ui32RefCount,
			 gXProcWorkaroundShareData[ui32Index].ui32RefCount - 1,
			 gXProcWorkaroundShareData[ui32Index].ui32Size);
	gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
	giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;

	PVRSRV_UNLOCK_CCB();

skip:
	gXProcWorkaroundShareData[ui32Index].ui32RefCount--;
}
Ejemplo n.º 2
0
IMG_INTERNAL
void PVRSRVKernelMemInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
								PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
	if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MEMINFO))
		goto skip;

	PVRSRV_LOCK_CCB();

	gsRefCountCCB[giOffset].pszFile = pszFile;
	gsRefCountCCB[giOffset].iLine = iLine;
	gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
	snprintf(gsRefCountCCB[giOffset].pcMesg,
			 PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
			 PVRSRV_REFCOUNT_CCB_FMT_STRING,
			 "MEMINFO",
			 psKernelMemInfo->psKernelSyncInfo,
			 psKernelMemInfo,
			 psKernelMemInfo->sMemBlk.hOSMemHandle,
			 NULL,
			 psKernelMemInfo->ui32RefCount,
			 psKernelMemInfo->ui32RefCount - 1,
			 psKernelMemInfo->uAllocSize);
	gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
	giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;

	PVRSRV_UNLOCK_CCB();

skip:
	psKernelMemInfo->ui32RefCount--;
}
Ejemplo n.º 3
0
IMG_INTERNAL
void PVRSRVKernelSyncInfoDecRef2(const IMG_CHAR *pszFile, IMG_INT iLine,
								 PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo,
								 PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo)
{
	IMG_UINT32 ui32RefValue = OSAtomicRead(psKernelSyncInfo->pvRefCount);

	if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_SYNCINFO))
		goto skip;

	PVRSRV_LOCK_CCB();

	gsRefCountCCB[giOffset].pszFile = pszFile;
	gsRefCountCCB[giOffset].iLine = iLine;
	gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
	snprintf(gsRefCountCCB[giOffset].pcMesg,
			 PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
			 PVRSRV_REFCOUNT_CCB_FMT_STRING,
			 "SYNCINFO",
			 psKernelSyncInfo,
			 psKernelMemInfo,
			 (psKernelMemInfo) ? psKernelMemInfo->sMemBlk.hOSMemHandle : NULL,
			 NULL,
			 ui32RefValue,
			 ui32RefValue - 1,
			 (psKernelMemInfo) ? psKernelMemInfo->uAllocSize : 0);
	gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
	giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;

	PVRSRV_UNLOCK_CCB();

skip:
	PVRSRVReleaseSyncInfoKM(psKernelSyncInfo);
}
Ejemplo n.º 4
0
IMG_INTERNAL
void PVRSRVBMBufDecExport2(const IMG_CHAR *pszFile, IMG_INT iLine, BM_BUF *pBuf)
{
	if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_BM_BUF2))
		goto skip;

	PVRSRV_LOCK_CCB();

	gsRefCountCCB[giOffset].pszFile = pszFile;
	gsRefCountCCB[giOffset].iLine = iLine;
	gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
	snprintf(gsRefCountCCB[giOffset].pcMesg,
			 PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
			 PVRSRV_REFCOUNT_CCB_FMT_STRING,
			 "BM_BUF2",
			 NULL,
			 NULL,
			 BM_HandleToOSMemHandle(pBuf),
			 pBuf,
			 pBuf->ui32ExportCount,
			 pBuf->ui32ExportCount - 1,
			 (pBuf->pMapping) ? pBuf->pMapping->uSize : 0);
	gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
	giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;

	PVRSRV_UNLOCK_CCB();

skip:
	pBuf->ui32ExportCount--;
}
Ejemplo n.º 5
0
void SystraceTAKick(PVRSRV_SGXDEV_INFO *psDevInfo, IMG_UINT32 ui32FrameNum, IMG_UINT32 ui32RTData, IMG_BOOL bIsFirstKick) 
{
	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
	IMG_UINT32 ui32JobID = 0;
	IMG_UINT32 ui32CtxID = 0;
	PVRSRV_SYSTRACE_ERROR eError = PVRSRV_SYSTRACE_OK;
	
	if(psDevInfo->bSystraceInitialised)
	{
		if(bIsFirstKick)
		{
			eError = CreateJob(psDevInfo->psSystraceData, ui32PID, ui32FrameNum, ui32RTData);
			if(eError != PVRSRV_SYSTRACE_OK)
			{
				PVR_DPF((PVR_DBG_WARNING,"Systrace: Error creating a Job"));
			}
		}
		
		eError = GetCtxAndJobID(psDevInfo->psSystraceData, ui32PID, ui32FrameNum, ui32RTData, &ui32CtxID, &ui32JobID);
		
		if(eError != PVRSRV_SYSTRACE_OK)
		{
			PVR_DPF((PVR_DBG_WARNING,"Systrace: Job not found"));
		}
		
		trace_gpu_job_enqueue(ui32CtxID, ui32JobID, "TA");
	}
}
Ejemplo n.º 6
0
IMG_INTERNAL
void PVRSRVOffsetStructDecMapped2(const IMG_CHAR *pszFile, IMG_INT iLine,
								  PKV_OFFSET_STRUCT psOffsetStruct)
{
	if(!(guiDebugMask & PVRSRV_REFCOUNT_CCB_DEBUG_MMAP2))
		goto skip;

	PVRSRV_LOCK_CCB();

	gsRefCountCCB[giOffset].pszFile = pszFile;
	gsRefCountCCB[giOffset].iLine = iLine;
	gsRefCountCCB[giOffset].ui32PID = OSGetCurrentProcessIDKM();
	snprintf(gsRefCountCCB[giOffset].pcMesg,
			 PVRSRV_REFCOUNT_CCB_MESG_MAX - 1,
			 PVRSRV_REFCOUNT_CCB_FMT_STRING,
			 "MMAP2",
			 NULL,
			 NULL,
			 psOffsetStruct->psLinuxMemArea,
			 psOffsetStruct,
			 psOffsetStruct->ui32Mapped,
			 psOffsetStruct->ui32Mapped - 1,
			 psOffsetStruct->ui32RealByteSize);
	gsRefCountCCB[giOffset].pcMesg[PVRSRV_REFCOUNT_CCB_MESG_MAX - 1] = 0;
	giOffset = (giOffset + 1) % PVRSRV_REFCOUNT_CCB_MAX;

	PVRSRV_UNLOCK_CCB();

skip:
	psOffsetStruct->ui32Mapped--;
}
Ejemplo n.º 7
0
int CreatePerProcessProcEntry(const char *name, read_proc_t rhandler,
			      write_proc_t whandler, void *data)
{
	struct PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
	u32 ui32PID;

	if (!dir) {
		PVR_DPF(PVR_DBG_ERROR,
			 "CreatePerProcessProcEntries: /proc/%s doesn't exist",
			 PVRProcDirRoot);

		return -ENOMEM;
	}

	ui32PID = OSGetCurrentProcessIDKM();

	psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
	if (!psPerProc) {
		PVR_DPF(PVR_DBG_ERROR,
			 "CreatePerProcessProcEntries: no per process data");

		return -ENOMEM;
	}

	if (!psPerProc->psProcDir) {
		char dirname[16];
		int ret;

		ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);

		if (ret <= 0 || ret >= sizeof(dirname)) {
			PVR_DPF(PVR_DBG_ERROR, "CreatePerProcessProcEntries: "
					"couldn't generate per process proc "
					"directory name \"%u\"",
					 ui32PID);

			return -ENOMEM;
		} else {
			psPerProc->psProcDir = proc_mkdir(dirname, dir);
			if (!psPerProc->psProcDir) {
				PVR_DPF(PVR_DBG_ERROR,
					"CreatePerProcessProcEntries: "
					"couldn't create per process proc "
					"directory /proc/%s/%u",
					 PVRProcDirRoot, ui32PID);

				return -ENOMEM;
			}
		}
	}

	return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler,
				    whandler, data);
}
Ejemplo n.º 8
0
static int PVRSRVRelease(struct inode unref__ * pInode,
			 struct file unref__ * pFile)
{
	int Ret = 0;

	LinuxLockMutex(&gPVRSRVLock);

	PVRSRVProcessDisconnect(OSGetCurrentProcessIDKM());

	LinuxUnLockMutex(&gPVRSRVLock);

	return Ret;
}
Ejemplo n.º 9
0
static int PVRSRVOpen(struct inode unref__ * pInode,
		      struct file unref__ * pFile)
{
	int Ret = 0;

	LinuxLockMutex(&gPVRSRVLock);

	if (PVRSRVProcessConnect(OSGetCurrentProcessIDKM()) != PVRSRV_OK)
		Ret = -ENOMEM;

	LinuxUnLockMutex(&gPVRSRVLock);

	return Ret;
}
/*!
******************************************************************************

 @Function	LinuxEventObjectAdd
 
 @Description 
 
 Linux wait object addition

 @Input    hOSEventObjectList : Event object list handle 
 @Output   phOSEventObject : Pointer to the event object handle 
 
 @Return   PVRSRV_ERROR  :  Error code

******************************************************************************/
PVRSRV_ERROR LinuxEventObjectAdd(IMG_HANDLE hOSEventObjectList, IMG_HANDLE *phOSEventObject)
 {
	PVRSRV_LINUX_EVENT_OBJECT *psLinuxEventObject; 
	PVRSRV_LINUX_EVENT_OBJECT_LIST *psLinuxEventObjectList = (PVRSRV_LINUX_EVENT_OBJECT_LIST*)hOSEventObjectList; 
	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	unsigned long ulLockFlags;

	psPerProc = PVRSRVPerProcessData(ui32PID);
	if (psPerProc == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: Couldn't find per-process data"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* allocate completion variable */
	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_LINUX_EVENT_OBJECT), 
		(IMG_VOID **)&psLinuxEventObject, IMG_NULL,
		"Linux Event Object") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "LinuxEventObjectAdd: failed to allocate memory "));		
		return PVRSRV_ERROR_OUT_OF_MEMORY;	
	}
	
	INIT_LIST_HEAD(&psLinuxEventObject->sList);

	atomic_set(&psLinuxEventObject->sTimeStamp, 0);
	psLinuxEventObject->ui32TimeStampPrevious = 0;

#if defined(DEBUG)
	psLinuxEventObject->ui32Stats = 0;
#endif
    init_waitqueue_head(&psLinuxEventObject->sWait);

	psLinuxEventObject->psLinuxEventObjectList = psLinuxEventObjectList;

	psLinuxEventObject->hResItem = ResManRegisterRes(psPerProc->hResManContext,
													 RESMAN_TYPE_EVENT_OBJECT,
													 psLinuxEventObject,
													 0,
													 &LinuxEventObjectDeleteCallback);	

	write_lock_irqsave(&psLinuxEventObjectList->sLock, ulLockFlags);
	list_add(&psLinuxEventObject->sList, &psLinuxEventObjectList->sList);
	write_unlock_irqrestore(&psLinuxEventObjectList->sLock, ulLockFlags);
	
	*phOSEventObject = psLinuxEventObject;

	return PVRSRV_OK;	 
}
Ejemplo n.º 11
0
int msvdx_preinit_mmu(unsigned long hmemcxt)
{
	PVRSRV_ERROR err;
	PVRSRV_PER_PROCESS_DATA *ps_data = NULL;
	IMG_HANDLE hmem = (IMG_HANDLE) hmemcxt;
	IMG_HANDLE hmemkm;
	IMG_DEV_PHYADDR addr;
	IMG_UINT32 pid = OSGetCurrentProcessIDKM();
	int ret;
	drm_emgd_priv_t *priv = gpDrmDevice->dev_private;
	igd_context_t *context = priv->context;
	platform_context_plb_t *platform =
		(platform_context_plb_t *) context->platform_context;

    ps_data = PVRSRVPerProcessData(pid);
	if (!ps_data) {
		printk(KERN_ERR "MSVDX: Cannot get process data information");

		return -1;
	}


	err = PVRSRVLookupHandle(ps_data->psHandleBase, &hmemkm, hmem, PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);

	if(err != PVRSRV_OK)
	{
		printk(KERN_ERR "MSVDX: Cannot get memory context from process data");

		return -1;
	}

	addr = BM_GetDeviceNode(hmemkm)->pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext(hmemkm));
	msvdx_init_compositor_mmu(addr.uiAddr);

	if (!platform->msvdx_pvr) {
		ret = msvdx_pvr_init();
		if (ret) {
			printk(KERN_INFO "Failed in msvdx_pvr_init()");
		} else {

		   	printk(KERN_INFO "Succeed for msvdx_pvr_init()");

		}
	}


	return 0;
}
Ejemplo n.º 12
0
int psb_get_meminfo_by_handle(IMG_HANDLE hKernelMemInfo,
				PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
{
	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = IMG_NULL;
	PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
	PVRSRV_ERROR eError;

	psPerProc = PVRSRVPerProcessData(OSGetCurrentProcessIDKM());
	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
				    (IMG_VOID *)&psKernelMemInfo,
				    hKernelMemInfo,
				    PVRSRV_HANDLE_TYPE_MEM_INFO);
	if (eError != PVRSRV_OK) {
		DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n",
			  (IMG_UINT32)hKernelMemInfo);
		return -EINVAL;
	}

	*ppsKernelMemInfo = psKernelMemInfo;

	DRM_DEBUG("Got Kernel MemInfo for handle %x\n",
		  (IMG_UINT32)hKernelMemInfo);
	return 0;
}
Ejemplo n.º 13
0
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT(psHashTab != IMG_NULL);


	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);

	if (psPerProc == IMG_NULL)
	{

		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
							sizeof(*psPerProc),
							(IMG_PVOID *)&psPerProc,
							&hBlockAlloc,
							"Per Process Data");
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		/*
		 * FIXME: using a hash to retrieve psPerProc makes not much
		 * sense. We always want to have this struct on the IOCTL path
		 * for the current task, so it'd be just a matter of storing
		 * it in the file private object. Until this is resolved and
		 * we get rid of this pid specific lookup make sure the above
		 * assumption holds.
		 */
		WARN_ON(OSGetCurrentProcessIDKM() != ui32PID);
		get_task_comm(psPerProc->name, current);

		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
			goto failure;
		}
		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

#if defined(PERPROC_LIST)
		List_PVRSRV_PER_PROCESS_DATA_Insert(&psPerProcList, psPerProc);
		/*PVR_LOG(("MarkTupsperproc %d\n", ui32PID));*/
#endif

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
		{
			psPerProc->bPDumpActive = IMG_TRUE;
		}
#else
		PVR_UNREFERENCED_PARAMETER(ui32Flags);
#endif


		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
								   &psPerProc->hPerProcData,
								   psPerProc,
								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
			goto failure;
		}


		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
			goto failure;
		}


		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
			goto failure;
		}
	}

	psPerProc->ui32RefCount++;
	PVR_DPF((PVR_DBG_MESSAGE,
			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
			ui32PID, psPerProc->ui32RefCount));

	return eError;

failure:
	(IMG_VOID)FreePerProcessData(psPerProc);
	return eError;
}
Ejemplo n.º 14
0
IMG_INT32
PVRSRV_BridgeDispatchKM(struct file *pFile, IMG_UINT unref__ ioctlCmd, IMG_UINT32 arg)
#endif
{
	IMG_UINT32 cmd;
#if !defined(SUPPORT_DRI_DRM)
	PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
	PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
#endif
	PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_INT err = -EFAULT;

	LinuxLockMutex(&gPVRSRVLock);

#if defined(SUPPORT_DRI_DRM)
	PVR_UNREFERENCED_PARAMETER(dev);

	psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
	PVR_ASSERT(psBridgePackageKM != IMG_NULL);
#else
	PVR_UNREFERENCED_PARAMETER(ioctlCmd);

	psBridgePackageKM = &sBridgePackageKM;

	if(!OSAccessOK(PVR_VERIFY_WRITE,
				   psBridgePackageUM,
				   sizeof(PVRSRV_BRIDGE_PACKAGE)))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
				 __FUNCTION__));

		goto unlock_and_return;
	}
	
	
	if(OSCopyFromUser(IMG_NULL,
					  psBridgePackageKM,
					  psBridgePackageUM,
					  sizeof(PVRSRV_BRIDGE_PACKAGE))
	  != PVRSRV_OK)
	{
		goto unlock_and_return;
	}
#endif

	cmd = psBridgePackageKM->ui32BridgeID;

#if defined(MODULE_TEST)
	switch (cmd)
	{
		case PVRSRV_BRIDGE_SERVICES_TEST_MEM1:
			{
				PVRSRV_ERROR eError = MemTest1();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;
		case PVRSRV_BRIDGE_SERVICES_TEST_MEM2:
			{
				PVRSRV_ERROR eError = MemTest2();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_RESOURCE:
			{
				PVRSRV_ERROR eError = ResourceTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_EVENTOBJECT:
			{
				PVRSRV_ERROR eError = EventObjectTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_MEMMAPPING:
			{
				PVRSRV_ERROR eError = MemMappingTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_PROCESSID:
			{
				PVRSRV_ERROR eError = ProcessIDTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_CLOCKUSWAITUS:
			{
				PVRSRV_ERROR eError = ClockusWaitusTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_TIMER:
			{
				PVRSRV_ERROR eError = TimerTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

		case PVRSRV_BRIDGE_SERVICES_TEST_PRIVSRV:
			{
				PVRSRV_ERROR eError = PrivSrvTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;
		case PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA:
		{
			IMG_UINT32               ui32PID;
			PVRSRV_PER_PROCESS_DATA *psPerProc;
			PVRSRV_ERROR eError;
			
			ui32PID = OSGetCurrentProcessIDKM();
		
			PVRSRVTrace("PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA %d", ui32PID);
			
			psPerProc = PVRSRVPerProcessData(ui32PID);
						
			eError = CopyDataTest(psBridgePackageKM->pvParamIn, psBridgePackageKM->pvParamOut, psPerProc);
			
			*(PVRSRV_ERROR*)psBridgePackageKM->pvParamOut = eError;
			err = 0;
			goto unlock_and_return;
		}


		case PVRSRV_BRIDGE_SERVICES_TEST_POWERMGMT:
    			{
				PVRSRV_ERROR eError = PowerMgmtTest();
				if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN))
				{
					PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ;
					pReturn->eError = eError;
				}
			}
			err = 0;
			goto unlock_and_return;

	}
#endif
	
	if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES)
	{
		PVRSRV_ERROR eError;

		eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
									(IMG_PVOID *)&psPerProc,
									psBridgePackageKM->hKernelServices,
									PVRSRV_HANDLE_TYPE_PERPROC_DATA);
		if(eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)",
					 __FUNCTION__, eError));
			goto unlock_and_return;
		}

		if(psPerProc->ui32PID != ui32PID)
		{
			PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data "
					 "belonging to process %d", __FUNCTION__, ui32PID,
					 psPerProc->ui32PID));
			goto unlock_and_return;
		}
	}
	else
	{
		
		psPerProc = PVRSRVPerProcessData(ui32PID);
		if(psPerProc == IMG_NULL)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: "
					 "Couldn't create per-process data area"));
			goto unlock_and_return;
		}
	}

	psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);

#if defined(PVR_SECURE_FD_EXPORT)
	switch(cmd)
	{
		case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
		{
			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);

			if(psPrivateData->hKernelMemInfo)
			{
				PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo "
						 "per file descriptor", __FUNCTION__));
				err = -EINVAL;
				goto unlock_and_return;
			}
			break;
		}

		case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
		{
			PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN =
				(PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn;
			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);

			if(!psPrivateData->hKernelMemInfo)
			{
				PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no "
						 "associated MemInfo handle", __FUNCTION__));
				err = -EINVAL;
				goto unlock_and_return;
			}

			psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo;
			break;
		}

		default:
		{
			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);

			if(psPrivateData->hKernelMemInfo)
			{
				PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried "
						 "to use privileged service", __FUNCTION__));
				goto unlock_and_return;
			}
			break;
		}
	}
#endif 

	err = BridgedDispatchKM(psPerProc, psBridgePackageKM);
	if(err != PVRSRV_OK)
		goto unlock_and_return;

	switch(cmd)
	{
#if defined(PVR_SECURE_FD_EXPORT)
		case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
		{
			PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT =
				(PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut;
			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);

			psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo;
#if defined(SUPPORT_MEMINFO_IDS)
			psExportDeviceMemOUT->ui64Stamp = psPrivateData->ui64Stamp = ++ui64Stamp;
#endif
			break;
		}
#endif 

#if defined(SUPPORT_MEMINFO_IDS)
		case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
		{
			PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT =
				(PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut;
			PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile);
			psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp =	psPrivateData->ui64Stamp;
			break;
		}

		case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
		{
			PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT =
				(PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut;
			psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp = ++ui64Stamp;
			break;
		}
#endif 

		default:
			break;
	}

unlock_and_return:
	LinuxUnLockMutex(&gPVRSRVLock);
	return err;
}
Ejemplo n.º 15
0
PVRSRV_ERROR OSConnectionPrivateDataInit(IMG_HANDLE *phOsPrivateData, IMG_PVOID pvOSData)
{
	ENV_CONNECTION_DATA *psEnvConnection;
#if defined(SUPPORT_ION)
	ENV_ION_CONNECTION_DATA *psIonConnection;
#endif

	*phOsPrivateData = OSAllocMem(sizeof(ENV_CONNECTION_DATA));

	if (*phOsPrivateData == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __FUNCTION__));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	psEnvConnection = (ENV_CONNECTION_DATA *)*phOsPrivateData;
	OSMemSet(psEnvConnection, 0, sizeof(*psEnvConnection));

	/* Save the pointer to our struct file */
	psEnvConnection->psFile = pvOSData;

#if defined(SUPPORT_ION)
	psIonConnection = (ENV_ION_CONNECTION_DATA *)OSAllocMem(sizeof(ENV_ION_CONNECTION_DATA));
	if (psIonConnection == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed", __FUNCTION__));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psIonConnection, 0, sizeof(*psIonConnection));
	psEnvConnection->psIonData = psIonConnection;
	/*
		We can have more then one connection per process so we need more then
		the PID to have a unique name
	*/
	psEnvConnection->psIonData->psIonDev = IonDevAcquire();
	OSSNPrintf(psEnvConnection->psIonData->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%p-%d", *phOsPrivateData, OSGetCurrentProcessIDKM());
	psEnvConnection->psIonData->psIonClient =
		ion_client_create(psEnvConnection->psIonData->psIonDev,
						  psEnvConnection->psIonData->azIonClientName);
 
	if (IS_ERR_OR_NULL(psEnvConnection->psIonData->psIonClient))
	{
		PVR_DPF((PVR_DBG_ERROR, "OSConnectionPrivateDataInit: Couldn't create "
								"ion client for per connection data"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	psEnvConnection->psIonData->ui32IonClientRefCount = 1;
#endif /* SUPPORT_ION */
	return PVRSRV_OK;
}
Ejemplo n.º 16
0
int alloc_ramdec_region(unsigned long *base_addr0, unsigned long *base_addr1,
				unsigned long size0, unsigned long size1)
{
	unsigned long pid = OSGetCurrentProcessIDKM();
    unsigned long num = 10;
	unsigned long heap_count = 0;
    void *sgx_cookie = NULL;
    unsigned long heapIndex = 0, generalHeapIndex = 0;
	PVRSRV_ERROR err;
	PVRSRV_KERNEL_MEM_INFO *rendec0MemInfo;
	PVRSRV_KERNEL_MEM_INFO *rendec1MemInfo;
	int i;

	printk(KERN_INFO "Calling PVRSRVPerProcessData()\n");
	if (PVRSRVPerProcessDataConnect(200) != PVRSRV_OK) {
		printk(KERN_ERR "msvdx_init: connect to PVR failed\n");
	}

	psPerProc = PVRSRVPerProcessData(200);
	if (psPerProc == IMG_NULL)
	{
		printk(KERN_ERR "msvdx_init:  Couldn't find per process data for pid=%lx\n", pid);
	}

	printk(KERN_INFO "  TEST: pp_data = 0x%p\n", psPerProc);


	PVRSRVEnumerateDevicesKM(&num, dev_id_list);
	printk(KERN_INFO "Calling PVRSRVEnumerateDevicesKM()\n");
	if (PVRSRVEnumerateDevicesKM(&num, dev_id_list) != PVRSRV_OK) {
		printk(KERN_ERR "msvdx_init: PVRSRVEnumerateDevice failed\n");
	} else {
		printk(KERN_INFO "  PVRSRVEnumerateDevicesKM() found %ld devices\n", num);
		for (i = 0 ; i < num ; i++) {
			PVRSRV_DEVICE_IDENTIFIER *id = dev_id_list + i;
			unsigned long cookie = 0;
			printk(KERN_INFO "    Device %d has type %d, class %d & index %ld\n", i,
					id->eDeviceType, id->eDeviceClass, id->ui32DeviceIndex);
			if (PVRSRV_DEVICE_TYPE_EXT != id->eDeviceType) {
				// Call PVRSRVAcquireDeviceDataKM():
				printk(KERN_INFO "Calling PVRSRVAcquireDeviceDataKM()\n");
				err = PVRSRVAcquireDeviceDataKM(id->ui32DeviceIndex,
						PVRSRV_DEVICE_TYPE_UNKNOWN, (void *) &cookie);
				if (err != PVRSRV_OK) {
					printk(KERN_ERR "[EMGD] PVRSRVAcquireDeviceDataKM() "
							"returned %d\n", err);
					break;
				}
				if (PVRSRV_DEVICE_TYPE_SGX == id->eDeviceType) {
					printk(KERN_INFO "  Found cookie = 0x%lx\n", cookie);
					// Save this away for later:
					sgx_cookie = (void *) cookie;
				}
			}
		}
	}

	// Enumerate the display class devices to be able to find the 3DD:
	printk(KERN_INFO "Calling PVRSRVEnumerateDCKM()\n");
	err = PVRSRVEnumerateDCKM(PVRSRV_DEVICE_CLASS_DISPLAY,
			&num, dev_ids);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] PVRSRVEnumerateDCKM() returned %d\n", err);
	} else {
		// Find the 3DD:
		printk(KERN_INFO "  PVRSRVEnumerateDCKM() found %ld devices\n", num);
		for (i = 0 ; i < num ; i++) {
			printk(KERN_INFO "    device %d has ID %ld\n", i, dev_ids[i]);
		}
		if (0 == dev_ids[0]) {
			printk(KERN_ERR "[EMGD] Did not find 3rd-party display driver ID\n");
		}
	}

	// Call PVRSRVCreateDeviceMemContextKM():

	printk(KERN_INFO "Calling PVRSRVCreateDeviceMemContextKM()\n");
	err = PVRSRVCreateDeviceMemContextKM(sgx_cookie, psPerProc,
			&dev_mem_context, &heap_count, heap_info, &mem_created, &dummy);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] PVRSRVCreateDeviceMemContextKM() "
				"returned %d\n", err);
	}


	for (heapIndex=0; heapIndex<heap_count; heapIndex++) {
		if (HEAP_IDX(heap_info[heapIndex].ui32HeapID) == SGX_GENERAL_HEAP_ID)
		{
			generalHeapIndex = heapIndex;
			break;
		}
	}

	if (PVRSRVAllocDeviceMemKM(sgx_cookie, psPerProc, heap_info[generalHeapIndex].hDevMemHeap,
                        PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
                        size0, 0, &rendec0MemInfo, "") != PVRSRV_OK) {
		printk(KERN_ERR "msvdx: PVRSRVAllocDeviceMemKM failed\n");
	}

	if (PVRSRVAllocDeviceMemKM(sgx_cookie, psPerProc, heap_info[generalHeapIndex].hDevMemHeap,
                        PVRSRV_MEM_READ | PVRSRV_MEM_WRITE,
                        size1, 0, &rendec1MemInfo, "") != PVRSRV_OK) {
		printk(KERN_ERR "msvdx: PVRSRVAllocDeviceMemKM failed\n");
	}

	*base_addr0 = rendec0MemInfo->sDevVAddr.uiAddr;
	*base_addr1 = rendec1MemInfo->sDevVAddr.uiAddr;

	//printk(KERN_INFO "pvr size0=%lx, size1=%lx, heap=%ld\n", size0, size1, generalHeapIndex);

//	return PVRSRV_OK;
	return 0;

}
Ejemplo n.º 17
0
/*!
******************************************************************************

 @Function	PVRSRVTimeTraceAllocItem

 @Description

 Allocate a trace item from the buffer of the current process

 @Output ppsTraceItem :	Pointer to allocated trace item

 @Input ui32Size : Size of data packet to be allocated

 @Return none

******************************************************************************/
static IMG_VOID
PVRSRVTimeTraceAllocItem(IMG_UINT32 **pui32Item, IMG_UINT32 ui32Size)
{
	IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM();
	IMG_UINT32 ui32AllocOffset;
	sTimeTraceBuffer *psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);

	/* The caller only asks for extra data space */
	ui32Size += PVRSRV_TRACE_ITEM_SIZE;

	/* Always round to 32-bit */
	ui32Size = ((ui32Size - 1) & (~0x3)) + 0x04;

	if (!psBuffer)
	{
		PVRSRV_ERROR eError;

		PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVTimeTraceAllocItem: Creating buffer for PID %u", (IMG_UINT32) ui32PID));
		eError = PVRSRVTimeTraceBufferCreate(ui32PID);
		if (eError != PVRSRV_OK)
		{
			*pui32Item = IMG_NULL;
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to create buffer"));
			return;
		}
		
		psBuffer = (sTimeTraceBuffer *) HASH_Retrieve(g_psBufferTable, (IMG_UINTPTR_T) ui32PID);
		if (psBuffer == IMG_NULL)
		{
			*pui32Item = NULL;
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Failed to retrieve buffer"));
			return;
		}
	}

	/* Can't allocate more then buffer size */
	if (ui32Size >= TIME_TRACE_BUFFER_SIZE)
	{
		*pui32Item = NULL;
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceAllocItem: Error trace item too large (%d)", ui32Size));
		return;
	}

	/* FIXME: Enter critical section? */

	/* Always ensure we have enough space to write a padding message */
	if ((psBuffer->ui32Woff + ui32Size + PVRSRV_TRACE_ITEM_SIZE) > TIME_TRACE_BUFFER_SIZE)
	{
		IMG_UINT32 *ui32WriteEOB = (IMG_UINT32 *) &psBuffer->pui8Data[psBuffer->ui32Woff];
		IMG_UINT32 ui32Remain = TIME_TRACE_BUFFER_SIZE - psBuffer->ui32Woff;

		/* Not enough space at the end of the buffer, back to the start */
		*ui32WriteEOB++ = WRITE_HEADER(GROUP, PVRSRV_TRACE_GROUP_PADDING);
		*ui32WriteEOB++ = 0;		/* Don't need timestamp */
		*ui32WriteEOB++ = 0;		/* Don't need UID */
		*ui32WriteEOB = WRITE_HEADER(SIZE, (ui32Remain - PVRSRV_TRACE_ITEM_SIZE));
		psBuffer->ui32ByteCount += ui32Remain;
		psBuffer->ui32Woff = ui32AllocOffset = 0;
	}
	else
		ui32AllocOffset = psBuffer->ui32Woff;

	psBuffer->ui32Woff = psBuffer->ui32Woff + ui32Size;
	psBuffer->ui32ByteCount += ui32Size;

	/* This allocation will start overwritting past our read pointer, move the read pointer along */
	while (psBuffer->ui32ByteCount > TIME_TRACE_BUFFER_SIZE)
	{
		IMG_UINT32 *psReadItem = (IMG_UINT32 *) &psBuffer->pui8Data[psBuffer->ui32Roff];
		IMG_UINT32 ui32ReadSize;

		ui32ReadSize = PVRSRVTimeTraceItemSize(psReadItem);
		psBuffer->ui32Roff = (psBuffer->ui32Roff + ui32ReadSize) & (TIME_TRACE_BUFFER_SIZE - 1);
		psBuffer->ui32ByteCount -= ui32ReadSize;
	}

	*pui32Item = (IMG_UINT32 *) &psBuffer->pui8Data[ui32AllocOffset];
	/* FIXME: Exit critical section? */
}
Ejemplo n.º 18
0
IMG_UINT32 psb_get_tgid(void)
{
	return OSGetCurrentProcessIDKM();
}
Ejemplo n.º 19
0
/*
 * Can't call from module initialization, since PVR services are started when
 * the Xorg server starts.
 */
int msvdx_pvr_init(void)
{
	drm_emgd_priv_t        *priv;
	igd_context_t           *context;
	platform_context_plb_t  *platform;
	struct msvdx_pvr_info   *pvr;
	PVRSRV_DEVICE_IDENTIFIER dev_id_list[PVRSRV_MAX_DEVICES];
	IMG_UINT32   pid;
	IMG_UINT32   num_devices;
	IMG_UINT32   i;
	IMG_BOOL     mem_created;
	PVRSRV_ERROR err;
	int ret;

	priv     = gpDrmDevice->dev_private;
	context  = priv->context;
	platform = (platform_context_plb_t *)context->platform_context;

	if (platform->msvdx_pvr) {
		printk(KERN_INFO "[EMGD] MSVDX: PVR services already "
			"initialized\n");
		return 0;
	}

    pvr = kzalloc(sizeof(*pvr), GFP_KERNEL);
	if (!pvr)
		return -ENOMEM;

    /*
	 * Create a dummy kernel thread so that a persistent PVR per process
	 * data could be created.
	 */
	pvr->kthread = kthread_run(msvdx_pvr_kthread, NULL, "msvdx-pvr");
	if (IS_ERR(pvr->kthread)) {
		ret = PTR_ERR(pvr->kthread);
		printk(KERN_ERR "[EMGD] MSVDX: failed to create MSVDX PVR "
			"kernel tread, error=%i\n", ret);
		pvr->kthread = NULL;
		goto out_free;
	}

	ret = -ENODEV;
	pid = OSGetCurrentProcessIDKM(); //(IMG_UINT32)pvr->kthread->pid;
    err = PVRSRVPerProcessDataConnect(pid);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: connect to PVR failed (pid=%u), "
			"error=%i\n", (unsigned int)err, err);
		goto out_stop_kthread;
	}
	pvr->per_proc = PVRSRVPerProcessData(pid);
	if (pvr->per_proc == IMG_NULL) {
		printk(KERN_ERR "[EMGD] MSVDX: Couldn't find per process "
			"data for pid=%u\n", (unsigned int)pid);
		goto out_stop_kthread;
	}

	err = PVRSRVEnumerateDevicesKM(&num_devices, dev_id_list);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: PVRSRVEnumerateDevice() failed, "
			"error=%u\n", (unsigned int)err);
		goto out_stop_kthread;
	}

	for (i = 0 ; i < num_devices ; i++) {
		PVRSRV_DEVICE_IDENTIFIER *id;
		IMG_HANDLE cookie;

		cookie = IMG_NULL;
		id = &dev_id_list[i];

		if (id->eDeviceType != PVRSRV_DEVICE_TYPE_EXT) {
			err = PVRSRVAcquireDeviceDataKM(id->ui32DeviceIndex,
				PVRSRV_DEVICE_TYPE_UNKNOWN, &cookie);
			if (err != PVRSRV_OK) {
				printk(KERN_ERR "[EMGD] MSVDX: "
					"PVRSRVAcquireDeviceDataKM() failed, "
					"error=%u\n", err);
				break;
			}
			if (PVRSRV_DEVICE_TYPE_SGX == id->eDeviceType) {
				pvr->sgx_cookie = cookie;
				break;
			}
		}
	}

	if (pvr->sgx_cookie == IMG_NULL)
		goto out_stop_kthread;

	err = PVRSRVCreateDeviceMemContextKM(pvr->sgx_cookie, pvr->per_proc,
			&pvr->dev_mem_context, &pvr->heap_count,
			pvr->heap_info, &mem_created, pvr->heap_shared);
	if (err != PVRSRV_OK) {
		printk(KERN_ERR "[EMGD] MSVDX: PVRSRVCreateDeviceMemContextKM()"
			" failed, error=%u\n", (unsigned int)err);
		goto out_stop_kthread;
	}

	for (i = 0; i < pvr->heap_count; i++) {
		if (HEAP_IDX(pvr->heap_info[i].ui32HeapID) ==
			SGX_VIDEO_HEAP_ID) {
			pvr->mapping_heap_index = i;
			break;
		}
	}

	platform->msvdx_pvr = pvr;
	pvr->pid = pid;


	return 0;

out_stop_kthread:
	kthread_stop(pvr->kthread);
out_free:
	kfree(pvr);
	return ret;
}
PVRSRV_ERROR OSPerProcessPrivateDataInit(IMG_HANDLE *phOsPrivateData)
{
	PVRSRV_ERROR eError;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;

	eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				sizeof(PVRSRV_ENV_PER_PROCESS_DATA),
				phOsPrivateData,
				&hBlockAlloc,
				"Environment per Process Data");

	if (eError != PVRSRV_OK)
	{
		*phOsPrivateData = IMG_NULL;

		PVR_DPF((PVR_DBG_ERROR, "%s: OSAllocMem failed (%d)", __FUNCTION__, eError));
		return eError;
	}

	psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)*phOsPrivateData;
	OSMemSet(psEnvPerProc, 0, sizeof(*psEnvPerProc));

	psEnvPerProc->hBlockAlloc = hBlockAlloc;

	/* Linux specific mmap processing */
	LinuxMMapPerProcessConnect(psEnvPerProc);

#if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
	/* Linked list of PVRSRV_FILE_PRIVATE_DATA structures */
	INIT_LIST_HEAD(&psEnvPerProc->sDRMAuthListHead);
#endif

#if defined(SUPPORT_ION)
	OSSNPrintf(psEnvPerProc->azIonClientName, ION_CLIENT_NAME_SIZE, "pvr_ion_client-%d", OSGetCurrentProcessIDKM());
	psEnvPerProc->psIONClient =
		ion_client_create(gpsIonDev,
						  psEnvPerProc->azIonClientName);
 
	if (IS_ERR_OR_NULL(psEnvPerProc->psIONClient))
	{
		PVR_DPF((PVR_DBG_ERROR, "OSPerProcessPrivateDataInit: Couldn't create "
								"ion client for per process data"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
#endif /* defined(SUPPORT_ION) */

	return PVRSRV_OK;
}