/* PVRSRVConnectionConnect*/ PVRSRV_ERROR PVRSRVConnectionConnect(IMG_PVOID *ppvPrivData, IMG_PVOID pvOSData) { PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); CONNECTION_DATA *psConnection; PVRSRV_ERROR eError = PVRSRV_OK; /* Allocate per-process data area */ psConnection = OSAllocMem(sizeof(*psConnection)); if (psConnection == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't allocate per-process data (%d)", eError)); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psConnection, 0, sizeof(*psConnection)); /* Call environment specific per process init function */ eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: OSConnectionPrivateDataInit failed (%d)", eError)); goto failure; } /* Allocate handle base for this process */ eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't allocate handle base for process (%d)", eError)); goto failure; } /* Create a resource manager context for the process */ eError = PVRSRVResManConnect(psPVRSRVData->hResManDeferContext, &psConnection->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVConnectionConnect: Couldn't register with the resource manager")); goto failure; } *ppvPrivData = psConnection; return eError; failure: (IMG_VOID)FreeConnectionData(psConnection); return eError; }
/*! ****************************************************************************** @Function PVRSRVHandleInit @Description Initialise handle management @Return Error code or PVRSRV_OK ******************************************************************************/ PVRSRV_ERROR PVRSRVHandleInit(IMG_VOID) { PVRSRV_ERROR eError; PVR_ASSERT(gpsKernelHandleBase == IMG_NULL); PVR_ASSERT(gpsHandleFuncs == IMG_NULL); eError = PVRSRVHandleGetFuncTable(&gpsHandleFuncs); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVHandleGetFuncTable failed (%s)", PVRSRVGetErrorStringKM(eError))); goto error; } eError = PVRSRVAllocHandleBase(&gpsKernelHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVAllocHandleBase failed (%s)", PVRSRVGetErrorStringKM(eError))); goto error; } eError = gpsHandleFuncs->pfnEnableHandlePurging(gpsKernelHandleBase->psImplBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVHandleInit: PVRSRVEnableHandlePurging failed (%s)", PVRSRVGetErrorStringKM(eError))); goto error; } return PVRSRV_OK; error: (IMG_VOID) PVRSRVHandleDeInit(); return eError; }
/*! ****************************************************************************** @Function PVRSRVPerProcessDataConnect @Description Allocate per-process data area, or increment refcount if one already exists for this PID. @Input ui32PID - process ID ppsPerProc - Pointer to per-process data area @Return PVRSRV_ERROR ******************************************************************************/ PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) { PVRSRV_PER_PROCESS_DATA *psPerProc; IMG_HANDLE hBlockAlloc; PVRSRV_ERROR eError = PVRSRV_OK; if (psHashTab == IMG_NULL) { return PVRSRV_ERROR_INIT_FAILURE; } /* Look for existing per-process data area */ psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); if (psPerProc == IMG_NULL) { /* Allocate per-process data area */ eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(*psPerProc), (IMG_PVOID *)&psPerProc, &hBlockAlloc, "Per Process Data"); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError)); return eError; } OSMemSet(psPerProc, 0, sizeof(*psPerProc)); psPerProc->hBlockAlloc = hBlockAlloc; if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc)) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table")); eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED; goto failure; } psPerProc->ui32PID = ui32PID; psPerProc->ui32RefCount = 0; #if defined(SUPPORT_PDUMP_MULTI_PROCESS) if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE) { psPerProc->bPDumpActive = IMG_TRUE; } #else PVR_UNREFERENCED_PARAMETER(ui32Flags); #endif /* Call environment specific per process init function */ eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError)); goto failure; } /* Allocate a handle for the per-process data area */ eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, &psPerProc->hPerProcData, psPerProc, PVRSRV_HANDLE_TYPE_PERPROC_DATA, PVRSRV_HANDLE_ALLOC_FLAG_NONE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError)); goto failure; } /* Allocate handle base for this process */ eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError)); goto failure; } /* Set per-process handle options */ eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError)); goto failure; } /* Create a resource manager context for the process */ eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager")); goto failure; } #if defined (TTRACE) PVRSRVTimeTraceBufferCreate(ui32PID); #endif } psPerProc->ui32RefCount++; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", ui32PID, psPerProc->ui32RefCount)); return eError; failure: (IMG_VOID)FreePerProcessData(psPerProc); return eError; }
enum PVRSRV_ERROR PVRSRVPerProcessDataConnect(u32 ui32PID) { struct PVRSRV_PER_PROCESS_DATA *psPerProc; void *hBlockAlloc; enum PVRSRV_ERROR eError = PVRSRV_OK; PVR_ASSERT(psHashTab != NULL); psPerProc = (struct PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (u32)ui32PID); if (psPerProc == NULL) { eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(*psPerProc), (void **)&psPerProc, &hBlockAlloc); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't allocate per-process data (%d)", eError); return eError; } OSMemSet(psPerProc, 0, sizeof(*psPerProc)); psPerProc->hBlockAlloc = hBlockAlloc; if (!HASH_Insert(psHashTab, (u32) ui32PID, (u32)psPerProc)) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't insert per-process data into hash table"); eError = PVRSRV_ERROR_GENERIC; goto failure; } psPerProc->ui32PID = ui32PID; psPerProc->ui32RefCount = 0; eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "OSPerProcessPrivateDataInit failed (%d)", eError); goto failure; } eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, &psPerProc->hPerProcData, psPerProc, PVRSRV_HANDLE_TYPE_PERPROC_DATA, PVRSRV_HANDLE_ALLOC_FLAG_NONE); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't allocate handle for per-process data (%d)", eError); goto failure; } eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't allocate handle base for process (%d)", eError); goto failure; } eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't set handle options (%d)", eError); goto failure; } eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: " "Couldn't register with the resource manager"); goto failure; } } psPerProc->ui32RefCount++; PVR_DPF(PVR_DBG_MESSAGE, "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", ui32PID, psPerProc->ui32RefCount); return eError; failure: (void)FreePerProcessData(psPerProc); return eError; }
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID, IMG_UINT32 ui32Flags) { PVRSRV_PER_PROCESS_DATA *psPerProc; IMG_HANDLE hBlockAlloc; PVRSRV_ERROR eError = PVRSRV_OK; PVR_ASSERT(psHashTab != IMG_NULL); psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID); if (psPerProc == IMG_NULL) { eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(*psPerProc), (IMG_PVOID *)&psPerProc, &hBlockAlloc, "Per Process Data"); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError)); return eError; } OSMemSet(psPerProc, 0, sizeof(*psPerProc)); psPerProc->hBlockAlloc = hBlockAlloc; /* * FIXME: using a hash to retrieve psPerProc makes not much * sense. We always want to have this struct on the IOCTL path * for the current task, so it'd be just a matter of storing * it in the file private object. Until this is resolved and * we get rid of this pid specific lookup make sure the above * assumption holds. */ WARN_ON(OSGetCurrentProcessIDKM() != ui32PID); get_task_comm(psPerProc->name, current); if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc)) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table")); eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED; goto failure; } psPerProc->ui32PID = ui32PID; psPerProc->ui32RefCount = 0; #if defined(PERPROC_LIST) List_PVRSRV_PER_PROCESS_DATA_Insert(&psPerProcList, psPerProc); /*PVR_LOG(("MarkTupsperproc %d\n", ui32PID));*/ #endif #if defined(SUPPORT_PDUMP_MULTI_PROCESS) if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE) { psPerProc->bPDumpActive = IMG_TRUE; } #else PVR_UNREFERENCED_PARAMETER(ui32Flags); #endif eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError)); goto failure; } eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE, &psPerProc->hPerProcData, psPerProc, PVRSRV_HANDLE_TYPE_PERPROC_DATA, PVRSRV_HANDLE_ALLOC_FLAG_NONE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError)); goto failure; } eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError)); goto failure; } eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError)); goto failure; } eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager")); goto failure; } } psPerProc->ui32RefCount++; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d", ui32PID, psPerProc->ui32RefCount)); return eError; failure: (IMG_VOID)FreePerProcessData(psPerProc); return eError; }