PVRSRV_ERROR PVRSRVRegisterSystemISRHandler (PFN_ISR_HANDLER pfnISRHandler, IMG_VOID *pvISRHandlerData, IMG_UINT32 ui32ISRSourceMask, IMG_UINT32 ui32DeviceID) { SYS_DATA *psSysData; PVRSRV_DEVICE_NODE *psDevNode; PVR_UNREFERENCED_PARAMETER(ui32ISRSourceMask); SysAcquireData(&psSysData); psDevNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, MatchDeviceKM_AnyVaCb, ui32DeviceID, IMG_TRUE); if (psDevNode == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRegisterSystemISRHandler: Failed to get psDevNode")); PVR_DBG_BREAK; return PVRSRV_ERROR_GENERIC; } psDevNode->pvISRData = (IMG_VOID*) pvISRHandlerData; psDevNode->pfnDeviceISR = pfnISRHandler; return PVRSRV_OK; }
PVRSRV_ERROR PVRSRVRemoveDCDeviceKM(IMG_UINT32 ui32DevIndex) { SYS_DATA *psSysData; PVRSRV_DEVICE_NODE *psDeviceNode; PVRSRV_DISPLAYCLASS_INFO *psDCInfo; SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_FALSE, PVRSRV_DEVICE_CLASS_DISPLAY); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: requested device %d not present", ui32DevIndex)); return PVRSRV_ERROR_GENERIC; } psDCInfo = (PVRSRV_DISPLAYCLASS_INFO*)psDeviceNode->pvDevice; if(psDCInfo->ui32RefCount == 0) { List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); SysRemoveExternalDevice(psDeviceNode); PVR_ASSERT(psDCInfo->ui32RefCount == 0); (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DC_SRV2DISP_KMJTABLE), psDCInfo->psFuncTable, IMG_NULL); psDCInfo->psFuncTable = IMG_NULL; (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DISPLAYCLASS_INFO), psDCInfo, IMG_NULL); (IMG_VOID)OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); } else { PVR_DPF((PVR_DBG_ERROR,"PVRSRVRemoveDCDeviceKM: failed as %d Services DC API connections are still open", psDCInfo->ui32RefCount)); return PVRSRV_ERROR_GENERIC; } return PVRSRV_OK; }
/*! ****************************************************************************** @Function PVRSRVInitialiseDevice @Description initialises device by index @Input ui32DevIndex : Index to the required device @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVInitialiseDevice (IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVInitialiseDevice")); SysAcquireData(&psSysData); /* Find device in the list */ psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if(!psDeviceNode) { /* Devinfo not in the list */ PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: requested device is not present")); return PVRSRV_ERROR_INIT_FAILURE; } /* FoundDevice: */ PVR_ASSERT (psDeviceNode->ui32RefCount > 0); /* Create the device's resource manager context. */ eError = PVRSRVResManConnect(IMG_NULL, &psDeviceNode->hResManContext); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed PVRSRVResManConnect call")); return eError; } /* Initialise the device */ if(psDeviceNode->pfnInitDevice != IMG_NULL) { eError = psDeviceNode->pfnInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVInitialiseDevice: Failed InitDevice call")); return eError; } } return PVRSRV_OK; }
/*! ****************************************************************************** @Function PVRSRVAcquireDeviceDataKM @Description Returns device information @Input ui32DevIndex : Index to the required device obtained from the PVRSRVEnumerateDevice function @Input eDeviceType : Required device type. If type is unknown use ui32DevIndex to locate device data @Output *phDevCookie : Dev Cookie @Return PVRSRV_ERROR : ******************************************************************************/ IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex, PVRSRV_DEVICE_TYPE eDeviceType, IMG_HANDLE *phDevCookie) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM")); SysAcquireData(&psSysData); /* Find device in the list */ psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &PVRSRVAcquireDeviceDataKM_Match_AnyVaCb, eDeviceType, ui32DevIndex); if (!psDeviceNode) { /* device can't be found in the list so it isn't in the system */ PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present")); return PVRSRV_ERROR_INIT_FAILURE; } /*FoundDevice:*/ PVR_ASSERT (psDeviceNode->ui32RefCount > 0); /* return the dev cookie? */ if (phDevCookie) { *phDevCookie = (IMG_HANDLE)psDeviceNode; } return PVRSRV_OK; }
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV PVRSRVAcquireDeviceDataKM (IMG_UINT32 ui32DevIndex, PVRSRV_DEVICE_TYPE eDeviceType, IMG_HANDLE *phDevCookie) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVAcquireDeviceDataKM")); SysAcquireData(&psSysData); psDeviceNode = List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, PVRSRVAcquireDeviceDataKM_Match_AnyVaCb, eDeviceType, ui32DevIndex); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVAcquireDeviceDataKM: requested device is not present")); return PVRSRV_ERROR_INIT_FAILURE; } PVR_ASSERT (psDeviceNode->ui32RefCount > 0); if (phDevCookie) { *phDevCookie = (IMG_HANDLE)psDeviceNode; } return PVRSRV_OK; }
PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); return PVRSRV_ERROR_DEVICEID_NOT_FOUND; } eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, PVRSRV_DEV_POWER_STATE_OFF, KERNEL_ID, IMG_FALSE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); return eError; } eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, IMG_NULL, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); return eError; } if(psDeviceNode->pfnDeInitDevice != IMG_NULL) { eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); return eError; } } PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); psDeviceNode->hResManContext = IMG_NULL; List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); return (PVRSRV_OK); }
/*! ****************************************************************************** @Function PVRSRVDeinitialiseDevice @Description This De-inits device @Input ui32DevIndex : Index to the required device @Return PVRSRV_ERROR : ******************************************************************************/ PVRSRV_ERROR IMG_CALLCONV PVRSRVDeinitialiseDevice(IMG_UINT32 ui32DevIndex) { PVRSRV_DEVICE_NODE *psDeviceNode; SYS_DATA *psSysData; PVRSRV_ERROR eError; SysAcquireData(&psSysData); psDeviceNode = (PVRSRV_DEVICE_NODE*) List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList, &MatchDeviceKM_AnyVaCb, ui32DevIndex, IMG_TRUE); if (!psDeviceNode) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: requested device %d is not present", ui32DevIndex)); return PVRSRV_ERROR_DEVICEID_NOT_FOUND; } eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVPowerLock call")); return eError; } /* Power down the device if necessary. */ eError = PVRSRVSetDevicePowerStateKM(ui32DevIndex, PVRSRV_DEV_POWER_STATE_OFF); PVRSRVPowerUnlock(KERNEL_ID); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed PVRSRVSetDevicePowerStateKM call")); return eError; } /* Free the dissociated device memory. */ eError = ResManFreeResByCriteria(psDeviceNode->hResManContext, RESMAN_CRITERIA_RESTYPE, RESMAN_TYPE_DEVICEMEM_ALLOCATION, IMG_NULL, 0); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed ResManFreeResByCriteria call")); return eError; } /* De-init the device. */ if(psDeviceNode->pfnDeInitDevice != IMG_NULL) { eError = psDeviceNode->pfnDeInitDevice(psDeviceNode); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVDeinitialiseDevice: Failed DeInitDevice call")); return eError; } } /* Close the device's resource manager context. */ PVRSRVResManDisconnect(psDeviceNode->hResManContext, IMG_TRUE); psDeviceNode->hResManContext = IMG_NULL; /* remove node from list */ List_PVRSRV_DEVICE_NODE_Remove(psDeviceNode); /* deallocate id and memory */ (IMG_VOID)FreeDeviceID(psSysData, ui32DevIndex); OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP, sizeof(PVRSRV_DEVICE_NODE), psDeviceNode, IMG_NULL); /*not nulling pointer, out of scope*/ return (PVRSRV_OK); }
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; }