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;
}
Example #2
0
IMG_EXPORT PVRSRV_ERROR
PVRSRVAllocSharedSysMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
							 IMG_UINT32					ui32Flags,
							 IMG_SIZE_T 				uSize,
							 PVRSRV_KERNEL_MEM_INFO 	**ppsKernelMemInfo)
{
	PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;

	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
				  sizeof(PVRSRV_KERNEL_MEM_INFO),
				  (IMG_VOID **)&psKernelMemInfo, IMG_NULL,
				  "Kernel Memory Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for meminfo"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));

	ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
	ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
	psKernelMemInfo->ui32Flags = ui32Flags;
	psKernelMemInfo->uAllocSize = uSize;

	if(OSAllocPages(psKernelMemInfo->ui32Flags,
					psKernelMemInfo->uAllocSize,
					(IMG_UINT32)HOST_PAGESIZE(),
					IMG_NULL,
					0,
					IMG_NULL,
					&psKernelMemInfo->pvLinAddrKM,
					&psKernelMemInfo->sMemBlk.hOSMemHandle)
		!= PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: Failed to alloc memory for block"));
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
				  sizeof(PVRSRV_KERNEL_MEM_INFO),
				  psKernelMemInfo,
				  0);
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* register with the resman */
	psKernelMemInfo->sMemBlk.hResItem =
				ResManRegisterRes(psPerProc->hResManContext,
								  RESMAN_TYPE_SHARED_MEM_INFO,
								  psKernelMemInfo,
								  0,
								  &FreeSharedSysMemCallBack);

	*ppsKernelMemInfo = psKernelMemInfo;

	return PVRSRV_OK;
}
Example #3
0
static IMG_INT
PVRSRVBridgePMRSecureImportPMR(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_PMRSECUREIMPORTPMR *psPMRSecureImportPMRIN,
					 PVRSRV_BRIDGE_OUT_PMRSECUREIMPORTPMR *psPMRSecureImportPMROUT,
					 CONNECTION_DATA *psConnection)
{
	PMR * psPMRInt;
	IMG_HANDLE hPMRInt2;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SMM_PMRSECUREIMPORTPMR);


	NEW_HANDLE_BATCH_OR_ERROR(psPMRSecureImportPMROUT->eError, psConnection, 1);


	psPMRSecureImportPMROUT->eError =
		PMRSecureImportPMR(
					psPMRSecureImportPMRIN->Export,
					&psPMRInt,
					&psPMRSecureImportPMROUT->uiSize,
					&psPMRSecureImportPMROUT->sAlign);
	/* Exit early if bridged call fails */
	if(psPMRSecureImportPMROUT->eError != PVRSRV_OK)
	{
		goto PMRSecureImportPMR_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hPMRInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_PMR,
												psPMRInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PMRUnrefPMR);
	if (hPMRInt2 == IMG_NULL)
	{
		psPMRSecureImportPMROUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto PMRSecureImportPMR_exit;
	}
	PVRSRVAllocHandleNR(psConnection->psHandleBase,
					  &psPMRSecureImportPMROUT->hPMR,
					  (IMG_HANDLE) hPMRInt2,
					  PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
					  PVRSRV_HANDLE_ALLOC_FLAG_NONE
					  );
	COMMIT_HANDLE_BATCH_OR_ERROR(psPMRSecureImportPMROUT->eError, psConnection);



PMRSecureImportPMR_exit:

	return 0;
}
/*!
******************************************************************************

 @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;	 
}
enum PVRSRV_ERROR PVRSRVAllocSharedSysMemoryKM(
			struct PVRSRV_PER_PROCESS_DATA *psPerProc,
			u32 ui32Flags, u32 ui32Size,
			struct PVRSRV_KERNEL_MEM_INFO **ppsKernelMemInfo)
{
	struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **) &psKernelMemInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: "
					"Failed to alloc memory for meminfo");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psKernelMemInfo, 0, sizeof(*psKernelMemInfo));

	ui32Flags &= ~PVRSRV_HAP_MAPTYPE_MASK;
	ui32Flags |= PVRSRV_HAP_MULTI_PROCESS;
	psKernelMemInfo->ui32Flags = ui32Flags;
	psKernelMemInfo->ui32AllocSize = ui32Size;

	if (OSAllocPages(psKernelMemInfo->ui32Flags,
			 psKernelMemInfo->ui32AllocSize, HOST_PAGESIZE(),
			 &psKernelMemInfo->pvLinAddrKM,
			 &psKernelMemInfo->sMemBlk.hOSMemHandle) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVAllocSharedSysMemoryKM: "
					"Failed to alloc memory for block");
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_KERNEL_MEM_INFO),
			  psKernelMemInfo, NULL);
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	psKernelMemInfo->sMemBlk.hResItem = ResManRegisterRes(
					psPerProc->hResManContext,
					RESMAN_TYPE_SHARED_MEM_INFO,
					psKernelMemInfo, 0,
					FreeSharedSysMemCallBack);

	*ppsKernelMemInfo = psKernelMemInfo;

	return PVRSRV_OK;
}
static IMG_INT
PVRSRVBridgeAllocSyncPrimitiveBlock(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockIN,
					 PVRSRV_BRIDGE_OUT_ALLOCSYNCPRIMITIVEBLOCK *psAllocSyncPrimitiveBlockOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_HANDLE hDevNodeInt = IMG_NULL;
	SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL;
	IMG_HANDLE hSyncHandleInt2 = IMG_NULL;
	DEVMEM_EXPORTCOOKIE * psExportCookieInt = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_ALLOCSYNCPRIMITIVEBLOCK);



	psAllocSyncPrimitiveBlockOUT->hSyncHandle = IMG_NULL;


				{
					/* Look up the address from the handle */
					psAllocSyncPrimitiveBlockOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hDevNodeInt,
											psAllocSyncPrimitiveBlockIN->hDevNode,
											PVRSRV_HANDLE_TYPE_DEV_NODE);
					if(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
					{
						goto AllocSyncPrimitiveBlock_exit;
					}

				}

	psAllocSyncPrimitiveBlockOUT->eError =
		PVRSRVAllocSyncPrimitiveBlockKM(psConnection,
					hDevNodeInt,
					&psSyncHandleInt,
					&psAllocSyncPrimitiveBlockOUT->ui32SyncPrimVAddr,
					&psAllocSyncPrimitiveBlockOUT->ui32SyncPrimBlockSize,
					&psExportCookieInt);
	/* Exit early if bridged call fails */
	if(psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
	{
		goto AllocSyncPrimitiveBlock_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hSyncHandleInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_SYNC_PRIMITIVE_BLOCK,
												psSyncHandleInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PVRSRVFreeSyncPrimitiveBlockKM);
	if (hSyncHandleInt2 == IMG_NULL)
	{
		psAllocSyncPrimitiveBlockOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto AllocSyncPrimitiveBlock_exit;
	}
	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psAllocSyncPrimitiveBlockOUT->hSyncHandle,
							(IMG_HANDLE) hSyncHandleInt2,
							PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
	{
		goto AllocSyncPrimitiveBlock_exit;
	}
	psAllocSyncPrimitiveBlockOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
							&psAllocSyncPrimitiveBlockOUT->hExportCookie,
							(IMG_HANDLE) psExportCookieInt,
							PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							,psAllocSyncPrimitiveBlockOUT->hSyncHandle);
	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
	{
		goto AllocSyncPrimitiveBlock_exit;
	}


AllocSyncPrimitiveBlock_exit:
	if (psAllocSyncPrimitiveBlockOUT->eError != PVRSRV_OK)
	{
		if (psAllocSyncPrimitiveBlockOUT->hSyncHandle)
		{
			PVRSRVReleaseHandle(psConnection->psHandleBase,
						(IMG_HANDLE) psAllocSyncPrimitiveBlockOUT->hSyncHandle,
						PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
		}

		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hSyncHandleInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hSyncHandleInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psSyncHandleInt)
		{
			PVRSRVFreeSyncPrimitiveBlockKM(psSyncHandleInt);
		}
	}


	return 0;
}
Example #7
0
enum PVRSRV_ERROR SGXFindSharedPBDescKM(
	     struct PVRSRV_PER_PROCESS_DATA *psPerProc,
	     void *hDevCookie, IMG_BOOL bLockOnFailure,
	     u32 ui32TotalPBSize, void **phSharedPBDesc,
	     struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescKernelMemInfo,
	     struct PVRSRV_KERNEL_MEM_INFO **ppsHWPBDescKernelMemInfo,
	     struct PVRSRV_KERNEL_MEM_INFO **ppsBlockKernelMemInfo,
	     struct PVRSRV_KERNEL_MEM_INFO ***pppsSharedPBDescSubKernelMemInfos,
	     u32 *ui32SharedPBDescSubKernelMemInfosCount)
{
	struct PVRSRV_STUB_PBDESC *psStubPBDesc;
	struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos = NULL;
	struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
	enum PVRSRV_ERROR eError;

	psSGXDevInfo = ((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;

	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
	if (psStubPBDesc != NULL) {
		u32 i;
		struct RESMAN_ITEM *psResItem;

		if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) {
			PVR_DPF(PVR_DBG_WARNING, "SGXFindSharedPBDescKM: "
				"Shared PB requested with different size "
				"(0x%x) from existing shared PB (0x%x) - "
				"requested size ignored",
				 ui32TotalPBSize,
				 psStubPBDesc->ui32TotalPBSize);
		}

		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
			       sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
				      psStubPBDesc->ui32SubKernelMemInfosCount,
			       (void **) &ppsSharedPBDescSubKernelMemInfos,
			       NULL) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR,
				 "SGXFindSharedPBDescKM: OSAllocMem failed");

				eError = PVRSRV_ERROR_OUT_OF_MEMORY;
				goto ExitNotFound;
			}

			psResItem = ResManRegisterRes(psPerProc->hResManContext,
					      RESMAN_TYPE_SHARED_PB_DESC,
					      psStubPBDesc, 0,
					      &SGXCleanupSharedPBDescCallback);

			if (psResItem == NULL) {
				OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				  sizeof(struct PVRSRV_KERNEL_MEM_INFO *)*
				  psStubPBDesc->ui32SubKernelMemInfosCount,
				  ppsSharedPBDescSubKernelMemInfos, NULL);

			PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM: "
						"ResManRegisterRes failed");
				eError = PVRSRV_ERROR_GENERIC;
				goto ExitNotFound;
			}

			*ppsSharedPBDescKernelMemInfo =
			    psStubPBDesc->psSharedPBDescKernelMemInfo;
			*ppsHWPBDescKernelMemInfo =
			    psStubPBDesc->psHWPBDescKernelMemInfo;
			*ppsBlockKernelMemInfo =
			    psStubPBDesc->psBlockKernelMemInfo;

			*ui32SharedPBDescSubKernelMemInfosCount =
			    psStubPBDesc->ui32SubKernelMemInfosCount;

			*pppsSharedPBDescSubKernelMemInfos =
			    ppsSharedPBDescSubKernelMemInfos;

			for (i = 0;
			     i < psStubPBDesc->ui32SubKernelMemInfosCount;
			     i++) {
				ppsSharedPBDescSubKernelMemInfos[i] =
				    psStubPBDesc->ppsSubKernelMemInfos[i];
			}

			psStubPBDesc->ui32RefCount++;
			*phSharedPBDesc = (void *) psResItem;
			return PVRSRV_OK;
		}

		eError = PVRSRV_OK;
		if (bLockOnFailure) {
			if (psResItemCreateSharedPB == NULL) {
				psResItemCreateSharedPB =
				    ResManRegisterRes(psPerProc->hResManContext,
				     RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
				     psPerProc, 0,
				     &SGXCleanupSharedPBDescCreateLockCallback);

			if (psResItemCreateSharedPB == NULL) {
				PVR_DPF(PVR_DBG_ERROR, "SGXFindSharedPBDescKM: "
						"ResManRegisterRes failed");

				eError = PVRSRV_ERROR_GENERIC;
				goto ExitNotFound;
			}
			PVR_ASSERT(psPerProcCreateSharedPB == NULL);
			psPerProcCreateSharedPB = psPerProc;
		} else {
			eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
		}
	}
ExitNotFound:
	*phSharedPBDesc = NULL;

	return eError;
}
Example #8
0
IMG_EXPORT PVRSRV_ERROR
SGXAddSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
					 IMG_HANDLE					hDevCookie,
					 PVRSRV_KERNEL_MEM_INFO		*psSharedPBDescKernelMemInfo,
					 PVRSRV_KERNEL_MEM_INFO		*psHWPBDescKernelMemInfo,
					 PVRSRV_KERNEL_MEM_INFO		*psBlockKernelMemInfo,
					 PVRSRV_KERNEL_MEM_INFO		*psHWBlockKernelMemInfo,
					 IMG_UINT32					ui32TotalPBSize,
					 IMG_HANDLE					*phSharedPBDesc,
					 PVRSRV_KERNEL_MEM_INFO		**ppsSharedPBDescSubKernelMemInfos,
					 IMG_UINT32					ui32SharedPBDescSubKernelMemInfosCount,
					 IMG_DEV_VIRTADDR			sHWPBDescDevVAddr)
{
	PVRSRV_STUB_PBDESC *psStubPBDesc=IMG_NULL;
	PVRSRV_ERROR eRet = PVRSRV_ERROR_INVALID_PERPROC;
	IMG_UINT32 i;
	PVRSRV_SGXDEV_INFO *psSGXDevInfo;
	PRESMAN_ITEM psResItem;


	if (psPerProcCreateSharedPB != psPerProc)
	{
		goto NoAdd;
	}
	else
	{
		PVR_ASSERT(psResItemCreateSharedPB != IMG_NULL);

		ResManFreeResByPtr(psResItemCreateSharedPB, CLEANUP_WITH_POLL);

		PVR_ASSERT(psResItemCreateSharedPB == IMG_NULL);
		PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
	}

	psSGXDevInfo = (PVRSRV_SGXDEV_INFO *)((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;

	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
	if (psStubPBDesc != IMG_NULL)
	{
		if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
		{
			PVR_DPF((PVR_DBG_WARNING,
					"SGXAddSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
					ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));

		}


		psResItem = ResManRegisterRes(psPerProc->hResManContext,
									  RESMAN_TYPE_SHARED_PB_DESC,
									  psStubPBDesc,
									  0,
									  &SGXCleanupSharedPBDescCallback);
		if (psResItem == IMG_NULL)
		{
			PVR_DPF((PVR_DBG_ERROR,
				"SGXAddSharedPBDescKM: "
				"Failed to register existing shared "
				"PBDesc with the resource manager"));
			goto NoAddKeepPB;
		}


		psStubPBDesc->ui32RefCount++;

		*phSharedPBDesc = (IMG_HANDLE)psResItem;
		eRet = PVRSRV_OK;
		goto NoAddKeepPB;
	}

	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				  sizeof(PVRSRV_STUB_PBDESC),
				  (IMG_VOID **)&psStubPBDesc,
				  0,
				  "Stub Parameter Buffer Description") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
					"StubPBDesc"));
		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto NoAdd;
	}


	psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;

	if(OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				  sizeof(PVRSRV_KERNEL_MEM_INFO *)
				  * ui32SharedPBDescSubKernelMemInfosCount,
				  (IMG_VOID **)&psStubPBDesc->ppsSubKernelMemInfos,
				  0,
				  "Array of Kernel Memory Info") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
				 "Failed to alloc "
				 "StubPBDesc->ppsSubKernelMemInfos"));
		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto NoAdd;
	}

	if(PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
	   != PVRSRV_OK)
	{
		goto NoAdd;
	}

	if(PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
	   != PVRSRV_OK)
	{
		goto NoAdd;
	}

	if(PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
	   != PVRSRV_OK)
	{
		goto NoAdd;
	}

	if(PVRSRVDissociateMemFromResmanKM(psHWBlockKernelMemInfo)
	   != PVRSRV_OK)
	{
		goto NoAdd;
	}

	psStubPBDesc->ui32RefCount = 1;
	psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
	psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
	psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
	psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;
	psStubPBDesc->psHWBlockKernelMemInfo = psHWBlockKernelMemInfo;

	psStubPBDesc->ui32SubKernelMemInfosCount =
		ui32SharedPBDescSubKernelMemInfosCount;
	for(i=0; i<ui32SharedPBDescSubKernelMemInfosCount; i++)
	{
		psStubPBDesc->ppsSubKernelMemInfos[i] = ppsSharedPBDescSubKernelMemInfos[i];
		if(PVRSRVDissociateMemFromResmanKM(ppsSharedPBDescSubKernelMemInfos[i])
		   != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
					 "Failed to dissociate shared PBDesc "
					 "from process"));
			goto NoAdd;
		}
	}

	psStubPBDesc->sHWPBDescDevVAddr = sHWPBDescDevVAddr;

	psResItem = ResManRegisterRes(psPerProc->hResManContext,
								  RESMAN_TYPE_SHARED_PB_DESC,
								  psStubPBDesc,
								  0,
								  &SGXCleanupSharedPBDescCallback);
	if (psResItem == IMG_NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
					 "Failed to register shared PBDesc "
					 " with the resource manager"));
		goto NoAdd;
	}
	psStubPBDesc->hDevCookie = hDevCookie;


	List_PVRSRV_STUB_PBDESC_Insert(&(psSGXDevInfo->psStubPBDescListKM),
									psStubPBDesc);

	*phSharedPBDesc = (IMG_HANDLE)psResItem;

	return PVRSRV_OK;

NoAdd:
	if(psStubPBDesc)
	{
		if(psStubPBDesc->ppsSubKernelMemInfos)
		{
			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
					  sizeof(PVRSRV_KERNEL_MEM_INFO *) * ui32SharedPBDescSubKernelMemInfosCount,
					  psStubPBDesc->ppsSubKernelMemInfos,
					  0);
			psStubPBDesc->ppsSubKernelMemInfos = IMG_NULL;
		}
		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				  sizeof(PVRSRV_STUB_PBDESC),
				  psStubPBDesc,
				  0);

	}

NoAddKeepPB:
	for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
	{
		PVRSRVFreeDeviceMemKM(hDevCookie, ppsSharedPBDescSubKernelMemInfos[i]);
	}

	PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
	PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);

	PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);
	PVRSRVFreeDeviceMemKM(hDevCookie, psHWBlockKernelMemInfo);

	return eRet;
}
Example #9
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;
}
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;
}
enum PVRSRV_ERROR PVRSRVMapDeviceClassMemoryKM(
				struct PVRSRV_PER_PROCESS_DATA *psPerProc,
				void *hDevMemContext, void *hDeviceClassBuffer,
				struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo,
				void **phOSMapInfo)
{
	enum PVRSRV_ERROR eError;
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
	struct PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
	struct IMG_SYS_PHYADDR *psSysPAddr;
	void *pvCPUVAddr, *pvPageAlignedCPUVAddr;
	IMG_BOOL bPhysContig;
	struct BM_CONTEXT *psBMContext;
	struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
	struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
	void *hDevMemHeap = NULL;
	u32 ui32ByteSize;
	u32 ui32Offset;
	u32 ui32PageSize = HOST_PAGESIZE();
	void *hBuffer;
	struct PVRSRV_MEMBLK *psMemBlock;
	IMG_BOOL bBMError;
	u32 i;

	if (!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo ||
	    !hDevMemContext) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVMapDeviceClassMemoryKM: invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psDeviceClassBuffer = (struct PVRSRV_DEVICECLASS_BUFFER *)
							hDeviceClassBuffer;

	eError =
	    psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->
						  hExtDevice,
						  psDeviceClassBuffer->
						  hExtBuffer, &psSysPAddr,
						  &ui32ByteSize,
						  (void __iomem **)&pvCPUVAddr,
						  phOSMapInfo, &bPhysContig);
	if (eError != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"unable to get buffer address");
		return PVRSRV_ERROR_GENERIC;
	}

	psBMContext = (struct BM_CONTEXT *)psDeviceClassBuffer->hDevMemContext;
	psDevMemoryInfo = &psBMContext->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 == NULL) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"unable to find mapping heap");
		return PVRSRV_ERROR_GENERIC;
	}

	ui32Offset = ((u32)pvCPUVAddr) & (ui32PageSize - 1);
	pvPageAlignedCPUVAddr = (void *)((u8 *)pvCPUVAddr - ui32Offset);

	if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **)&psMemInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceClassMemoryKM: "
					"Failed to alloc memory for block");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap, ui32ByteSize, ui32Offset, bPhysContig,
			   psSysPAddr, pvPageAlignedCPUVAddr,
			   &psMemInfo->ui32Flags, &hBuffer);

	if (!bBMError) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed");
		OSFreeMem(PVRSRV_PAGEABLE_SELECT,
			  sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
			  NULL);
		return PVRSRV_ERROR_BAD_MAPPING;
	}

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

	psMemBlock->hBuffer = (void *) hBuffer;

	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);

	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;
	psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;

	psMemInfo->pvSysBackupBuffer = NULL;

	psMemInfo->sMemBlk.hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_DEVICECLASSMEM_MAPPING, psMemInfo, 0,
			      UnmapDeviceClassMemoryCallBack);

	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;
}
static IMG_INT
PVRSRVBridgeTLOpenStream(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_TLOPENSTREAM *psTLOpenStreamIN,
					 PVRSRV_BRIDGE_OUT_TLOPENSTREAM *psTLOpenStreamOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_CHAR *uiNameInt = IMG_NULL;
	TL_STREAM_DESC * psSDInt = IMG_NULL;
	IMG_HANDLE hSDInt2 = IMG_NULL;
	DEVMEM_EXPORTCOOKIE * psClientBUFExportCookieInt = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PVRTL_TLOPENSTREAM);



	psTLOpenStreamOUT->hSD = IMG_NULL;

	
	{
		uiNameInt = OSAllocMem(PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR));
		if (!uiNameInt)
		{
			psTLOpenStreamOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto TLOpenStream_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psTLOpenStreamIN->puiName, PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR))
				|| (OSCopyFromUser(NULL, uiNameInt, psTLOpenStreamIN->puiName,
				PRVSRVTL_MAX_STREAM_NAME_SIZE * sizeof(IMG_CHAR)) != PVRSRV_OK) )
			{
				psTLOpenStreamOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto TLOpenStream_exit;
			}

	psTLOpenStreamOUT->eError =
		TLServerOpenStreamKM(
					uiNameInt,
					psTLOpenStreamIN->ui32Mode,
					&psSDInt,
					&psClientBUFExportCookieInt);
	/* Exit early if bridged call fails */
	if(psTLOpenStreamOUT->eError != PVRSRV_OK)
	{
		goto TLOpenStream_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hSDInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_TL_STREAM_DESC,
												psSDInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&TLServerCloseStreamKM);
	if (hSDInt2 == IMG_NULL)
	{
		psTLOpenStreamOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto TLOpenStream_exit;
	}
	psTLOpenStreamOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psTLOpenStreamOUT->hSD,
							(IMG_HANDLE) hSDInt2,
							PVRSRV_HANDLE_TYPE_PVR_TL_SD,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
	{
		goto TLOpenStream_exit;
	}
	psTLOpenStreamOUT->eError = PVRSRVAllocSubHandle(psConnection->psHandleBase,
							&psTLOpenStreamOUT->hClientBUFExportCookie,
							(IMG_HANDLE) psClientBUFExportCookieInt,
							PVRSRV_HANDLE_TYPE_SERVER_EXPORTCOOKIE,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							,psTLOpenStreamOUT->hSD);
	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
	{
		goto TLOpenStream_exit;
	}


TLOpenStream_exit:
	if (psTLOpenStreamOUT->eError != PVRSRV_OK)
	{
		if (psTLOpenStreamOUT->hSD)
		{
			PVRSRVReleaseHandle(psConnection->psHandleBase,
						(IMG_HANDLE) psTLOpenStreamOUT->hSD,
						PVRSRV_HANDLE_TYPE_PVR_TL_SD);
		}

		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hSDInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hSDInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psSDInt)
		{
			TLServerCloseStreamKM(psSDInt);
		}
	}

	if (uiNameInt)
		OSFreeMem(uiNameInt);

	return 0;
}
static IMG_INT
PVRSRVBridgeRGXCreateComputeContext(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextIN,
					 PVRSRV_BRIDGE_OUT_RGXCREATECOMPUTECONTEXT *psRGXCreateComputeContextOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_HANDLE hDevNodeInt = IMG_NULL;
	IMG_BYTE *psFrameworkCmdInt = IMG_NULL;
	IMG_HANDLE hPrivDataInt = IMG_NULL;
	RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL;
	IMG_HANDLE hComputeContextInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RGXCMP_RGXCREATECOMPUTECONTEXT);




	if (psRGXCreateComputeContextIN->ui32FrameworkCmdize != 0)
	{
		psFrameworkCmdInt = OSAllocMem(psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
		if (!psFrameworkCmdInt)
		{
			psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;

			goto RGXCreateComputeContext_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateComputeContextIN->psFrameworkCmd, psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
				|| (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateComputeContextIN->psFrameworkCmd,
				psRGXCreateComputeContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
			{
				psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto RGXCreateComputeContext_exit;
			}

				{
					/* Look up the address from the handle */
					psRGXCreateComputeContextOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hDevNodeInt,
											psRGXCreateComputeContextIN->hDevNode,
											PVRSRV_HANDLE_TYPE_DEV_NODE);
					if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
					{
						goto RGXCreateComputeContext_exit;
					}

				}

				{
					/* Look up the address from the handle */
					psRGXCreateComputeContextOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hPrivDataInt,
											psRGXCreateComputeContextIN->hPrivData,
											PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
					if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
					{
						goto RGXCreateComputeContext_exit;
					}

				}

	psRGXCreateComputeContextOUT->eError =
		PVRSRVRGXCreateComputeContextKM(psConnection,
					hDevNodeInt,
					psRGXCreateComputeContextIN->ui32Priority,
					psRGXCreateComputeContextIN->sMCUFenceAddr,
					psRGXCreateComputeContextIN->ui32FrameworkCmdize,
					psFrameworkCmdInt,
					hPrivDataInt,
					&psComputeContextInt);
	/* Exit early if bridged call fails */
	if(psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
	{
		goto RGXCreateComputeContext_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hComputeContextInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
												psComputeContextInt,
												(RESMAN_FREE_FN)&PVRSRVRGXDestroyComputeContextKM);
	if (hComputeContextInt2 == IMG_NULL)
	{
		psRGXCreateComputeContextOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto RGXCreateComputeContext_exit;
	}
	psRGXCreateComputeContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psRGXCreateComputeContextOUT->hComputeContext,
							(IMG_HANDLE) hComputeContextInt2,
							PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
	{
		goto RGXCreateComputeContext_exit;
	}


RGXCreateComputeContext_exit:
	if (psRGXCreateComputeContextOUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hComputeContextInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hComputeContextInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psComputeContextInt)
		{
			PVRSRVRGXDestroyComputeContextKM(psComputeContextInt);
		}
	}

	if (psFrameworkCmdInt)
		OSFreeMem(psFrameworkCmdInt);

	return 0;
}
static IMG_INT
PVRSRVBridgeEventObjectOpen(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_EVENTOBJECTOPEN *psEventObjectOpenIN,
					 PVRSRV_BRIDGE_OUT_EVENTOBJECTOPEN *psEventObjectOpenOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_HANDLE hEventObjectInt = IMG_NULL;
	IMG_HANDLE hEventObjectInt2 = IMG_NULL;
	IMG_HANDLE hOSEventInt = IMG_NULL;
	IMG_HANDLE hOSEventInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTOPEN);





				{
					/* Look up the address from the handle */
					psEventObjectOpenOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hEventObjectInt2,
											psEventObjectOpenIN->hEventObject,
											PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
					if(psEventObjectOpenOUT->eError != PVRSRV_OK)
					{
						goto EventObjectOpen_exit;
					}

					/* Look up the data from the resman address */
					psEventObjectOpenOUT->eError = ResManFindPrivateDataByPtr(hEventObjectInt2, (IMG_VOID **) &hEventObjectInt);

					if(psEventObjectOpenOUT->eError != PVRSRV_OK)
					{
						goto EventObjectOpen_exit;
					}
				}

	psEventObjectOpenOUT->eError =
		OSEventObjectOpen(
					hEventObjectInt,
					&hOSEventInt);
	/* Exit early if bridged call fails */
	if(psEventObjectOpenOUT->eError != PVRSRV_OK)
	{
		goto EventObjectOpen_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hOSEventInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_EVENT_OBJECT,
												hOSEventInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&OSEventObjectClose);
	if (hOSEventInt2 == IMG_NULL)
	{
		psEventObjectOpenOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto EventObjectOpen_exit;
	}
	psEventObjectOpenOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psEventObjectOpenOUT->hOSEvent,
							(IMG_HANDLE) hOSEventInt2,
							PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
							PVRSRV_HANDLE_ALLOC_FLAG_MULTI
							);
	if (psEventObjectOpenOUT->eError != PVRSRV_OK)
	{
		goto EventObjectOpen_exit;
	}


EventObjectOpen_exit:
	if (psEventObjectOpenOUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hOSEventInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hOSEventInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (hOSEventInt)
		{
			OSEventObjectClose(hOSEventInt);
		}
	}


	return 0;
}
static IMG_INT
PVRSRVBridgeAcquireGlobalEventObject(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectIN,
					 PVRSRV_BRIDGE_OUT_ACQUIREGLOBALEVENTOBJECT *psAcquireGlobalEventObjectOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_HANDLE hGlobalEventObjectInt = IMG_NULL;
	IMG_HANDLE hGlobalEventObjectInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT);

	PVR_UNREFERENCED_PARAMETER(psAcquireGlobalEventObjectIN);




	psAcquireGlobalEventObjectOUT->eError =
		AcquireGlobalEventObjectServer(
					&hGlobalEventObjectInt);
	/* Exit early if bridged call fails */
	if(psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
	{
		goto AcquireGlobalEventObject_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hGlobalEventObjectInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_SHARED_EVENT_OBJECT,
												hGlobalEventObjectInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&ReleaseGlobalEventObjectServer);
	if (hGlobalEventObjectInt2 == IMG_NULL)
	{
		psAcquireGlobalEventObjectOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto AcquireGlobalEventObject_exit;
	}
	psAcquireGlobalEventObjectOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psAcquireGlobalEventObjectOUT->hGlobalEventObject,
							(IMG_HANDLE) hGlobalEventObjectInt2,
							PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
							PVRSRV_HANDLE_ALLOC_FLAG_SHARED
							);
	if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
	{
		goto AcquireGlobalEventObject_exit;
	}


AcquireGlobalEventObject_exit:
	if (psAcquireGlobalEventObjectOUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hGlobalEventObjectInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hGlobalEventObjectInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (hGlobalEventObjectInt)
		{
			ReleaseGlobalEventObjectServer(hGlobalEventObjectInt);
		}
	}


	return 0;
}
static IMG_INT
PVRSRVBridgePMRSecureExportPMR(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_PMRSECUREEXPORTPMR *psPMRSecureExportPMRIN,
					 PVRSRV_BRIDGE_OUT_PMRSECUREEXPORTPMR *psPMRSecureExportPMROUT,
					 CONNECTION_DATA *psConnection)
{
	PMR * psPMRInt = IMG_NULL;
	IMG_HANDLE hPMRInt2 = IMG_NULL;
	PMR * psPMROutInt = IMG_NULL;
	IMG_HANDLE hPMROutInt2 = IMG_NULL;
	CONNECTION_DATA *psSecureConnection;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SMM_PMRSECUREEXPORTPMR);





				{
					/* Look up the address from the handle */
					psPMRSecureExportPMROUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hPMRInt2,
											psPMRSecureExportPMRIN->hPMR,
											PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
					if(psPMRSecureExportPMROUT->eError != PVRSRV_OK)
					{
						goto PMRSecureExportPMR_exit;
					}

					/* Look up the data from the resman address */
					psPMRSecureExportPMROUT->eError = ResManFindPrivateDataByPtr(hPMRInt2, (IMG_VOID **) &psPMRInt);

					if(psPMRSecureExportPMROUT->eError != PVRSRV_OK)
					{
						goto PMRSecureExportPMR_exit;
					}
				}

	psPMRSecureExportPMROUT->eError =
		PMRSecureExportPMR(psConnection,
					psPMRInt,
					&psPMRSecureExportPMROUT->Export,
					&psPMROutInt, &psSecureConnection);
	/* Exit early if bridged call fails */
	if(psPMRSecureExportPMROUT->eError != PVRSRV_OK)
	{
		goto PMRSecureExportPMR_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hPMROutInt2 = ResManRegisterRes(psSecureConnection->hResManContext,
												RESMAN_TYPE_PMR,
												psPMROutInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PMRSecureUnexportPMR);
	if (hPMROutInt2 == IMG_NULL)
	{
		psPMRSecureExportPMROUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto PMRSecureExportPMR_exit;
	}


PMRSecureExportPMR_exit:
	if (psPMRSecureExportPMROUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hPMROutInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hPMROutInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psPMROutInt)
		{
			PMRSecureUnexportPMR(psPMROutInt);
		}
	}


	return 0;
}
static IMG_INT
PVRSRVBridgePMRSecureImportPMR(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_PMRSECUREIMPORTPMR *psPMRSecureImportPMRIN,
					 PVRSRV_BRIDGE_OUT_PMRSECUREIMPORTPMR *psPMRSecureImportPMROUT,
					 CONNECTION_DATA *psConnection)
{
	PMR * psPMRInt = IMG_NULL;
	IMG_HANDLE hPMRInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SMM_PMRSECUREIMPORTPMR);





	psPMRSecureImportPMROUT->eError =
		PMRSecureImportPMR(
					psPMRSecureImportPMRIN->Export,
					&psPMRInt,
					&psPMRSecureImportPMROUT->uiSize,
					&psPMRSecureImportPMROUT->sAlign);
	/* Exit early if bridged call fails */
	if(psPMRSecureImportPMROUT->eError != PVRSRV_OK)
	{
		goto PMRSecureImportPMR_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hPMRInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_PMR,
												psPMRInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PMRUnrefPMR);
	if (hPMRInt2 == IMG_NULL)
	{
		psPMRSecureImportPMROUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto PMRSecureImportPMR_exit;
	}
	psPMRSecureImportPMROUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psPMRSecureImportPMROUT->hPMR,
							(IMG_HANDLE) hPMRInt2,
							PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psPMRSecureImportPMROUT->eError != PVRSRV_OK)
	{
		goto PMRSecureImportPMR_exit;
	}


PMRSecureImportPMR_exit:
	if (psPMRSecureImportPMROUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hPMRInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hPMRInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psPMRInt)
		{
			PMRUnrefPMR(psPMRInt);
		}
	}


	return 0;
}
static IMG_INT
PVRSRVBridgeServerSyncAlloc(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_SERVERSYNCALLOC *psServerSyncAllocIN,
					 PVRSRV_BRIDGE_OUT_SERVERSYNCALLOC *psServerSyncAllocOUT,
					 CONNECTION_DATA *psConnection)
{
	IMG_HANDLE hDevNodeInt = IMG_NULL;
	SERVER_SYNC_PRIMITIVE * psSyncHandleInt = IMG_NULL;
	IMG_HANDLE hSyncHandleInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SERVERSYNCALLOC);





				{
					/* Look up the address from the handle */
					psServerSyncAllocOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hDevNodeInt,
											psServerSyncAllocIN->hDevNode,
											PVRSRV_HANDLE_TYPE_DEV_NODE);
					if(psServerSyncAllocOUT->eError != PVRSRV_OK)
					{
						goto ServerSyncAlloc_exit;
					}

				}

	psServerSyncAllocOUT->eError =
		PVRSRVServerSyncAllocKM(
					hDevNodeInt,
					&psSyncHandleInt,
					&psServerSyncAllocOUT->ui32SyncPrimVAddr);
	/* Exit early if bridged call fails */
	if(psServerSyncAllocOUT->eError != PVRSRV_OK)
	{
		goto ServerSyncAlloc_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hSyncHandleInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_SERVER_SYNC_PRIMITIVE,
												psSyncHandleInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PVRSRVServerSyncFreeKM);
	if (hSyncHandleInt2 == IMG_NULL)
	{
		psServerSyncAllocOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto ServerSyncAlloc_exit;
	}
	psServerSyncAllocOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psServerSyncAllocOUT->hSyncHandle,
							(IMG_HANDLE) hSyncHandleInt2,
							PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psServerSyncAllocOUT->eError != PVRSRV_OK)
	{
		goto ServerSyncAlloc_exit;
	}


ServerSyncAlloc_exit:
	if (psServerSyncAllocOUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hSyncHandleInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hSyncHandleInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psSyncHandleInt)
		{
			PVRSRVServerSyncFreeKM(psSyncHandleInt);
		}
	}


	return 0;
}
static IMG_INT
PVRSRVBridgeSyncPrimOpCreate(IMG_UINT32 ui32BridgeID,
					 PVRSRV_BRIDGE_IN_SYNCPRIMOPCREATE *psSyncPrimOpCreateIN,
					 PVRSRV_BRIDGE_OUT_SYNCPRIMOPCREATE *psSyncPrimOpCreateOUT,
					 CONNECTION_DATA *psConnection)
{
	SYNC_PRIMITIVE_BLOCK * *psBlockListInt = IMG_NULL;
	IMG_HANDLE *hBlockListInt2 = IMG_NULL;
	IMG_UINT32 *ui32SyncBlockIndexInt = IMG_NULL;
	IMG_UINT32 *ui32IndexInt = IMG_NULL;
	SERVER_SYNC_PRIMITIVE * *psServerSyncInt = IMG_NULL;
	IMG_HANDLE *hServerSyncInt2 = IMG_NULL;
	SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL;
	IMG_HANDLE hServerCookieInt2 = IMG_NULL;

	PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPCREATE);




	if (psSyncPrimOpCreateIN->ui32SyncBlockCount != 0)
	{
		psBlockListInt = OSAllocMem(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
		if (!psBlockListInt)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
		hBlockListInt2 = OSAllocMem(psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE));
		if (!hBlockListInt2)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->phBlockList, psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE))
				|| (OSCopyFromUser(NULL, hBlockListInt2, psSyncPrimOpCreateIN->phBlockList,
				psSyncPrimOpCreateIN->ui32SyncBlockCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
			{
				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto SyncPrimOpCreate_exit;
			}
	if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
	{
		ui32SyncBlockIndexInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
		if (!ui32SyncBlockIndexInt)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->pui32SyncBlockIndex, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
				|| (OSCopyFromUser(NULL, ui32SyncBlockIndexInt, psSyncPrimOpCreateIN->pui32SyncBlockIndex,
				psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
			{
				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto SyncPrimOpCreate_exit;
			}
	if (psSyncPrimOpCreateIN->ui32ClientSyncCount != 0)
	{
		ui32IndexInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32));
		if (!ui32IndexInt)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->pui32Index, psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32))
				|| (OSCopyFromUser(NULL, ui32IndexInt, psSyncPrimOpCreateIN->pui32Index,
				psSyncPrimOpCreateIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
			{
				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto SyncPrimOpCreate_exit;
			}
	if (psSyncPrimOpCreateIN->ui32ServerSyncCount != 0)
	{
		psServerSyncInt = OSAllocMem(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
		if (!psServerSyncInt)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
		hServerSyncInt2 = OSAllocMem(psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
		if (!hServerSyncInt2)
		{
			psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
	
			goto SyncPrimOpCreate_exit;
		}
	}

			/* Copy the data over */
			if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpCreateIN->phServerSync, psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
				|| (OSCopyFromUser(NULL, hServerSyncInt2, psSyncPrimOpCreateIN->phServerSync,
				psSyncPrimOpCreateIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
			{
				psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;

				goto SyncPrimOpCreate_exit;
			}

	{
		IMG_UINT32 i;

		for (i=0;i<psSyncPrimOpCreateIN->ui32SyncBlockCount;i++)
		{
				{
					/* Look up the address from the handle */
					psSyncPrimOpCreateOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hBlockListInt2[i],
											psSyncPrimOpCreateIN->phBlockList[i],
											PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
					{
						goto SyncPrimOpCreate_exit;
					}

					/* Look up the data from the resman address */
					psSyncPrimOpCreateOUT->eError = ResManFindPrivateDataByPtr(hBlockListInt2[i], (IMG_VOID **) &psBlockListInt[i]);

					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
					{
						goto SyncPrimOpCreate_exit;
					}
				}
		}
	}

	{
		IMG_UINT32 i;

		for (i=0;i<psSyncPrimOpCreateIN->ui32ServerSyncCount;i++)
		{
				{
					/* Look up the address from the handle */
					psSyncPrimOpCreateOUT->eError =
						PVRSRVLookupHandle(psConnection->psHandleBase,
											(IMG_HANDLE *) &hServerSyncInt2[i],
											psSyncPrimOpCreateIN->phServerSync[i],
											PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
					{
						goto SyncPrimOpCreate_exit;
					}

					/* Look up the data from the resman address */
					psSyncPrimOpCreateOUT->eError = ResManFindPrivateDataByPtr(hServerSyncInt2[i], (IMG_VOID **) &psServerSyncInt[i]);

					if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
					{
						goto SyncPrimOpCreate_exit;
					}
				}
		}
	}

	psSyncPrimOpCreateOUT->eError =
		PVRSRVSyncPrimOpCreateKM(
					psSyncPrimOpCreateIN->ui32SyncBlockCount,
					psBlockListInt,
					psSyncPrimOpCreateIN->ui32ClientSyncCount,
					ui32SyncBlockIndexInt,
					ui32IndexInt,
					psSyncPrimOpCreateIN->ui32ServerSyncCount,
					psServerSyncInt,
					&psServerCookieInt);
	/* Exit early if bridged call fails */
	if(psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
	{
		goto SyncPrimOpCreate_exit;
	}

	/* Create a resman item and overwrite the handle with it */
	hServerCookieInt2 = ResManRegisterRes(psConnection->hResManContext,
												RESMAN_TYPE_SERVER_OP_COOKIE,
												psServerCookieInt,
												/* FIXME: how can we avoid this cast? */
												(RESMAN_FREE_FN)&PVRSRVSyncPrimOpDestroyKM);
	if (hServerCookieInt2 == IMG_NULL)
	{
		psSyncPrimOpCreateOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
		goto SyncPrimOpCreate_exit;
	}
	psSyncPrimOpCreateOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
							&psSyncPrimOpCreateOUT->hServerCookie,
							(IMG_HANDLE) hServerCookieInt2,
							PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE,
							PVRSRV_HANDLE_ALLOC_FLAG_NONE
							);
	if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
	{
		goto SyncPrimOpCreate_exit;
	}


SyncPrimOpCreate_exit:
	if (psSyncPrimOpCreateOUT->eError != PVRSRV_OK)
	{
		/* If we have a valid resman item we should undo the bridge function by freeing the resman item */
		if (hServerCookieInt2)
		{
			PVRSRV_ERROR eError = ResManFreeResByPtr(hServerCookieInt2);

			/* Freeing a resource should never fail... */
			PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY));
		}
		else if (psServerCookieInt)
		{
			PVRSRVSyncPrimOpDestroyKM(psServerCookieInt);
		}
	}

	if (psBlockListInt)
		OSFreeMem(psBlockListInt);
	if (hBlockListInt2)
		OSFreeMem(hBlockListInt2);
	if (ui32SyncBlockIndexInt)
		OSFreeMem(ui32SyncBlockIndexInt);
	if (ui32IndexInt)
		OSFreeMem(ui32IndexInt);
	if (psServerSyncInt)
		OSFreeMem(psServerSyncInt);
	if (hServerSyncInt2)
		OSFreeMem(hServerSyncInt2);

	return 0;
}
enum PVRSRV_ERROR PVRSRVWrapExtMemoryKM(void *hDevCookie,
			    struct PVRSRV_PER_PROCESS_DATA *psPerProc,
			    void *hDevMemContext, u32 ui32ByteSize,
			    u32 ui32PageOffset, IMG_BOOL bPhysContig,
			    struct IMG_SYS_PHYADDR *psExtSysPAddr,
			    void *pvLinAddr,
			    struct PVRSRV_KERNEL_MEM_INFO **ppsMemInfo)
{
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL;
	struct DEVICE_MEMORY_INFO *psDevMemoryInfo;
	u32 ui32HostPageSize = HOST_PAGESIZE();
	void *hDevMemHeap = NULL;
	struct PVRSRV_DEVICE_NODE *psDeviceNode;
	void *hBuffer;
	struct PVRSRV_MEMBLK *psMemBlock;
	IMG_BOOL bBMError;
	struct BM_HEAP *psBMHeap;
	enum PVRSRV_ERROR eError;
	void *pvPageAlignedCPUVAddr;
	struct IMG_SYS_PHYADDR *psIntSysPAddr = NULL;
	void *hOSWrapMem = NULL;
	struct DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
	int page_count = 0;
	u32 i;

	psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
	PVR_ASSERT(psDeviceNode != NULL);

	if (!psDeviceNode || (!pvLinAddr && !psExtSysPAddr)) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVWrapExtMemoryKM: invalid parameter");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (pvLinAddr) {
		get_page_details((u32)pvLinAddr, ui32ByteSize,
				&ui32PageOffset, &page_count);
		pvPageAlignedCPUVAddr = (void *)((u8 *) pvLinAddr -
					ui32PageOffset);

		if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
			       page_count * sizeof(struct IMG_SYS_PHYADDR),
			       (void **)&psIntSysPAddr, NULL) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVWrapExtMemoryKM: "
					"Failed to alloc memory for block");
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}

		eError = OSAcquirePhysPageAddr(pvPageAlignedCPUVAddr,
				       page_count * 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;
	}

	psDevMemoryInfo =
	    &((struct 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 == NULL) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVWrapExtMemoryKM: unable to find mapping heap");
		eError = PVRSRV_ERROR_GENERIC;
		goto ErrorExitPhase2;
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **) &psMemInfo, NULL) != 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));
	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap,
			   ui32ByteSize,
			   ui32PageOffset,
			   bPhysContig,
			   psExtSysPAddr,
			   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 = (void *) hBuffer;

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

	psMemInfo->pvSysBackupBuffer = NULL;

	psBMHeap = (struct BM_HEAP *)hDevMemHeap;
	hDevMemContext = (void *) psBMHeap->pBMContext;
	eError = alloc_or_reuse_syncinfo(hDevCookie,
					 hDevMemContext,
					 &psMemInfo->psKernelSyncInfo,
					 psExtSysPAddr);
	if (eError != PVRSRV_OK)
		goto ErrorExitPhase4;

	psMemInfo->ui32RefCount++;

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

	*ppsMemInfo = psMemInfo;

	return PVRSRV_OK;

ErrorExitPhase4:
	FreeDeviceMem(psMemInfo);
	psMemInfo = NULL;

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

ErrorExitPhase2:
	if (hOSWrapMem)
		OSReleasePhysPageAddr(hOSWrapMem);

ErrorExitPhase1:
	if (psIntSysPAddr) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  page_count * sizeof(struct IMG_SYS_PHYADDR),
			  psIntSysPAddr, NULL);
	}

	return eError;
}
Example #21
0
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
												  PVRSRV_KERNEL_MEM_INFO	*psSrcMemInfo,
												  IMG_HANDLE				hDstDevMemHeap,
												  PVRSRV_KERNEL_MEM_INFO	**ppsDstMemInfo)
{
	PVRSRV_ERROR				eError;
	IMG_UINT32					i;
	IMG_SIZE_T					ui32PageCount, ui32PageOffset;
	IMG_SIZE_T					ui32HostPageSize = HOST_PAGESIZE();
	IMG_SYS_PHYADDR				*psSysPAddr = IMG_NULL;
	IMG_DEV_PHYADDR				sDevPAddr;
	BM_BUF						*psBuf;
	IMG_DEV_VIRTADDR			sDevVAddr;
	PVRSRV_KERNEL_MEM_INFO		*psMemInfo = IMG_NULL;
	BM_HANDLE 					hBuffer;
	PVRSRV_MEMBLK				*psMemBlock;
	IMG_BOOL					bBMError;
	PVRSRV_DEVICE_NODE			*psDeviceNode;
	IMG_VOID 					*pvPageAlignedCPUVAddr;
	RESMAN_MAP_DEVICE_MEM_DATA	*psMapData = IMG_NULL;

	
	if(!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: invalid parameters"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	
	*ppsDstMemInfo = IMG_NULL;

	ui32PageOffset = psSrcMemInfo->sDevVAddr.uiAddr & (ui32HostPageSize - 1);
	ui32PageCount = HOST_PAGEALIGN(psSrcMemInfo->ui32AllocSize + ui32PageOffset) / ui32HostPageSize;
	pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)psSrcMemInfo->pvLinAddrKM - ui32PageOffset);

	



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

	psBuf = psSrcMemInfo->sMemBlk.hBuffer;

	
	psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;

	
	sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - IMG_CAST_TO_DEVVADDR_UINT(ui32PageOffset);
	for(i=0; i<ui32PageCount; i++)
	{
		BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);

		
		psSysPAddr[i] = SysDevPAddrToSysPAddr (psDeviceNode->sDevId.eDeviceType, sDevPAddr);

		
		sDevVAddr.uiAddr += IMG_CAST_TO_DEVVADDR_UINT(ui32HostPageSize);
	}

	
	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					sizeof(RESMAN_MAP_DEVICE_MEM_DATA),
					(IMG_VOID **)&psMapData, IMG_NULL,
					"Resource Manager Map Data") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: Failed to alloc resman map data"));
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExit;
	}


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

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

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDstDevMemHeap,
					   psSrcMemInfo->ui32AllocSize,
					   ui32PageOffset,
					   IMG_FALSE,
					   psSysPAddr,
					   pvPageAlignedCPUVAddr,
					   &psMemInfo->ui32Flags,
					   &hBuffer);

	if (!bBMError)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceMemoryKM: BM_Wrap Failed"));
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExit;
	}

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

	
	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;

	
	psMemBlock->psIntSysPAddr = psSysPAddr;

	
	psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;

	
	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
	psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;

	
	if( psMemInfo->psKernelSyncInfo )
		psMemInfo->psKernelSyncInfo->ui32RefCount++;

	

	psMemInfo->pvSysBackupBuffer = IMG_NULL;

	
	psMemInfo->ui32RefCount++;

	
	psSrcMemInfo->ui32RefCount++;

	
	BM_Export(psSrcMemInfo->sMemBlk.hBuffer);

	psMemInfo->memType = PVRSRV_MEMTYPE_MAPPED;

	
	psMapData->psMemInfo = psMemInfo;
	psMapData->psSrcMemInfo = psSrcMemInfo;

	
	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
													RESMAN_TYPE_DEVICEMEM_MAPPING,
													psMapData,
													0,
													&UnmapDeviceMemoryCallBack);

	*ppsDstMemInfo = psMemInfo;

	return PVRSRV_OK;

	

ErrorExit:

	if(psSysPAddr)
	{
		
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psSysPAddr, IMG_NULL);
		
	}

	if(psMemInfo)
	{
		
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
		
	}

	if(psMapData)
	{
		
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL);
		
	}

	return eError;
}
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;
}
enum PVRSRV_ERROR PVRSRVMapDeviceMemoryKM(
		struct PVRSRV_PER_PROCESS_DATA *psPerProc,
			      struct PVRSRV_KERNEL_MEM_INFO *psSrcMemInfo,
			      void *hDstDevMemHeap,
			      struct PVRSRV_KERNEL_MEM_INFO **ppsDstMemInfo)
{
	enum PVRSRV_ERROR eError;
	u32 ui32PageOffset;
	u32 ui32HostPageSize = HOST_PAGESIZE();
	int page_count;
	int i;
	struct IMG_SYS_PHYADDR *psSysPAddr = NULL;
	struct IMG_DEV_PHYADDR sDevPAddr;
	struct BM_BUF *psBuf;
	struct IMG_DEV_VIRTADDR sDevVAddr;
	struct PVRSRV_KERNEL_MEM_INFO *psMemInfo = NULL;
	void *hBuffer;
	struct PVRSRV_MEMBLK *psMemBlock;
	IMG_BOOL bBMError;
	struct PVRSRV_DEVICE_NODE *psDeviceNode;
	void *pvPageAlignedCPUVAddr;
	struct RESMAN_MAP_DEVICE_MEM_DATA *psMapData = NULL;

	if (!psSrcMemInfo || !hDstDevMemHeap || !ppsDstMemInfo) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVMapDeviceMemoryKM: invalid parameters");
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	*ppsDstMemInfo = NULL;

	get_page_details((u32)psSrcMemInfo->pvLinAddrKM,
			psSrcMemInfo->ui32AllocSize,
			&ui32PageOffset, &page_count);
	pvPageAlignedCPUVAddr =
	    (void *) ((u8 *) psSrcMemInfo->pvLinAddrKM -
			  ui32PageOffset);

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       page_count * sizeof(struct IMG_SYS_PHYADDR),
		       (void **) &psSysPAddr, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
					"Failed to alloc memory for block");
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	psBuf = psSrcMemInfo->sMemBlk.hBuffer;

	psDeviceNode = psBuf->pMapping->pBMHeap->pBMContext->psDeviceNode;

	sDevVAddr.uiAddr = psSrcMemInfo->sDevVAddr.uiAddr - ui32PageOffset;
	for (i = 0; i < page_count; i++) {
		eError =
		    BM_GetPhysPageAddr(psSrcMemInfo, sDevVAddr, &sDevPAddr);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
				"Failed to retrieve page list from device");
			goto ErrorExit;
		}

		psSysPAddr[i] =
		    SysDevPAddrToSysPAddr(psDeviceNode->sDevId.eDeviceType,
					  sDevPAddr);

		sDevVAddr.uiAddr += ui32HostPageSize;
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
		       sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA),
		       (void **)&psMapData, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
				"Failed to alloc resman map data");
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExit;
	}

	if (OSAllocMem(PVRSRV_PAGEABLE_SELECT,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO),
		       (void **)&psMemInfo, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "PVRSRVMapDeviceMemoryKM: "
				"Failed to alloc memory for block");
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto ErrorExit;
	}

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDstDevMemHeap, psSrcMemInfo->ui32AllocSize,
			   ui32PageOffset, bm_is_continuous(psBuf), psSysPAddr,
			   pvPageAlignedCPUVAddr, &psMemInfo->ui32Flags,
			   &hBuffer);

	if (!bBMError) {
		PVR_DPF(PVR_DBG_ERROR,
			 "PVRSRVMapDeviceMemoryKM: BM_Wrap Failed");
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExit;
	}

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

	psMemBlock->hBuffer = (void *) hBuffer;

	psMemBlock->psIntSysPAddr = psSysPAddr;

	psMemInfo->pvLinAddrKM = psSrcMemInfo->pvLinAddrKM;

	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = psSrcMemInfo->ui32AllocSize;
	psMemInfo->psKernelSyncInfo = psSrcMemInfo->psKernelSyncInfo;

	psMemInfo->pvSysBackupBuffer = NULL;

	psSrcMemInfo->ui32RefCount++;

	psMapData->psMemInfo = psMemInfo;
	psMapData->psSrcMemInfo = psSrcMemInfo;

	psMemInfo->sMemBlk.hResItem =
	    ResManRegisterRes(psPerProc->hResManContext,
			      RESMAN_TYPE_DEVICEMEM_MAPPING, psMapData, 0,
			      UnmapDeviceMemoryCallBack);

	*ppsDstMemInfo = psMemInfo;

	return PVRSRV_OK;

ErrorExit:

	if (psSysPAddr) {
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
			  sizeof(struct IMG_SYS_PHYADDR), psSysPAddr, NULL);
	}

	if (psMemInfo) {
		OSFreeMem(PVRSRV_PAGEABLE_SELECT,
			  sizeof(struct PVRSRV_KERNEL_MEM_INFO), psMemInfo,
			  NULL);
	}

	if (psMapData) {
		OSFreeMem(PVRSRV_PAGEABLE_SELECT,
			  sizeof(struct RESMAN_MAP_DEVICE_MEM_DATA), psMapData,
			  NULL);
	}

	return eError;
}
Example #24
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;
}
Example #25
0
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVMapDeviceClassMemoryKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
													   IMG_HANDLE				hDevMemContext,
													   IMG_HANDLE				hDeviceClassBuffer,
													   PVRSRV_KERNEL_MEM_INFO	**ppsMemInfo,
													   IMG_HANDLE				*phOSMapInfo)
{
	PVRSRV_ERROR eError;
	PVRSRV_DEVICE_NODE* psDeviceNode;
	PVRSRV_KERNEL_MEM_INFO *psMemInfo = IMG_NULL;
	PVRSRV_DEVICECLASS_BUFFER *psDeviceClassBuffer;
	IMG_SYS_PHYADDR *psSysPAddr;
	IMG_VOID *pvCPUVAddr, *pvPageAlignedCPUVAddr;
	IMG_BOOL bPhysContig;
	BM_CONTEXT *psBMContext;
	DEVICE_MEMORY_INFO *psDevMemoryInfo;
	DEVICE_MEMORY_HEAP_INFO *psDeviceMemoryHeap;
	IMG_HANDLE hDevMemHeap = IMG_NULL;
	IMG_SIZE_T ui32ByteSize;
	IMG_SIZE_T ui32Offset;
	IMG_SIZE_T ui32PageSize = HOST_PAGESIZE();
	BM_HANDLE		hBuffer;
	PVRSRV_MEMBLK	*psMemBlock;
	IMG_BOOL		bBMError;
	IMG_UINT32 i;
	PVRSRV_DC_MAPINFO *psDCMapInfo = IMG_NULL;

	if(!hDeviceClassBuffer || !ppsMemInfo || !phOSMapInfo || !hDevMemContext)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: invalid parameters"));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	
	if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					sizeof(PVRSRV_DC_MAPINFO),
					(IMG_VOID **)&psDCMapInfo, IMG_NULL,
					"PVRSRV_DC_MAPINFO") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: Failed to alloc memory for psDCMapInfo"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	OSMemSet(psDCMapInfo, 0, sizeof(PVRSRV_DC_MAPINFO));

	psDeviceClassBuffer = (PVRSRV_DEVICECLASS_BUFFER*)hDeviceClassBuffer;

	


















	eError = psDeviceClassBuffer->pfnGetBufferAddr(psDeviceClassBuffer->hExtDevice,
												   psDeviceClassBuffer->hExtBuffer,
												   &psSysPAddr,
												   &ui32ByteSize,
												   &pvCPUVAddr,
												   phOSMapInfo,
												   &bPhysContig,
												   &psDCMapInfo->ui32TilingStride);
	if(eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: unable to get buffer address"));
		goto ErrorExitPhase1;
	}

	
	psBMContext = (BM_CONTEXT*)psDeviceClassBuffer->hDevMemContext;
	psDeviceNode = psBMContext->psDeviceNode;
	psDevMemoryInfo = &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,"PVRSRVMapDeviceClassMemoryKM: unable to find mapping heap"));
		eError = PVRSRV_ERROR_UNABLE_TO_FIND_RESOURCE;
		goto ErrorExitPhase1;
	}

	
	ui32Offset = ((IMG_UINTPTR_T)pvCPUVAddr) & (ui32PageSize - 1);
	pvPageAlignedCPUVAddr = (IMG_VOID *)((IMG_UINTPTR_T)pvCPUVAddr - ui32Offset);

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

	OSMemSet(psMemInfo, 0, sizeof(*psMemInfo));

	psMemBlock = &(psMemInfo->sMemBlk);

	bBMError = BM_Wrap(hDevMemHeap,
					   ui32ByteSize,
					   ui32Offset,
					   bPhysContig,
					   psSysPAddr,
					   pvPageAlignedCPUVAddr,
					   &psMemInfo->ui32Flags,
					   &hBuffer);

	if (!bBMError)
	{
		PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: BM_Wrap Failed"));
		
		eError = PVRSRV_ERROR_BAD_MAPPING;
		goto ErrorExitPhase2;
	}

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

	
	psMemBlock->hBuffer = (IMG_HANDLE)hBuffer;

	

	psMemInfo->pvLinAddrKM = BM_HandleToCpuVaddr(hBuffer);

	
	psMemInfo->sDevVAddr = psMemBlock->sDevVirtAddr;
	psMemInfo->ui32AllocSize = ui32ByteSize;
	psMemInfo->psKernelSyncInfo = psDeviceClassBuffer->psKernelSyncInfo;

	

	psMemInfo->pvSysBackupBuffer = IMG_NULL;

	
	psDCMapInfo->psMemInfo = psMemInfo;

#if defined(SUPPORT_MEMORY_TILING)
	psDCMapInfo->psDeviceNode = psDeviceNode;

	if(psDCMapInfo->ui32TilingStride > 0)
	{
		
		eError = psDeviceNode->pfnAllocMemTilingRange(psDeviceNode,
														psMemInfo,
														psDCMapInfo->ui32TilingStride,
														&psDCMapInfo->ui32RangeIndex);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,"PVRSRVMapDeviceClassMemoryKM: AllocMemTilingRange failed"));
			goto ErrorExitPhase3;
		}
	}
#endif

	
	psMemInfo->sMemBlk.hResItem = ResManRegisterRes(psPerProc->hResManContext,
													RESMAN_TYPE_DEVICECLASSMEM_MAPPING,
													psDCMapInfo,
													0,
													&UnmapDeviceClassMemoryCallBack);

	psMemInfo->ui32RefCount++;

	psMemInfo->memType = PVRSRV_MEMTYPE_DEVICECLASS;

	
	*ppsMemInfo = psMemInfo;

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)

	PDUMPCOMMENT("Dump display surface");
	PDUMPMEM(IMG_NULL, psMemInfo, ui32Offset, psMemInfo->ui32AllocSize, PDUMP_FLAGS_CONTINUOUS, ((BM_BUF*)psMemInfo->sMemBlk.hBuffer)->pMapping);
#endif
	return PVRSRV_OK;

#if defined(SUPPORT_MEMORY_TILING)
ErrorExitPhase3:
	if(psMemInfo)
	{
		FreeDeviceMem(psMemInfo);
		


		psMemInfo = IMG_NULL;
	}
#endif

ErrorExitPhase2:
	if(psMemInfo)
	{
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(PVRSRV_KERNEL_MEM_INFO), psMemInfo, IMG_NULL);
	}

ErrorExitPhase1:
	if(psDCMapInfo)
	{
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_KERNEL_MEM_INFO), psDCMapInfo, IMG_NULL);
	}

	return eError;
}
Example #26
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;
}
Example #27
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;
}
Example #28
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;
}
Example #29
0
IMG_EXPORT PVRSRV_ERROR
SGXFindSharedPBDescKM(PVRSRV_PER_PROCESS_DATA	*psPerProc,
					  IMG_HANDLE 				hDevCookie,
					  IMG_BOOL 				bLockOnFailure,
					  IMG_UINT32 				ui32TotalPBSize,
					  IMG_HANDLE 				*phSharedPBDesc,
					  PVRSRV_KERNEL_MEM_INFO 	**ppsSharedPBDescKernelMemInfo,
					  PVRSRV_KERNEL_MEM_INFO 	**ppsHWPBDescKernelMemInfo,
					  PVRSRV_KERNEL_MEM_INFO 	**ppsBlockKernelMemInfo,
					  PVRSRV_KERNEL_MEM_INFO 	**ppsHWBlockKernelMemInfo,
					  PVRSRV_KERNEL_MEM_INFO 	***pppsSharedPBDescSubKernelMemInfos,
					  IMG_UINT32				*ui32SharedPBDescSubKernelMemInfosCount)
{
	PVRSRV_STUB_PBDESC *psStubPBDesc;
	PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos=IMG_NULL;
	PVRSRV_SGXDEV_INFO *psSGXDevInfo;
	PVRSRV_ERROR eError;

	psSGXDevInfo = ((PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;

	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
	if (psStubPBDesc != IMG_NULL)
	{
		IMG_UINT32 i;
		PRESMAN_ITEM psResItem;

		if(psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize)
		{
			PVR_DPF((PVR_DBG_WARNING,
					"SGXFindSharedPBDescKM: Shared PB requested with different size (0x%x) from existing shared PB (0x%x) - requested size ignored",
					ui32TotalPBSize, psStubPBDesc->ui32TotalPBSize));
		}

		if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
					  sizeof(PVRSRV_KERNEL_MEM_INFO *)
						* psStubPBDesc->ui32SubKernelMemInfosCount,
					  (IMG_VOID **)&ppsSharedPBDescSubKernelMemInfos,
					  IMG_NULL,
					  "Array of Kernel Memory Info") != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: OSAllocMem failed"));

			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto ExitNotFound;
		}

		psResItem = ResManRegisterRes(psPerProc->hResManContext,
									  RESMAN_TYPE_SHARED_PB_DESC,
									  psStubPBDesc,
									  0,
									  &SGXCleanupSharedPBDescCallback);

		if (psResItem == IMG_NULL)
		{
			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
					  sizeof(PVRSRV_KERNEL_MEM_INFO *) * psStubPBDesc->ui32SubKernelMemInfosCount,
					  ppsSharedPBDescSubKernelMemInfos,
					  0);


			PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));

			eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
			goto ExitNotFound;
		}

		*ppsSharedPBDescKernelMemInfo = psStubPBDesc->psSharedPBDescKernelMemInfo;
		*ppsHWPBDescKernelMemInfo = psStubPBDesc->psHWPBDescKernelMemInfo;
		*ppsBlockKernelMemInfo = psStubPBDesc->psBlockKernelMemInfo;
		*ppsHWBlockKernelMemInfo = psStubPBDesc->psHWBlockKernelMemInfo;

		*ui32SharedPBDescSubKernelMemInfosCount =
			psStubPBDesc->ui32SubKernelMemInfosCount;

		*pppsSharedPBDescSubKernelMemInfos = ppsSharedPBDescSubKernelMemInfos;

		for(i=0; i<psStubPBDesc->ui32SubKernelMemInfosCount; i++)
		{
			ppsSharedPBDescSubKernelMemInfos[i] =
				psStubPBDesc->ppsSubKernelMemInfos[i];
		}

		psStubPBDesc->ui32RefCount++;
		*phSharedPBDesc = (IMG_HANDLE)psResItem;
		return PVRSRV_OK;
	}

	eError = PVRSRV_OK;
	if (bLockOnFailure)
	{
		if (psResItemCreateSharedPB == IMG_NULL)
		{
			psResItemCreateSharedPB = ResManRegisterRes(psPerProc->hResManContext,
				  RESMAN_TYPE_SHARED_PB_DESC_CREATE_LOCK,
				  psPerProc,
				  0,
				  &SGXCleanupSharedPBDescCreateLockCallback);

			if (psResItemCreateSharedPB == IMG_NULL)
			{
				PVR_DPF((PVR_DBG_ERROR, "SGXFindSharedPBDescKM: ResManRegisterRes failed"));

				eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE;
				goto ExitNotFound;
			}
			PVR_ASSERT(psPerProcCreateSharedPB == IMG_NULL);
			psPerProcCreateSharedPB = psPerProc;
		}
		else
		{
			 eError = PVRSRV_ERROR_PROCESSING_BLOCKED;
		}
	}
ExitNotFound:
	*phSharedPBDesc = IMG_NULL;

	return eError;
}
Example #30
0
enum PVRSRV_ERROR SGXAddSharedPBDescKM(
	struct PVRSRV_PER_PROCESS_DATA *psPerProc,
	void *hDevCookie,
	struct PVRSRV_KERNEL_MEM_INFO *psSharedPBDescKernelMemInfo,
	struct PVRSRV_KERNEL_MEM_INFO *psHWPBDescKernelMemInfo,
	struct PVRSRV_KERNEL_MEM_INFO *psBlockKernelMemInfo,
	u32 ui32TotalPBSize, void **phSharedPBDesc,
	struct PVRSRV_KERNEL_MEM_INFO **ppsSharedPBDescSubKernelMemInfos,
	u32 ui32SharedPBDescSubKernelMemInfosCount)
{
	struct PVRSRV_STUB_PBDESC *psStubPBDesc = NULL;
	enum PVRSRV_ERROR eRet = PVRSRV_ERROR_GENERIC;
	u32 i;
	struct PVRSRV_SGXDEV_INFO *psSGXDevInfo;
	struct RESMAN_ITEM *psResItem;

	if (psPerProcCreateSharedPB != psPerProc) {
		goto NoAdd;
	} else {
		PVR_ASSERT(psResItemCreateSharedPB != NULL);

		ResManFreeResByPtr(psResItemCreateSharedPB);

		PVR_ASSERT(psResItemCreateSharedPB == NULL);
		PVR_ASSERT(psPerProcCreateSharedPB == NULL);
	}

	psSGXDevInfo = (struct PVRSRV_SGXDEV_INFO *)
		((struct PVRSRV_DEVICE_NODE *)hDevCookie)->pvDevice;

	psStubPBDesc = psSGXDevInfo->psStubPBDescListKM;
	if (psStubPBDesc != NULL) {
		if (psStubPBDesc->ui32TotalPBSize != ui32TotalPBSize) {
			PVR_DPF(PVR_DBG_WARNING, "SGXAddSharedPBDescKM: "
				"Shared PB requested with different size "
				"(0x%x) from existing shared PB (0x%x) - "
				"requested size ignored",
				 ui32TotalPBSize,
				 psStubPBDesc->ui32TotalPBSize);

		}

		psResItem = ResManRegisterRes(psPerProc->hResManContext,
					      RESMAN_TYPE_SHARED_PB_DESC,
					      psStubPBDesc, 0,
					      &SGXCleanupSharedPBDescCallback);
		if (psResItem == NULL) {
			PVR_DPF(PVR_DBG_ERROR,
					 "SGXAddSharedPBDescKM: "
					 "Failed to register existing shared "
					 "PBDesc with the resource manager");
			goto NoAddKeepPB;
		}

		psStubPBDesc->ui32RefCount++;

		*phSharedPBDesc = (void *) psResItem;
		eRet = PVRSRV_OK;
		goto NoAddKeepPB;
	}

	if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_STUB_PBDESC),
		       (void **)&psStubPBDesc, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: Failed to alloc "
			 "StubPBDesc");
		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto NoAdd;
	}

	psStubPBDesc->ppsSubKernelMemInfos = NULL;

	if (OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
		       sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
					ui32SharedPBDescSubKernelMemInfosCount,
		       (void **)&psStubPBDesc->ppsSubKernelMemInfos, NULL) !=
			PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
			 "Failed to alloc "
			 "StubPBDesc->ppsSubKernelMemInfos");
		eRet = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto NoAdd;
	}

	if (PVRSRVDissociateMemFromResmanKM(psSharedPBDescKernelMemInfo)
	    != PVRSRV_OK)
		goto NoAdd;

	if (PVRSRVDissociateMemFromResmanKM(psHWPBDescKernelMemInfo)
	    != PVRSRV_OK)
		goto NoAdd;

	if (PVRSRVDissociateMemFromResmanKM(psBlockKernelMemInfo)
	    != PVRSRV_OK)
		goto NoAdd;

	psStubPBDesc->ui32RefCount = 1;
	psStubPBDesc->ui32TotalPBSize = ui32TotalPBSize;
	psStubPBDesc->psSharedPBDescKernelMemInfo = psSharedPBDescKernelMemInfo;
	psStubPBDesc->psHWPBDescKernelMemInfo = psHWPBDescKernelMemInfo;
	psStubPBDesc->psBlockKernelMemInfo = psBlockKernelMemInfo;

	psStubPBDesc->ui32SubKernelMemInfosCount =
	    ui32SharedPBDescSubKernelMemInfosCount;
	for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++) {
		psStubPBDesc->ppsSubKernelMemInfos[i] =
		    ppsSharedPBDescSubKernelMemInfos[i];
		if (PVRSRVDissociateMemFromResmanKM
		    (ppsSharedPBDescSubKernelMemInfos[i]) != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
				 "Failed to dissociate shared PBDesc "
				 "from process");
			goto NoAdd;
		}
	}

	psResItem = ResManRegisterRes(psPerProc->hResManContext,
				      RESMAN_TYPE_SHARED_PB_DESC,
				      psStubPBDesc,
				      0, &SGXCleanupSharedPBDescCallback);
	if (psResItem == NULL) {
		PVR_DPF(PVR_DBG_ERROR, "SGXAddSharedPBDescKM: "
			 "Failed to register shared PBDesc "
			 " with the resource manager");
		goto NoAdd;
	}
	psStubPBDesc->hDevCookie = hDevCookie;

	psStubPBDesc->psNext = psSGXDevInfo->psStubPBDescListKM;
	psSGXDevInfo->psStubPBDescListKM = psStubPBDesc;

	*phSharedPBDesc = (void *) psResItem;

	return PVRSRV_OK;

NoAdd:
	if (psStubPBDesc) {
		if (psStubPBDesc->ppsSubKernelMemInfos) {
			OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				  sizeof(struct PVRSRV_KERNEL_MEM_INFO *) *
					ui32SharedPBDescSubKernelMemInfosCount,
				  psStubPBDesc->ppsSubKernelMemInfos, NULL);
		}
		OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
			  sizeof(struct PVRSRV_STUB_PBDESC), psStubPBDesc,
			  NULL);
	}

NoAddKeepPB:
	for (i = 0; i < ui32SharedPBDescSubKernelMemInfosCount; i++)
		PVRSRVFreeDeviceMemKM(hDevCookie,
				      ppsSharedPBDescSubKernelMemInfos[i]);

	PVRSRVFreeSharedSysMemoryKM(psSharedPBDescKernelMemInfo);
	PVRSRVFreeDeviceMemKM(hDevCookie, psHWPBDescKernelMemInfo);

	PVRSRVFreeSharedSysMemoryKM(psBlockKernelMemInfo);

	return eRet;
}