static PVRSRV_ERROR CloseDCDeviceCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; PVRSRV_DISPLAYCLASS_INFO *psDCInfo; PVR_UNREFERENCED_PARAMETER(ui32Param); psDCPerContextInfo = (PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *)pvParam; psDCInfo = psDCPerContextInfo->psDCInfo; psDCInfo->ui32RefCount--; if(psDCInfo->ui32RefCount == 0) { psDCInfo->psFuncTable->pfnCloseDCDevice(psDCInfo->hExtDevice); PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); psDCInfo->hDevMemContext = IMG_NULL; psDCInfo->hExtDevice = IMG_NULL; } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, IMG_NULL); return PVRSRV_OK; }
static enum PVRSRV_ERROR DestroyDCSwapChainCallBack(void *pvParam, u32 ui32Param) { enum PVRSRV_ERROR eError; struct PVRSRV_DC_SWAPCHAIN *psSwapChain = pvParam; struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo = psSwapChain->psDCInfo; u32 i; PVR_UNREFERENCED_PARAMETER(ui32Param); PVRSRVDestroyCommandQueueKM(psSwapChain->psQueue); eError = psDCInfo->psFuncTable->pfnDestroyDCSwapChain(psDCInfo->hExtDevice, psSwapChain-> hExtSwapChain); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "DestroyDCSwapChainCallBack: " "Failed to destroy DC swap chain"); return eError; } for (i = 0; i < psSwapChain->ui32BufferCount; i++) if (psSwapChain->asBuffer[i].sDeviceClassBuffer. psKernelSyncInfo) PVRSRVFreeSyncInfoKM(psSwapChain->asBuffer[i]. sDeviceClassBuffer. psKernelSyncInfo); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DC_SWAPCHAIN), psSwapChain, NULL); return eError; }
static enum PVRSRV_ERROR CloseDCDeviceCallBack(void *pvParam, u32 ui32Param) { struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; PVR_UNREFERENCED_PARAMETER(ui32Param); psDCPerContextInfo = (struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *) pvParam; psDCInfo = psDCPerContextInfo->psDCInfo; psDCInfo->ui32RefCount--; if (psDCInfo->ui32RefCount == 0) { struct PVRSRV_DC_SRV2DISP_KMJTABLE *jtbl; jtbl = psDCInfo->psFuncTable; jtbl->pfnCloseDCDevice(psDCInfo->hExtDevice); PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer. psKernelSyncInfo); psDCInfo->hDevMemContext = NULL; psDCInfo->hExtDevice = NULL; module_put(jtbl->owner); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO), psDCPerContextInfo, NULL); return PVRSRV_OK; }
static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; PVR_UNREFERENCED_PARAMETER(ui32Param); psMemInfo->ui32RefCount--; if(psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) { IMG_HANDLE hMemInfo = IMG_NULL; if (psMemInfo->ui32RefCount != 0) { PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: mappings are open in other processes")); return PVRSRV_ERROR_GENERIC; } eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, &hMemInfo, psMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: can't find exported meminfo in the global handle list")); return eError; } eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, hMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeDeviceMemCallBack: PVRSRVReleaseHandle failed for exported meminfo")); return eError; } } PVR_ASSERT(psMemInfo->ui32RefCount == 0); if (psMemInfo->psKernelSyncInfo) { eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); } if (eError == PVRSRV_OK) { eError = FreeDeviceMem(psMemInfo); } return eError; }
static inline void put_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo) { struct PVRSRV_DEVICE_NODE *dev = syncinfo->dev_cookie; syncinfo->refcount--; if (!syncinfo->refcount) { HASH_Remove(dev->sync_table, syncinfo->phys_addr.uiAddr); PVRSRVFreeSyncInfoKM(syncinfo); } }
static PVRSRV_ERROR UnmapDeviceMemoryCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param, IMG_BOOL bDummy) { PVRSRV_ERROR eError; RESMAN_MAP_DEVICE_MEM_DATA *psMapData = pvParam; PVR_UNREFERENCED_PARAMETER(ui32Param); if(psMapData->psMemInfo->sMemBlk.psIntSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMapData->psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); psMapData->psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; } if( psMapData->psMemInfo->psKernelSyncInfo ) { psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount--; if (psMapData->psMemInfo->psKernelSyncInfo->ui32RefCount == 0) { eError = PVRSRVFreeSyncInfoKM(psMapData->psMemInfo->psKernelSyncInfo); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free sync info")); return eError; } } } eError = FreeDeviceMem(psMapData->psMemInfo); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"UnmapDeviceMemoryCallBack: Failed to free DST meminfo")); return eError; } eError = FreeMemCallBackCommon(psMapData->psSrcMemInfo, 0, IMG_FALSE); OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RESMAN_MAP_DEVICE_MEM_DATA), psMapData, IMG_NULL); return eError; }
static PVRSRV_ERROR CloseBCDeviceCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; PVRSRV_BUFFERCLASS_INFO *psBCInfo; PVR_UNREFERENCED_PARAMETER(ui32Param); psBCPerContextInfo = (PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *)pvParam; psBCInfo = psBCPerContextInfo->psBCInfo; psBCInfo->ui32RefCount--; if(psBCInfo->ui32RefCount == 0) { IMG_UINT32 i; psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice); 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; } } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, IMG_NULL); return PVRSRV_OK; }
static enum PVRSRV_ERROR CloseBCDeviceCallBack(void *pvParam, u32 ui32Param) { struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; struct PVRSRV_BUFFERCLASS_INFO *psBCInfo; PVR_UNREFERENCED_PARAMETER(ui32Param); psBCPerContextInfo = (struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *) pvParam; psBCInfo = psBCPerContextInfo->psBCInfo; psBCInfo->ui32RefCount--; if (psBCInfo->ui32RefCount == 0) { u32 i; psBCInfo->psFuncTable->pfnCloseBCDevice(psBCInfo->hExtDevice); 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->ui32BufferCount, psBCInfo->psBuffer, NULL); } OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO), psBCPerContextInfo, NULL); return PVRSRV_OK; }
static PVRSRV_ERROR UnwrapExtMemoryCallBack(IMG_PVOID pvParam, IMG_UINT32 ui32Param) { PVRSRV_ERROR eError = PVRSRV_OK; PVRSRV_KERNEL_MEM_INFO *psMemInfo = pvParam; IMG_HANDLE hOSWrapMem; PVR_UNREFERENCED_PARAMETER(ui32Param); hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem; if (psMemInfo->psKernelSyncInfo) { eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); } if(psMemInfo->sMemBlk.psIntSysPAddr) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(IMG_SYS_PHYADDR), psMemInfo->sMemBlk.psIntSysPAddr, IMG_NULL); psMemInfo->sMemBlk.psIntSysPAddr = IMG_NULL; } if (eError == PVRSRV_OK) { psMemInfo->ui32RefCount--; eError = FreeDeviceMem(psMemInfo); } if(hOSWrapMem) { OSReleasePhysPageAddr(hOSWrapMem); } return eError; }
static PVRSRV_ERROR FreeMemCallBackCommon(PVRSRV_KERNEL_MEM_INFO *psMemInfo, IMG_UINT32 ui32Param, IMG_BOOL bFromAllocator) { PVRSRV_ERROR eError = PVRSRV_OK; PVR_UNREFERENCED_PARAMETER(ui32Param); psMemInfo->ui32RefCount--; if (psMemInfo->ui32RefCount == 0) { if(psMemInfo->ui32Flags & PVRSRV_MEM_EXPORTED) { IMG_HANDLE hMemInfo = IMG_NULL; eError = PVRSRVFindHandle(KERNEL_HANDLE_BASE, &hMemInfo, psMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: can't find exported meminfo in the global handle list")); return eError; } eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, hMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: PVRSRVReleaseHandle failed for exported meminfo")); return eError; } } switch(psMemInfo->memType) { case PVRSRV_MEMTYPE_WRAPPED: freeWrapped(psMemInfo); case PVRSRV_MEMTYPE_DEVICE: if (psMemInfo->psKernelSyncInfo) { psMemInfo->psKernelSyncInfo->ui32RefCount--; if (psMemInfo->psKernelSyncInfo->ui32RefCount == 0) { eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo); } } case PVRSRV_MEMTYPE_DEVICECLASS: break; default: PVR_DPF((PVR_DBG_ERROR, "FreeMemCallBackCommon: Unknown memType")); eError = PVRSRV_ERROR_INVALID_MEMINFO; } } eError = FreeDeviceMem2(psMemInfo, bFromAllocator); return eError; }
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; }
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; }
enum PVRSRV_ERROR PVRSRVOpenBCDeviceKM( struct PVRSRV_PER_PROCESS_DATA *psPerProc, u32 ui32DeviceID, void *hDevCookie, void **phDeviceKM) { struct PVRSRV_BUFFERCLASS_INFO *psBCInfo; struct PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; struct PVRSRV_DEVICE_NODE *psDeviceNode; struct SYS_DATA *psSysData; u32 i; enum PVRSRV_ERROR eError; if (!phDeviceKM || !hDevCookie) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: Invalid params"); return PVRSRV_ERROR_GENERIC; } if (SysAcquireData(&psSysData) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: Failed to get SysData"); return PVRSRV_ERROR_GENERIC; } psDeviceNode = psSysData->psDeviceNodeList; while (psDeviceNode) { if ((psDeviceNode->sDevId.eDeviceClass == PVRSRV_DEVICE_CLASS_BUFFER) && (psDeviceNode->sDevId.ui32DeviceIndex == ui32DeviceID)) { psBCInfo = (struct PVRSRV_BUFFERCLASS_INFO *) psDeviceNode->pvDevice; goto FoundDevice; } psDeviceNode = psDeviceNode->psNext; } PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID); return PVRSRV_ERROR_GENERIC; FoundDevice: if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBCPerContextInfo), (void **)&psBCPerContextInfo, NULL) != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed psBCPerContextInfo alloc"); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); if (psBCInfo->ui32RefCount++ == 0) { struct BUFFER_INFO sBufferInfo; psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie; psBCInfo->hDevMemContext = (void *) psDeviceNode->sDevMemoryInfo.pBMKernelContext; eError = psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo-> hExtDevice); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed to open external BC device"); return eError; } eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM : Failed to get BC Info"); return eError; } psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, (void **) &psBCInfo->psBuffer, NULL); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed to allocate BC buffers"); return eError; } OSMemSet(psBCInfo->psBuffer, 0, sizeof(struct PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); for (i = 0; i < psBCInfo->ui32BufferCount; i++) { eError = PVRSRVAllocSyncInfoKM(NULL, psBCInfo->hDevMemContext, &psBCInfo->psBuffer[i].sDeviceClassBuffer. psKernelSyncInfo); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed sync info alloc"); goto ErrorExit; } eError = psBCInfo->psFuncTable->pfnGetBCBuffer( psBCInfo->hExtDevice, i, psBCInfo->psBuffer[i].sDeviceClassBuffer. psKernelSyncInfo-> psSyncData, &psBCInfo->psBuffer[i].sDeviceClassBuffer. hExtBuffer); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVOpenBCDeviceKM: " "Failed to get BC buffers"); goto ErrorExit; } psBCInfo->psBuffer[i].sDeviceClassBuffer. pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; psBCInfo->psBuffer[i].sDeviceClassBuffer. hDevMemContext = psBCInfo->hDevMemContext; psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; } } psBCPerContextInfo->psBCInfo = psBCInfo; psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_BUFFERCLASS_DEVICE, psBCPerContextInfo, 0, CloseBCDeviceCallBack); *phDeviceKM = (void *)psBCPerContextInfo; return PVRSRV_OK; ErrorExit: for (i = 0; i < psBCInfo->ui32BufferCount; i++) { if (psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) { PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i]. sDeviceClassBuffer. psKernelSyncInfo); } } if (psBCInfo->psBuffer) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct PVRSRV_BC_BUFFER), psBCInfo->psBuffer, NULL); } return eError; }
IMG_EXPORT PVRSRV_ERROR PVRSRVOpenDCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_UINT32 ui32DeviceID, IMG_HANDLE hDevCookie, IMG_HANDLE *phDeviceKM) { PVRSRV_DISPLAYCLASS_INFO *psDCInfo; PVRSRV_DISPLAYCLASS_PERCONTEXT_INFO *psDCPerContextInfo; PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; if(!phDeviceKM || !hDevCookie) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Invalid params")); return PVRSRV_ERROR_GENERIC; } SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, MatchDeviceKM_AnyVaCb, ui32DeviceID, IMG_FALSE, PVRSRV_DEVICE_CLASS_DISPLAY); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: no devnode matching index %d", ui32DeviceID)); return PVRSRV_ERROR_GENERIC; } psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psDCPerContextInfo), (IMG_VOID **)&psDCPerContextInfo, IMG_NULL, "Display Class per Context Info") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed psDCPerContextInfo alloc")); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psDCPerContextInfo, 0, sizeof(*psDCPerContextInfo)); if(psDCInfo->ui32RefCount++ == 0) { psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; psDCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; eError = PVRSRVAllocSyncInfoKM(IMG_NULL, (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext, &psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed sync info alloc")); psDCInfo->ui32RefCount--; return eError; } eError = psDCInfo->psFuncTable->pfnOpenDCDevice(ui32DeviceID, &psDCInfo->hExtDevice, (PVRSRV_SYNC_DATA*)psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo->psSyncDataMemInfoKM->pvLinAddrKM); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenDCDeviceKM: Failed to open external DC device")); psDCInfo->ui32RefCount--; PVRSRVFreeSyncInfoKM(psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo); return eError; } } psDCPerContextInfo->psDCInfo = psDCInfo; psDCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_DISPLAYCLASS_DEVICE, psDCPerContextInfo, 0, CloseDCDeviceCallBack); *phDeviceKM = (IMG_HANDLE)psDCPerContextInfo; return PVRSRV_OK; }
IMG_EXPORT PVRSRV_ERROR PVRSRVOpenBCDeviceKM (PVRSRV_PER_PROCESS_DATA *psPerProc, IMG_UINT32 ui32DeviceID, IMG_HANDLE hDevCookie, IMG_HANDLE *phDeviceKM) { PVRSRV_BUFFERCLASS_INFO *psBCInfo; PVRSRV_BUFFERCLASS_PERCONTEXT_INFO *psBCPerContextInfo; PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; IMG_UINT32 i; PVRSRV_ERROR eError; if(!phDeviceKM || !hDevCookie) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Invalid params")); return PVRSRV_ERROR_GENERIC; } SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, MatchDeviceKM_AnyVaCb, ui32DeviceID, IMG_FALSE, PVRSRV_DEVICE_CLASS_BUFFER); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: No devnode matching index %d", ui32DeviceID)); return PVRSRV_ERROR_GENERIC; } psBCInfo = (PVRSRV_BUFFERCLASS_INFO*)psDeviceNode->pvDevice; if(OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*psBCPerContextInfo), (IMG_VOID **)&psBCPerContextInfo, IMG_NULL, "Buffer Class per Context Info") != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed psBCPerContextInfo alloc")); return PVRSRV_ERROR_OUT_OF_MEMORY; } OSMemSet(psBCPerContextInfo, 0, sizeof(*psBCPerContextInfo)); if(psBCInfo->ui32RefCount++ == 0) { BUFFER_INFO sBufferInfo; psDeviceNode = (PVRSRV_DEVICE_NODE *)hDevCookie; psBCInfo->hDevMemContext = (IMG_HANDLE)psDeviceNode->sDevMemoryInfo.pBMKernelContext; eError = psBCInfo->psFuncTable->pfnOpenBCDevice(&psBCInfo->hExtDevice); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to open external BC device")); return eError; } eError = psBCInfo->psFuncTable->pfnGetBCInfo(psBCInfo->hExtDevice, &sBufferInfo); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM : Failed to get BC Info")); return eError; } psBCInfo->ui32BufferCount = sBufferInfo.ui32BufferCount; eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount, (IMG_VOID **)&psBCInfo->psBuffer, IMG_NULL, "Array of Buffer Class Buffer"); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to allocate BC buffers")); return eError; } OSMemSet (psBCInfo->psBuffer, 0, sizeof(PVRSRV_BC_BUFFER) * sBufferInfo.ui32BufferCount); for(i=0; i<psBCInfo->ui32BufferCount; i++) { eError = PVRSRVAllocSyncInfoKM(IMG_NULL, psBCInfo->hDevMemContext, &psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed sync info alloc")); goto ErrorExit; } eError = psBCInfo->psFuncTable->pfnGetBCBuffer(psBCInfo->hExtDevice, i, psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo->psSyncData, &psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtBuffer); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVOpenBCDeviceKM: Failed to get BC buffers")); goto ErrorExit; } psBCInfo->psBuffer[i].sDeviceClassBuffer.pfnGetBufferAddr = psBCInfo->psFuncTable->pfnGetBufferAddr; psBCInfo->psBuffer[i].sDeviceClassBuffer.hDevMemContext = psBCInfo->hDevMemContext; psBCInfo->psBuffer[i].sDeviceClassBuffer.hExtDevice = psBCInfo->hExtDevice; } } psBCPerContextInfo->psBCInfo = psBCInfo; psBCPerContextInfo->hResItem = ResManRegisterRes(psPerProc->hResManContext, RESMAN_TYPE_BUFFERCLASS_DEVICE, psBCPerContextInfo, 0, CloseBCDeviceCallBack); *phDeviceKM = (IMG_HANDLE)psBCPerContextInfo; return PVRSRV_OK; ErrorExit: for(i=0; i<psBCInfo->ui32BufferCount; i++) { if(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo) { PVRSRVFreeSyncInfoKM(psBCInfo->psBuffer[i].sDeviceClassBuffer.psKernelSyncInfo); } } if(psBCInfo->psBuffer) { OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_BC_BUFFER), psBCInfo->psBuffer, IMG_NULL); psBCInfo->psBuffer = IMG_NULL; } return eError; }