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; }
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; }