static IMG_INT PVRSRVBridgeSyncPrimPDump(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_SYNCPRIMPDUMP *psSyncPrimPDumpIN, PVRSRV_BRIDGE_OUT_SYNCPRIMPDUMP *psSyncPrimPDumpOUT, CONNECTION_DATA *psConnection) { SYNC_PRIMITIVE_BLOCK * psSyncHandleInt = IMG_NULL; IMG_HANDLE hSyncHandleInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SYNCPRIMPDUMP); { /* Look up the address from the handle */ psSyncPrimPDumpOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hSyncHandleInt2, psSyncPrimPDumpIN->hSyncHandle, PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK); if(psSyncPrimPDumpOUT->eError != PVRSRV_OK) { goto SyncPrimPDump_exit; } /* Look up the data from the resman address */ psSyncPrimPDumpOUT->eError = ResManFindPrivateDataByPtr(hSyncHandleInt2, (IMG_VOID **) &psSyncHandleInt); if(psSyncPrimPDumpOUT->eError != PVRSRV_OK) { goto SyncPrimPDump_exit; } } psSyncPrimPDumpOUT->eError = PVRSRVSyncPrimPDumpKM( psSyncHandleInt, psSyncPrimPDumpIN->ui32Offset); SyncPrimPDump_exit: return 0; }
static IMG_INT PVRSRVBridgeRGXSetComputeContextPriority(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityIN, PVRSRV_BRIDGE_OUT_RGXSETCOMPUTECONTEXTPRIORITY *psRGXSetComputeContextPriorityOUT, CONNECTION_DATA *psConnection) { RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL; IMG_HANDLE hComputeContextInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RGXCMP_RGXSETCOMPUTECONTEXTPRIORITY); { /* Look up the address from the handle */ psRGXSetComputeContextPriorityOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hComputeContextInt2, psRGXSetComputeContextPriorityIN->hComputeContext, PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); if(psRGXSetComputeContextPriorityOUT->eError != PVRSRV_OK) { goto RGXSetComputeContextPriority_exit; } /* Look up the data from the resman address */ psRGXSetComputeContextPriorityOUT->eError = ResManFindPrivateDataByPtr(hComputeContextInt2, (IMG_VOID **) &psComputeContextInt); if(psRGXSetComputeContextPriorityOUT->eError != PVRSRV_OK) { goto RGXSetComputeContextPriority_exit; } } psRGXSetComputeContextPriorityOUT->eError = PVRSRVRGXSetComputeContextPriorityKM(psConnection, psComputeContextInt, psRGXSetComputeContextPriorityIN->ui32Priority); RGXSetComputeContextPriority_exit: return 0; }
static IMG_INT PVRSRVBridgeSyncPrimOpReady(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_SYNCPRIMOPREADY *psSyncPrimOpReadyIN, PVRSRV_BRIDGE_OUT_SYNCPRIMOPREADY *psSyncPrimOpReadyOUT, CONNECTION_DATA *psConnection) { SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL; IMG_HANDLE hServerCookieInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPREADY); { /* Look up the address from the handle */ psSyncPrimOpReadyOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hServerCookieInt2, psSyncPrimOpReadyIN->hServerCookie, PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE); if(psSyncPrimOpReadyOUT->eError != PVRSRV_OK) { goto SyncPrimOpReady_exit; } /* Look up the data from the resman address */ psSyncPrimOpReadyOUT->eError = ResManFindPrivateDataByPtr(hServerCookieInt2, (IMG_VOID **) &psServerCookieInt); if(psSyncPrimOpReadyOUT->eError != PVRSRV_OK) { goto SyncPrimOpReady_exit; } } psSyncPrimOpReadyOUT->eError = PVRSRVSyncPrimOpReadyKM( psServerCookieInt, &psSyncPrimOpReadyOUT->bReady); SyncPrimOpReady_exit: return 0; }
static IMG_INT PVRSRVBridgeRIUpdateMEMDESCAddr(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrIN, PVRSRV_BRIDGE_OUT_RIUPDATEMEMDESCADDR *psRIUpdateMEMDESCAddrOUT, CONNECTION_DATA *psConnection) { RI_HANDLE psRIHandleInt = IMG_NULL; IMG_HANDLE hRIHandleInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RI_RIUPDATEMEMDESCADDR); { /* Look up the address from the handle */ psRIUpdateMEMDESCAddrOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hRIHandleInt2, psRIUpdateMEMDESCAddrIN->hRIHandle, PVRSRV_HANDLE_TYPE_RI_HANDLE); if(psRIUpdateMEMDESCAddrOUT->eError != PVRSRV_OK) { goto RIUpdateMEMDESCAddr_exit; } /* Look up the data from the resman address */ psRIUpdateMEMDESCAddrOUT->eError = ResManFindPrivateDataByPtr(hRIHandleInt2, (IMG_VOID **) &psRIHandleInt); if(psRIUpdateMEMDESCAddrOUT->eError != PVRSRV_OK) { goto RIUpdateMEMDESCAddr_exit; } } psRIUpdateMEMDESCAddrOUT->eError = RIUpdateMEMDESCAddrKM( psRIHandleInt, psRIUpdateMEMDESCAddrIN->sAddr); RIUpdateMEMDESCAddr_exit: return 0; }
static IMG_INT PVRSRVBridgeEventObjectWait(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_EVENTOBJECTWAIT *psEventObjectWaitIN, PVRSRV_BRIDGE_OUT_EVENTOBJECTWAIT *psEventObjectWaitOUT, CONNECTION_DATA *psConnection) { IMG_HANDLE hOSEventKMInt = IMG_NULL; IMG_HANDLE hOSEventKMInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SRVCORE_EVENTOBJECTWAIT); { /* Look up the address from the handle */ psEventObjectWaitOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hOSEventKMInt2, psEventObjectWaitIN->hOSEventKM, PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT); if(psEventObjectWaitOUT->eError != PVRSRV_OK) { goto EventObjectWait_exit; } /* Look up the data from the resman address */ psEventObjectWaitOUT->eError = ResManFindPrivateDataByPtr(hOSEventKMInt2, (IMG_VOID **) &hOSEventKMInt); if(psEventObjectWaitOUT->eError != PVRSRV_OK) { goto EventObjectWait_exit; } } psEventObjectWaitOUT->eError = OSEventObjectWait( hOSEventKMInt); EventObjectWait_exit: return 0; }
static IMG_INT PVRSRVBridgeRIDumpList(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RIDUMPLIST *psRIDumpListIN, PVRSRV_BRIDGE_OUT_RIDUMPLIST *psRIDumpListOUT, CONNECTION_DATA *psConnection) { PMR * psPMRHandleInt = IMG_NULL; IMG_HANDLE hPMRHandleInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RI_RIDUMPLIST); { /* Look up the address from the handle */ psRIDumpListOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hPMRHandleInt2, psRIDumpListIN->hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); if(psRIDumpListOUT->eError != PVRSRV_OK) { goto RIDumpList_exit; } /* Look up the data from the resman address */ psRIDumpListOUT->eError = ResManFindPrivateDataByPtr(hPMRHandleInt2, (IMG_VOID **) &psPMRHandleInt); if(psRIDumpListOUT->eError != PVRSRV_OK) { goto RIDumpList_exit; } } psRIDumpListOUT->eError = RIDumpListKM( psPMRHandleInt); RIDumpList_exit: return 0; }
int MMapPMR(struct file *pFile, struct vm_area_struct *ps_vma) { PVRSRV_ERROR eError; IMG_HANDLE hSecurePMRHandle; IMG_SIZE_T uiLength; IMG_DEVMEM_OFFSET_T uiOffset; unsigned long uiPFN; IMG_HANDLE hPMRResmanHandle; PMR *psPMR; PMR_FLAGS_T ulPMRFlags; IMG_UINT32 ui32CPUCacheFlags; unsigned long ulNewFlags = 0; pgprot_t sPageProt; #if defined(SUPPORT_DRM) CONNECTION_DATA *psConnection = LinuxConnectionFromFile(PVR_DRM_FILE_FROM_FILE(pFile)); #else CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile); #endif #if defined(PVR_MMAP_USE_VM_INSERT) IMG_BOOL bMixedMap = IMG_FALSE; #endif /* * The pmr lock used here to protect both handle related operations and PMR * operations. * This was introduced to fix lockdep issue. */ mutex_lock(&g_sMMapMutex); PMRLock(); #if defined(SUPPORT_DRM_DC_MODULE) psPMR = PVRSRVGEMMMapLookupPMR(pFile, ps_vma); if (!psPMR) #endif { hSecurePMRHandle = (IMG_HANDLE)((IMG_UINTPTR_T)ps_vma->vm_pgoff); eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hPMRResmanHandle, hSecurePMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); if (eError != PVRSRV_OK) { goto e0; } eError = ResManFindPrivateDataByPtr(hPMRResmanHandle, (void **)&psPMR); if (eError != PVRSRV_OK) { goto e0; } } /* * Take a reference on the PMR, make's sure that it can't be freed * while it's mapped into the user process */ PMRRefPMR(psPMR); PMRUnlock(); eError = PMRLockSysPhysAddresses(psPMR, PAGE_SHIFT); if (eError != PVRSRV_OK) { goto e1; } if (((ps_vma->vm_flags & VM_WRITE) != 0) && ((ps_vma->vm_flags & VM_SHARED) == 0)) { eError = PVRSRV_ERROR_INVALID_PARAMS; goto e1; } /* * We ought to call PMR_Flags() here to check the permissions * against the requested mode, and possibly to set up the cache * control protflags */ eError = PMR_Flags(psPMR, &ulPMRFlags); if (eError != PVRSRV_OK) { goto e1; } ulNewFlags = ps_vma->vm_flags; #if 0 /* Discard user read/write request, we will pull these flags from the PMR */ ulNewFlags &= ~(VM_READ | VM_WRITE); if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_READABLE) { ulNewFlags |= VM_READ; } if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) { ulNewFlags |= VM_WRITE; } #endif ps_vma->vm_flags = ulNewFlags; #if defined (CONFIG_ARM64) sPageProt = __pgprot_modify(ps_vma->vm_page_prot, 0, vm_get_page_prot(ulNewFlags)); #elif defined(CONFIG_ARM) sPageProt = __pgprot_modify(ps_vma->vm_page_prot, L_PTE_MT_MASK, vm_get_page_prot(ulNewFlags)); #elif defined(CONFIG_X86) sPageProt = pgprot_modify(ps_vma->vm_page_prot, vm_get_page_prot(ulNewFlags)); #elif defined(CONFIG_METAG) || defined(CONFIG_MIPS) sPageProt = vm_get_page_prot(ulNewFlags); #else #error Please add pgprot_modify equivalent for your system #endif ui32CPUCacheFlags = DevmemCPUCacheMode(ulPMRFlags); switch (ui32CPUCacheFlags) { case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: sPageProt = pgprot_noncached(sPageProt); break; case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE: sPageProt = pgprot_writecombine(sPageProt); break; case PVRSRV_MEMALLOCFLAG_CPU_CACHED: break; default: eError = PVRSRV_ERROR_INVALID_PARAMS; goto e1; } ps_vma->vm_page_prot = sPageProt; uiLength = ps_vma->vm_end - ps_vma->vm_start; ps_vma->vm_flags |= VM_IO; /* Don't include the mapping in core dumps */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) ps_vma->vm_flags |= VM_DONTDUMP; #else ps_vma->vm_flags |= VM_RESERVED; #endif /* * Disable mremap because our nopage handler assumes all * page requests have already been validated. */ ps_vma->vm_flags |= VM_DONTEXPAND; /* Don't allow mapping to be inherited across a process fork */ ps_vma->vm_flags |= VM_DONTCOPY; #if defined(PVR_MMAP_USE_VM_INSERT) { /* Scan the map range for pfns without struct page* handling. If we find * one, this is a mixed map, and we can't use vm_insert_page(). */ for (uiOffset = 0; uiOffset < uiLength; uiOffset += 1ULL<<PAGE_SHIFT) { IMG_CPU_PHYADDR sCpuPAddr; IMG_BOOL bValid; eError = PMR_CpuPhysAddr(psPMR, uiOffset, &sCpuPAddr, &bValid); PVR_ASSERT(eError == PVRSRV_OK); if (eError) { goto e2; } if (bValid) { uiPFN = sCpuPAddr.uiAddr >> PAGE_SHIFT; PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == sCpuPAddr.uiAddr); if (!pfn_valid(uiPFN) || page_count(pfn_to_page(uiPFN)) == 0) { bMixedMap = IMG_TRUE; } } } if (bMixedMap) { ps_vma->vm_flags |= VM_MIXEDMAP; } } #endif /* defined(PVR_MMAP_USE_VM_INSERT) */ for (uiOffset = 0; uiOffset < uiLength; uiOffset += 1ULL<<PAGE_SHIFT) { IMG_SIZE_T uiNumContiguousBytes; IMG_INT32 iStatus; IMG_CPU_PHYADDR sCpuPAddr; IMG_BOOL bValid; uiNumContiguousBytes = 1ULL<<PAGE_SHIFT; eError = PMR_CpuPhysAddr(psPMR, uiOffset, &sCpuPAddr, &bValid); PVR_ASSERT(eError == PVRSRV_OK); if (eError) { goto e2; } /* Only map in pages that are valid, any that aren't will be picked up by the nopage handler which will return a zeroed page for us */ if (bValid) { uiPFN = sCpuPAddr.uiAddr >> PAGE_SHIFT; PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == sCpuPAddr.uiAddr); #if defined(PVR_MMAP_USE_VM_INSERT) if (bMixedMap) { /* This path is just for debugging. It should be equivalent * to the remap_pfn_range() path. */ iStatus = vm_insert_mixed(ps_vma, ps_vma->vm_start + uiOffset, uiPFN); } else { iStatus = vm_insert_page(ps_vma, ps_vma->vm_start + uiOffset, pfn_to_page(uiPFN)); } #else /* defined(PVR_MMAP_USE_VM_INSERT) */ iStatus = remap_pfn_range(ps_vma, ps_vma->vm_start + uiOffset, uiPFN, uiNumContiguousBytes, ps_vma->vm_page_prot); #endif /* defined(PVR_MMAP_USE_VM_INSERT) */ PVR_ASSERT(iStatus == 0); if(iStatus) { // N.B. not the right error code, but, it doesn't get propagated anyway... :( eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto e2; } #if defined(PVRSRV_ENABLE_PROCESS_STATS) /* USER MAPPING*/ #if !defined(PVRSRV_ENABLE_MEMORY_STATS) PVRSRVStatsIncrMemAllocStat(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, PAGE_SIZE); #else PVRSRVStatsAddMemAllocRecord(PVRSRV_MEM_ALLOC_TYPE_MAP_UMA_LMA_PAGES, (IMG_VOID*)(IMG_UINTPTR_T)(ps_vma->vm_start + uiOffset), sCpuPAddr, PAGE_SIZE, IMG_NULL); #endif #endif } (void)pFile; } /* let us see the PMR so we can unlock it later */ ps_vma->vm_private_data = psPMR; /* Install open and close handlers for ref-counting */ ps_vma->vm_ops = &gsMMapOps; mutex_unlock(&g_sMMapMutex); return 0; /* error exit paths follow */ e2: PVR_DPF((PVR_DBG_ERROR, "don't know how to handle this error. Abort!")); PMRUnlockSysPhysAddresses(psPMR); e1: PMRUnrefPMR(psPMR); goto em1; e0: PVR_DPF((PVR_DBG_ERROR, "Error in MMapPMR critical section")); PMRUnlock(); em1: PVR_ASSERT(eError != PVRSRV_OK); PVR_DPF((PVR_DBG_ERROR, "unable to translate error %d", eError)); mutex_unlock(&g_sMMapMutex); return -ENOENT; // -EAGAIN // or what? }
static IMG_INT PVRSRVBridgeSyncPrimOpTake(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_SYNCPRIMOPTAKE *psSyncPrimOpTakeIN, PVRSRV_BRIDGE_OUT_SYNCPRIMOPTAKE *psSyncPrimOpTakeOUT, CONNECTION_DATA *psConnection) { SERVER_OP_COOKIE * psServerCookieInt = IMG_NULL; IMG_HANDLE hServerCookieInt2 = IMG_NULL; IMG_UINT32 *ui32FlagsInt = IMG_NULL; IMG_UINT32 *ui32FenceValueInt = IMG_NULL; IMG_UINT32 *ui32UpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerFlagsInt = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SYNCPRIMOPTAKE); if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0) { ui32FlagsInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)); if (!ui32FlagsInt) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto SyncPrimOpTake_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32Flags, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32FlagsInt, psSyncPrimOpTakeIN->pui32Flags, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto SyncPrimOpTake_exit; } if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0) { ui32FenceValueInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)); if (!ui32FenceValueInt) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto SyncPrimOpTake_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32FenceValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32FenceValueInt, psSyncPrimOpTakeIN->pui32FenceValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto SyncPrimOpTake_exit; } if (psSyncPrimOpTakeIN->ui32ClientSyncCount != 0) { ui32UpdateValueInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)); if (!ui32UpdateValueInt) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto SyncPrimOpTake_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32UpdateValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32UpdateValueInt, psSyncPrimOpTakeIN->pui32UpdateValue, psSyncPrimOpTakeIN->ui32ClientSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto SyncPrimOpTake_exit; } if (psSyncPrimOpTakeIN->ui32ServerSyncCount != 0) { ui32ServerFlagsInt = OSAllocMem(psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)); if (!ui32ServerFlagsInt) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto SyncPrimOpTake_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psSyncPrimOpTakeIN->pui32ServerFlags, psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32ServerFlagsInt, psSyncPrimOpTakeIN->pui32ServerFlags, psSyncPrimOpTakeIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psSyncPrimOpTakeOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto SyncPrimOpTake_exit; } { /* Look up the address from the handle */ psSyncPrimOpTakeOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hServerCookieInt2, psSyncPrimOpTakeIN->hServerCookie, PVRSRV_HANDLE_TYPE_SERVER_OP_COOKIE); if(psSyncPrimOpTakeOUT->eError != PVRSRV_OK) { goto SyncPrimOpTake_exit; } /* Look up the data from the resman address */ psSyncPrimOpTakeOUT->eError = ResManFindPrivateDataByPtr(hServerCookieInt2, (IMG_VOID **) &psServerCookieInt); if(psSyncPrimOpTakeOUT->eError != PVRSRV_OK) { goto SyncPrimOpTake_exit; } } psSyncPrimOpTakeOUT->eError = PVRSRVSyncPrimOpTakeKM( psServerCookieInt, psSyncPrimOpTakeIN->ui32ClientSyncCount, ui32FlagsInt, ui32FenceValueInt, ui32UpdateValueInt, psSyncPrimOpTakeIN->ui32ServerSyncCount, ui32ServerFlagsInt); SyncPrimOpTake_exit: if (ui32FlagsInt) OSFreeMem(ui32FlagsInt); if (ui32FenceValueInt) OSFreeMem(ui32FenceValueInt); if (ui32UpdateValueInt) OSFreeMem(ui32UpdateValueInt); if (ui32ServerFlagsInt) OSFreeMem(ui32ServerFlagsInt); 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; }
static IMG_INT PVRSRVBridgeServerSyncGetStatus(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_SERVERSYNCGETSTATUS *psServerSyncGetStatusIN, PVRSRV_BRIDGE_OUT_SERVERSYNCGETSTATUS *psServerSyncGetStatusOUT, CONNECTION_DATA *psConnection) { SERVER_SYNC_PRIMITIVE * *psSyncHandleInt = IMG_NULL; IMG_HANDLE *hSyncHandleInt2 = IMG_NULL; IMG_UINT32 *pui32UIDInt = IMG_NULL; IMG_UINT32 *pui32FWAddrInt = IMG_NULL; IMG_UINT32 *pui32CurrentOpInt = IMG_NULL; IMG_UINT32 *pui32NextOpInt = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_SYNC_SERVERSYNCGETSTATUS); psServerSyncGetStatusOUT->pui32UID = psServerSyncGetStatusIN->pui32UID; psServerSyncGetStatusOUT->pui32FWAddr = psServerSyncGetStatusIN->pui32FWAddr; psServerSyncGetStatusOUT->pui32CurrentOp = psServerSyncGetStatusIN->pui32CurrentOp; psServerSyncGetStatusOUT->pui32NextOp = psServerSyncGetStatusIN->pui32NextOp; if (psServerSyncGetStatusIN->ui32SyncCount != 0) { psSyncHandleInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)); if (!psSyncHandleInt) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } hSyncHandleInt2 = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)); if (!hSyncHandleInt2) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psServerSyncGetStatusIN->phSyncHandle, psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) || (OSCopyFromUser(NULL, hSyncHandleInt2, psServerSyncGetStatusIN->phSyncHandle, psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto ServerSyncGetStatus_exit; } if (psServerSyncGetStatusIN->ui32SyncCount != 0) { pui32UIDInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)); if (!pui32UIDInt) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } } if (psServerSyncGetStatusIN->ui32SyncCount != 0) { pui32FWAddrInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)); if (!pui32FWAddrInt) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } } if (psServerSyncGetStatusIN->ui32SyncCount != 0) { pui32CurrentOpInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)); if (!pui32CurrentOpInt) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } } if (psServerSyncGetStatusIN->ui32SyncCount != 0) { pui32NextOpInt = OSAllocMem(psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32)); if (!pui32NextOpInt) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto ServerSyncGetStatus_exit; } } { IMG_UINT32 i; for (i=0;i<psServerSyncGetStatusIN->ui32SyncCount;i++) { { /* Look up the address from the handle */ psServerSyncGetStatusOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hSyncHandleInt2[i], psServerSyncGetStatusIN->phSyncHandle[i], PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE); if(psServerSyncGetStatusOUT->eError != PVRSRV_OK) { goto ServerSyncGetStatus_exit; } /* Look up the data from the resman address */ psServerSyncGetStatusOUT->eError = ResManFindPrivateDataByPtr(hSyncHandleInt2[i], (IMG_VOID **) &psSyncHandleInt[i]); if(psServerSyncGetStatusOUT->eError != PVRSRV_OK) { goto ServerSyncGetStatus_exit; } } } } psServerSyncGetStatusOUT->eError = PVRSRVServerSyncGetStatusKM( psServerSyncGetStatusIN->ui32SyncCount, psSyncHandleInt, pui32UIDInt, pui32FWAddrInt, pui32CurrentOpInt, pui32NextOpInt); if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32UID, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32UID, pui32UIDInt, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto ServerSyncGetStatus_exit; } if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32FWAddr, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32FWAddr, pui32FWAddrInt, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto ServerSyncGetStatus_exit; } if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32CurrentOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32CurrentOp, pui32CurrentOpInt, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto ServerSyncGetStatus_exit; } if ( !OSAccessOK(PVR_VERIFY_WRITE, (IMG_VOID*) psServerSyncGetStatusOUT->pui32NextOp, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) || (OSCopyToUser(NULL, psServerSyncGetStatusOUT->pui32NextOp, pui32NextOpInt, (psServerSyncGetStatusIN->ui32SyncCount * sizeof(IMG_UINT32))) != PVRSRV_OK) ) { psServerSyncGetStatusOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto ServerSyncGetStatus_exit; } ServerSyncGetStatus_exit: if (psSyncHandleInt) OSFreeMem(psSyncHandleInt); if (hSyncHandleInt2) OSFreeMem(hSyncHandleInt2); if (pui32UIDInt) OSFreeMem(pui32UIDInt); if (pui32FWAddrInt) OSFreeMem(pui32FWAddrInt); if (pui32CurrentOpInt) OSFreeMem(pui32CurrentOpInt); if (pui32NextOpInt) OSFreeMem(pui32NextOpInt); return 0; }
static IMG_INT PVRSRVBridgeRGXKickCDM(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RGXKICKCDM *psRGXKickCDMIN, PVRSRV_BRIDGE_OUT_RGXKICKCDM *psRGXKickCDMOUT, CONNECTION_DATA *psConnection) { RGX_SERVER_COMPUTE_CONTEXT * psComputeContextInt = IMG_NULL; IMG_HANDLE hComputeContextInt2 = IMG_NULL; PRGXFWIF_UFO_ADDR *sClientFenceUFOAddressInt = IMG_NULL; IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL; PRGXFWIF_UFO_ADDR *sClientUpdateUFOAddressInt = IMG_NULL; IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL; IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL; SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL; IMG_HANDLE *hServerSyncsInt2 = IMG_NULL; IMG_BYTE *psDMCmdInt = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RGXCMP_RGXKICKCDM); if (psRGXKickCDMIN->ui32ClientFenceCount != 0) { sClientFenceUFOAddressInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)); if (!sClientFenceUFOAddressInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psClientFenceUFOAddress, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) || (OSCopyFromUser(NULL, sClientFenceUFOAddressInt, psRGXKickCDMIN->psClientFenceUFOAddress, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32ClientFenceCount != 0) { ui32ClientFenceValueInt = OSAllocMem(psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)); if (!ui32ClientFenceValueInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientFenceValue, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickCDMIN->pui32ClientFenceValue, psRGXKickCDMIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32ClientUpdateCount != 0) { sClientUpdateUFOAddressInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)); if (!sClientUpdateUFOAddressInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psClientUpdateUFOAddress, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) || (OSCopyFromUser(NULL, sClientUpdateUFOAddressInt, psRGXKickCDMIN->psClientUpdateUFOAddress, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(PRGXFWIF_UFO_ADDR)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32ClientUpdateCount != 0) { ui32ClientUpdateValueInt = OSAllocMem(psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)); if (!ui32ClientUpdateValueInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ClientUpdateValue, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickCDMIN->pui32ClientUpdateValue, psRGXKickCDMIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32ServerSyncCount != 0) { ui32ServerSyncFlagsInt = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)); if (!ui32ServerSyncFlagsInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->pui32ServerSyncFlags, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) || (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickCDMIN->pui32ServerSyncFlags, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32ServerSyncCount != 0) { psServerSyncsInt = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *)); if (!psServerSyncsInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } hServerSyncsInt2 = OSAllocMem(psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)); if (!hServerSyncsInt2) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->phServerSyncs, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) || (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickCDMIN->phServerSyncs, psRGXKickCDMIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } if (psRGXKickCDMIN->ui32CmdSize != 0) { psDMCmdInt = OSAllocMem(psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)); if (!psDMCmdInt) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RGXKickCDM_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickCDMIN->psDMCmd, psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) || (OSCopyFromUser(NULL, psDMCmdInt, psRGXKickCDMIN->psDMCmd, psRGXKickCDMIN->ui32CmdSize * sizeof(IMG_BYTE)) != PVRSRV_OK) ) { psRGXKickCDMOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RGXKickCDM_exit; } { /* Look up the address from the handle */ psRGXKickCDMOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hComputeContextInt2, psRGXKickCDMIN->hComputeContext, PVRSRV_HANDLE_TYPE_RGX_SERVER_COMPUTE_CONTEXT); if(psRGXKickCDMOUT->eError != PVRSRV_OK) { goto RGXKickCDM_exit; } /* Look up the data from the resman address */ psRGXKickCDMOUT->eError = ResManFindPrivateDataByPtr(hComputeContextInt2, (IMG_VOID **) &psComputeContextInt); if(psRGXKickCDMOUT->eError != PVRSRV_OK) { goto RGXKickCDM_exit; } } { IMG_UINT32 i; for (i=0;i<psRGXKickCDMIN->ui32ServerSyncCount;i++) { { /* Look up the address from the handle */ psRGXKickCDMOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hServerSyncsInt2[i], psRGXKickCDMIN->phServerSyncs[i], PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE); if(psRGXKickCDMOUT->eError != PVRSRV_OK) { goto RGXKickCDM_exit; } /* Look up the data from the resman address */ psRGXKickCDMOUT->eError = ResManFindPrivateDataByPtr(hServerSyncsInt2[i], (IMG_VOID **) &psServerSyncsInt[i]); if(psRGXKickCDMOUT->eError != PVRSRV_OK) { goto RGXKickCDM_exit; } } } } psRGXKickCDMOUT->eError = PVRSRVRGXKickCDMKM( psComputeContextInt, psRGXKickCDMIN->ui32ClientFenceCount, sClientFenceUFOAddressInt, ui32ClientFenceValueInt, psRGXKickCDMIN->ui32ClientUpdateCount, sClientUpdateUFOAddressInt, ui32ClientUpdateValueInt, psRGXKickCDMIN->ui32ServerSyncCount, ui32ServerSyncFlagsInt, psServerSyncsInt, psRGXKickCDMIN->ui32CmdSize, psDMCmdInt, psRGXKickCDMIN->bbPDumpContinuous); RGXKickCDM_exit: if (sClientFenceUFOAddressInt) OSFreeMem(sClientFenceUFOAddressInt); if (ui32ClientFenceValueInt) OSFreeMem(ui32ClientFenceValueInt); if (sClientUpdateUFOAddressInt) OSFreeMem(sClientUpdateUFOAddressInt); if (ui32ClientUpdateValueInt) OSFreeMem(ui32ClientUpdateValueInt); if (ui32ServerSyncFlagsInt) OSFreeMem(ui32ServerSyncFlagsInt); if (psServerSyncsInt) OSFreeMem(psServerSyncsInt); if (hServerSyncsInt2) OSFreeMem(hServerSyncsInt2); if (psDMCmdInt) OSFreeMem(psDMCmdInt); 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; }
int MMapPMR(struct file* pFile, struct vm_area_struct* ps_vma) { PVRSRV_ERROR eError; IMG_HANDLE hSecurePMRHandle; IMG_SIZE_T uiLength; IMG_DEVMEM_OFFSET_T uiOffset; unsigned long uiPFN; IMG_HANDLE hPMRResmanHandle; PMR *psPMR; PMR_FLAGS_T ulPMRFlags; IMG_UINT32 ui32CPUCacheFlags; unsigned long ulNewFlags = 0; pgprot_t sPageProt; #if defined(SUPPORT_DRM) // INTEL_TEMP // SINCE PVR_DRM_FILE_FROM_FILE is NOT found CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile->private_data); // INTEL_TEMP // SINCE PVR_DRM_FILE_FROM_FILE is NOT found //if (ps_vma->vm_pgoff > INT_MAX) //{ // ps_vma->vm_pgoff -= ((unsigned int)INT_MAX + 1); // return MMapGEM(pFile, ps_vma); //} #else CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile); #endif /* * Both PVRSRVLookupHandle and ResManFindPrivateDataByPtr * require the bridge mutex to be held for thread safety. */ LinuxLockMutex(&gPVRSRVLock); LinuxLockMutex(&g_sMMapMutex); hSecurePMRHandle=(IMG_HANDLE)((IMG_UINTPTR_T)ps_vma->vm_pgoff); eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hPMRResmanHandle, hSecurePMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); if (eError != PVRSRV_OK) { goto e0; } eError = ResManFindPrivateDataByPtr(hPMRResmanHandle, (IMG_VOID **)&psPMR); if (eError != PVRSRV_OK) { goto e0; } /* Take a reference on the PMR, make's sure that it can't be freed while it's mapped into the user process */ PMRRefPMR(psPMR); LinuxUnLockMutex(&gPVRSRVLock); eError = PMRLockSysPhysAddresses(psPMR, PAGE_SHIFT); if (eError != PVRSRV_OK) { goto e1; } if (((ps_vma->vm_flags & VM_WRITE) != 0) && ((ps_vma->vm_flags & VM_SHARED) == 0)) { eError = PVRSRV_ERROR_INVALID_PARAMS; goto e1; } /* we ought to call PMR_Flags() here to check the permissions against the requested mode, and possibly to set up the cache control protflags */ eError = PMR_Flags(psPMR, &ulPMRFlags); if (eError != PVRSRV_OK) { goto e1; } ulNewFlags = ps_vma->vm_flags; #if 0 /* Discard user read/write request, we will pull these flags from the PMR */ ulNewFlags &= ~(VM_READ | VM_WRITE); if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_READABLE) { ulNewFlags |= VM_READ; } if (ulPMRFlags & PVRSRV_MEMALLOCFLAG_CPU_WRITEABLE) { ulNewFlags |= VM_WRITE; } #endif ps_vma->vm_flags = ulNewFlags; #if defined(__arm__) sPageProt = __pgprot_modify(ps_vma->vm_page_prot, L_PTE_MT_MASK, vm_get_page_prot(ulNewFlags)); #elif defined(__i386__) || defined(__x86_64) sPageProt = pgprot_modify(ps_vma->vm_page_prot, vm_get_page_prot(ulNewFlags)); #elif defined(__metag__) sPageProt = vm_get_page_prot(ulNewFlags); #else #error Please add pgprot_modify equivalent for your system #endif ui32CPUCacheFlags = DevmemCPUCacheMode(ulPMRFlags); switch (ui32CPUCacheFlags) { case PVRSRV_MEMALLOCFLAG_CPU_UNCACHED: sPageProt = pgprot_noncached(sPageProt); break; case PVRSRV_MEMALLOCFLAG_CPU_WRITE_COMBINE: sPageProt = pgprot_writecombine(sPageProt); break; case PVRSRV_MEMALLOCFLAG_CPU_CACHED: break; default: eError = PVRSRV_ERROR_INVALID_PARAMS; goto e1; } ps_vma->vm_page_prot = sPageProt; uiLength = ps_vma->vm_end - ps_vma->vm_start; for (uiOffset = 0; uiOffset < uiLength; uiOffset += 1ULL<<PAGE_SHIFT) { IMG_SIZE_T uiNumContiguousBytes; IMG_INT32 iStatus; IMG_CPU_PHYADDR sCpuPAddr; IMG_BOOL bValid; struct page *psPage = NULL; uiNumContiguousBytes = 1ULL<<PAGE_SHIFT; eError = PMR_CpuPhysAddr(psPMR, uiOffset, &sCpuPAddr, &bValid); PVR_ASSERT(eError == PVRSRV_OK); if (eError) { goto e2; } /* Only map in pages that are valid, any that aren't will be picked up by the nopage handler which will return a zeroed page for us */ if (bValid) { uiPFN = sCpuPAddr.uiAddr >> PAGE_SHIFT; PVR_ASSERT(((IMG_UINT64)uiPFN << PAGE_SHIFT) == sCpuPAddr.uiAddr); PVR_ASSERT(pfn_valid(uiPFN)); psPage = pfn_to_page(uiPFN); iStatus = vm_insert_page(ps_vma, ps_vma->vm_start + uiOffset, psPage); PVR_ASSERT(iStatus == 0); if(iStatus) { // N.B. not the right error code, but, it doesn't get propagated anyway... :( eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto e2; } } (void)pFile; } ps_vma->vm_flags |= VM_IO; /* Don't include the mapping in core dumps */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) ps_vma->vm_flags |= VM_DONTDUMP; #else ps_vma->vm_flags |= VM_RESERVED; #endif /* * Disable mremap because our nopage handler assumes all * page requests have already been validated. */ ps_vma->vm_flags |= VM_DONTEXPAND; /* Don't allow mapping to be inherited across a process fork */ ps_vma->vm_flags |= VM_DONTCOPY; /* let us see the PMR so we can unlock it later */ ps_vma->vm_private_data = psPMR; /* Install open and close handlers for ref-counting */ ps_vma->vm_ops = &gsMMapOps; LinuxUnLockMutex(&g_sMMapMutex); return 0; /* error exit paths follow */ e2: PVR_DPF((PVR_DBG_ERROR, "don't know how to handle this error. Abort!")); PMRUnlockSysPhysAddresses(psPMR); e1: PMRUnrefPMR(psPMR); goto em1; e0: LinuxUnLockMutex(&gPVRSRVLock); em1: PVR_ASSERT(eError != PVRSRV_OK); PVR_DPF((PVR_DBG_ERROR, "unable to translate error %d", eError)); LinuxUnLockMutex(&g_sMMapMutex); return -ENOENT; // -EAGAIN // or what? }
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 PVRSRVBridgeRIWritePMREntry(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RIWRITEPMRENTRY *psRIWritePMREntryIN, PVRSRV_BRIDGE_OUT_RIWRITEPMRENTRY *psRIWritePMREntryOUT, CONNECTION_DATA *psConnection) { PMR * psPMRHandleInt = IMG_NULL; IMG_HANDLE hPMRHandleInt2 = IMG_NULL; IMG_CHAR *uiTextAInt = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RI_RIWRITEPMRENTRY); { uiTextAInt = OSAllocMem(RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)); if (!uiTextAInt) { psRIWritePMREntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RIWritePMREntry_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRIWritePMREntryIN->puiTextA, RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)) || (OSCopyFromUser(NULL, uiTextAInt, psRIWritePMREntryIN->puiTextA, RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) ) { psRIWritePMREntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RIWritePMREntry_exit; } { /* Look up the address from the handle */ psRIWritePMREntryOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hPMRHandleInt2, psRIWritePMREntryIN->hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); if(psRIWritePMREntryOUT->eError != PVRSRV_OK) { goto RIWritePMREntry_exit; } /* Look up the data from the resman address */ psRIWritePMREntryOUT->eError = ResManFindPrivateDataByPtr(hPMRHandleInt2, (IMG_VOID **) &psPMRHandleInt); if(psRIWritePMREntryOUT->eError != PVRSRV_OK) { goto RIWritePMREntry_exit; } } psRIWritePMREntryOUT->eError = RIWritePMREntryKM( psPMRHandleInt, uiTextAInt, psRIWritePMREntryIN->uiLogicalSize); RIWritePMREntry_exit: if (uiTextAInt) OSFreeMem(uiTextAInt); return 0; }
static IMG_INT PVRSRVBridgeRIWriteMEMDESCEntry(IMG_UINT32 ui32BridgeID, PVRSRV_BRIDGE_IN_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryIN, PVRSRV_BRIDGE_OUT_RIWRITEMEMDESCENTRY *psRIWriteMEMDESCEntryOUT, CONNECTION_DATA *psConnection) { PMR * psPMRHandleInt = IMG_NULL; IMG_HANDLE hPMRHandleInt2 = IMG_NULL; IMG_CHAR *uiTextBInt = IMG_NULL; RI_HANDLE psRIHandleInt = IMG_NULL; IMG_HANDLE hRIHandleInt2 = IMG_NULL; PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RI_RIWRITEMEMDESCENTRY); { uiTextBInt = OSAllocMem(RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)); if (!uiTextBInt) { psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto RIWriteMEMDESCEntry_exit; } } /* Copy the data over */ if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRIWriteMEMDESCEntryIN->puiTextB, RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)) || (OSCopyFromUser(NULL, uiTextBInt, psRIWriteMEMDESCEntryIN->puiTextB, RI_MAX_TEXT_LEN * sizeof(IMG_CHAR)) != PVRSRV_OK) ) { psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_INVALID_PARAMS; goto RIWriteMEMDESCEntry_exit; } { /* Look up the address from the handle */ psRIWriteMEMDESCEntryOUT->eError = PVRSRVLookupHandle(psConnection->psHandleBase, (IMG_HANDLE *) &hPMRHandleInt2, psRIWriteMEMDESCEntryIN->hPMRHandle, PVRSRV_HANDLE_TYPE_PHYSMEM_PMR); if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) { goto RIWriteMEMDESCEntry_exit; } /* Look up the data from the resman address */ psRIWriteMEMDESCEntryOUT->eError = ResManFindPrivateDataByPtr(hPMRHandleInt2, (IMG_VOID **) &psPMRHandleInt); if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) { goto RIWriteMEMDESCEntry_exit; } } psRIWriteMEMDESCEntryOUT->eError = RIWriteMEMDESCEntryKM( psPMRHandleInt, uiTextBInt, psRIWriteMEMDESCEntryIN->uiOffset, psRIWriteMEMDESCEntryIN->uiSize, psRIWriteMEMDESCEntryIN->bIsImport, psRIWriteMEMDESCEntryIN->bIsExportable, &psRIHandleInt); /* Exit early if bridged call fails */ if(psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) { goto RIWriteMEMDESCEntry_exit; } /* Create a resman item and overwrite the handle with it */ hRIHandleInt2 = ResManRegisterRes(psConnection->hResManContext, RESMAN_TYPE_RI_HANDLE, psRIHandleInt, (RESMAN_FREE_FN)&RIDeleteMEMDESCEntryKM); if (hRIHandleInt2 == IMG_NULL) { psRIWriteMEMDESCEntryOUT->eError = PVRSRV_ERROR_UNABLE_TO_REGISTER_RESOURCE; goto RIWriteMEMDESCEntry_exit; } psRIWriteMEMDESCEntryOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase, &psRIWriteMEMDESCEntryOUT->hRIHandle, (IMG_HANDLE) hRIHandleInt2, PVRSRV_HANDLE_TYPE_RI_HANDLE, PVRSRV_HANDLE_ALLOC_FLAG_NONE ); if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) { goto RIWriteMEMDESCEntry_exit; } RIWriteMEMDESCEntry_exit: if (psRIWriteMEMDESCEntryOUT->eError != PVRSRV_OK) { /* If we have a valid resman item we should undo the bridge function by freeing the resman item */ if (hRIHandleInt2) { PVRSRV_ERROR eError = ResManFreeResByPtr(hRIHandleInt2); /* Freeing a resource should never fail... */ PVR_ASSERT((eError == PVRSRV_OK) || (eError == PVRSRV_ERROR_RETRY)); } else if (psRIHandleInt) { RIDeleteMEMDESCEntryKM(psRIHandleInt); } } if (uiTextBInt) OSFreeMem(uiTextBInt); return 0; }