static int PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *pFile) { u32 *pui32Args = (u32 *) arg; u32 ui32Cmd = pui32Args[0]; u32 ui32Arg1 = pui32Args[1]; u32 *pui32OutArg = (u32 *) arg; s32 ret = 0; mutex_lock(&gPVRSRVLock); switch (ui32Cmd) { case PVR_DRM_UNPRIV_INIT_SUCCESFUL: *pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0; break; case PVR_DRM_UNPRIV_BUSID_TYPE: *pui32OutArg = PVR_DRM_BUS_TYPE_PCI; break; case PVR_DRM_UNPRIV_BUSID_FIELD: ret = PVRDRMPCIBusIDField(dev, pui32OutArg, ui32Arg1); default: ret = -EFAULT; } mutex_unlock(&gPVRSRVLock); return ret; }
DRI_DRM_STATIC IMG_INT PVRDRMUnprivCmd(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile) { IMG_UINT32 *pui32Args = (IMG_UINT32 *)arg; IMG_UINT32 ui32Cmd = pui32Args[0]; IMG_UINT32 ui32Arg1 = pui32Args[1]; IMG_UINT32 *pui32OutArg = (IMG_UINT32 *)arg; switch (ui32Cmd) { case PVR_DRM_UNPRIV_INIT_SUCCESFUL: *pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0; break; case PVR_DRM_UNPRIV_BUSID_TYPE: *pui32OutArg = PVR_DRM_BUS_TYPE_PCI; break; case PVR_DRM_UNPRIV_BUSID_FIELD: return PVRDRMPCIBusIDField(dev, pui32OutArg, ui32Arg1); default: return -EFAULT; } return 0; }
DRI_DRM_STATIC IMG_INT PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *pFile) { IMG_INT ret = 0; LinuxLockMutex(&gPVRSRVLock); if (arg == NULL) { ret = -EFAULT; } else { IMG_UINT32 *pui32Args = (IMG_UINT32 *)arg; IMG_UINT32 ui32Cmd = pui32Args[0]; IMG_UINT32 *pui32OutArg = (IMG_UINT32 *)arg; switch (ui32Cmd) { case PVR_DRM_UNPRIV_INIT_SUCCESFUL: *pui32OutArg = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0; break; default: ret = -EFAULT; } } LinuxUnLockMutex(&gPVRSRVLock); return ret; }
static int PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *file) { int ret = 0; mutex_lock(&gPVRSRVLock); if (arg == NULL) { ret = -EFAULT; } else { drm_pvr_unpriv_cmd *psCommand = (drm_pvr_unpriv_cmd *)arg; switch (psCommand->cmd) { case DRM_PVR_UNPRIV_CMD_INIT_SUCCESFUL: psCommand->result = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0; break; default: ret = -EFAULT; } } mutex_unlock(&gPVRSRVLock); return ret; }
PVRSRV_ERROR PVRSRVInitSrvConnectKM(CONNECTION_DATA *psConnection) { /* PRQA S 3415 1 */ /* side effects needed - if any step fails */ if((OSProcHasPrivSrvInit() == IMG_FALSE) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) || PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { return PVRSRV_ERROR_SRV_CONNECT_FAILED; } #if defined (__linux__) PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE); #endif psConnection->bInitProcess = IMG_TRUE; return PVRSRV_OK; }
enum PVRSRV_ERROR PVRSRVSystemPostPowerStateKM( enum PVR_POWER_STATE eNewPowerState) { enum PVRSRV_ERROR eError; struct SYS_DATA *psSysData; enum PVR_POWER_STATE eNewDevicePowerState; eError = SysAcquireData(&psSysData); if (eError != PVRSRV_OK) goto Exit; if (eNewPowerState != psSysData->eCurrentPowerState) { eError = SysSystemPostPowerState(eNewPowerState); if (eError != PVRSRV_OK) goto Exit; } if (_IsSystemStatePowered(eNewPowerState) != _IsSystemStatePowered(psSysData->eCurrentPowerState)) { if (_IsSystemStatePowered(eNewPowerState)) eNewDevicePowerState = PVRSRV_POWER_Unspecified; else eNewDevicePowerState = PVRSRV_POWER_STATE_D3; eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); if (eError != PVRSRV_OK) goto Exit; } PVR_DPF(PVR_DBG_WARNING, "PVRSRVSystemPostPowerStateKM: " "System Power Transition from %d to %d OK", psSysData->eCurrentPowerState, eNewPowerState); psSysData->eCurrentPowerState = eNewPowerState; Exit: PVRSRVPowerUnlock(KERNEL_ID); if (_IsSystemStatePowered(eNewPowerState) && PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) PVRSRVCommandCompleteCallbacks(); return eError; }
/*! ****************************************************************************** @Function PVRSRVSetPowerStateKM @Description Set the system into a new state @Input eNewPowerState : @Input bForced : TRUE if the transition should not fail (e.g. OS request) @Return PVRSRV_ERROR ******************************************************************************/ IMG_EXPORT PVRSRV_ERROR PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState, IMG_BOOL bForced) { PVRSRV_ERROR eError; PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData(); IMG_UINT uiStage = 0; PVRSRV_DEV_POWER_STATE eNewDevicePowerState = _IsSystemStatePowered(eNewSysPowerState)? PVRSRV_DEV_POWER_STATE_DEFAULT : PVRSRV_DEV_POWER_STATE_OFF; /* require a proper power state */ if (eNewSysPowerState == PVRSRV_SYS_POWER_STATE_Unspecified) { return PVRSRV_ERROR_INVALID_PARAMS; } /* no power transition requested, so do nothing */ if (eNewSysPowerState == psPVRSRVData->eCurrentPowerState) { return PVRSRV_OK; } /* Prevent simultaneous SetPowerStateKM calls */ PVRSRVForcedPowerLock(); /* Perform pre transitions: first device and then sys layer */ eError = PVRSRVDevicePrePowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced); if (eError != PVRSRV_OK) { uiStage++; goto ErrorExit; } eError = PVRSRVSysPrePowerState(eNewSysPowerState, bForced); if (eError != PVRSRV_OK) { uiStage++; goto ErrorExit; } /* Perform system-specific post power transitions: first sys layer and then device */ eError = PVRSRVSysPostPowerState(eNewSysPowerState, bForced); if (eError != PVRSRV_OK) { uiStage++; goto ErrorExit; } eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState, bForced); if (eError != PVRSRV_OK) { uiStage++; goto ErrorExit; } psPVRSRVData->eCurrentPowerState = eNewSysPowerState; psPVRSRVData->eFailedPowerState = PVRSRV_SYS_POWER_STATE_Unspecified; PVRSRVPowerUnlock(); /* Reprocess the devices' queues in case commands were blocked during the power transition. */ if (_IsSystemStatePowered(eNewSysPowerState) && PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) { PVRSRVCheckStatus(IMG_NULL); } return PVRSRV_OK; ErrorExit: /* save the power state for the re-attempt */ psPVRSRVData->eFailedPowerState = eNewSysPowerState; PVRSRVPowerUnlock(); PVR_DPF((PVR_DBG_ERROR, "PVRSRVSetPowerStateKM: Transition from %d to %d FAILED (%s) at stage %d, forced: %d. Dumping debug info.", psPVRSRVData->eCurrentPowerState, eNewSysPowerState, PVRSRVGetErrorStringKM(eError), uiStage, bForced)); PVRSRVDebugRequest(DEBUG_REQUEST_VERBOSITY_MAX); return eError; }
IMG_EXPORT PVRSRV_ERROR PVRSRVSystemPostPowerStateKM(PVRSRV_SYS_POWER_STATE eNewSysPowerState) { PVRSRV_ERROR eError = PVRSRV_OK; SYS_DATA *psSysData; PVRSRV_DEV_POWER_STATE eNewDevicePowerState; SysAcquireData(&psSysData); if (eNewSysPowerState != psSysData->eCurrentPowerState) { eError = SysSystemPostPowerState(eNewSysPowerState); if (eError != PVRSRV_OK) { goto Exit; } } if (_IsSystemStatePowered(eNewSysPowerState) != _IsSystemStatePowered(psSysData->eCurrentPowerState)) { if (_IsSystemStatePowered(eNewSysPowerState)) { eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_DEFAULT; } else { eNewDevicePowerState = PVRSRV_DEV_POWER_STATE_OFF; } eError = PVRSRVDevicePostPowerStateKM(IMG_TRUE, 0, eNewDevicePowerState); if (eError != PVRSRV_OK) { goto Exit; } } PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVSystemPostPowerStateKM: System Power Transition from %d to %d OK", psSysData->eCurrentPowerState, eNewSysPowerState)); psSysData->eCurrentPowerState = eNewSysPowerState; Exit: PVRSRVPowerUnlock(KERNEL_ID); if (_IsSystemStatePowered(eNewSysPowerState) && PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) { PVRSRVCommandCompleteCallbacks(); } return eError; }
struct RA_ARENA *RA_Create(char *name, u32 base, size_t uSize, struct BM_MAPPING *psMapping, size_t uQuantum, IMG_BOOL(*imp_alloc) (void *, size_t uSize, size_t *pActualSize, struct BM_MAPPING **ppsMapping, u32 _flags, u32 *pBase), void (*imp_free) (void *, u32, struct BM_MAPPING *), void(*backingstore_free) (void *, u32, u32, void *), void *pImportHandle) { struct RA_ARENA *pArena; struct BT *pBT; int i; PVR_DPF(PVR_DBG_MESSAGE, "RA_Create: " "name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x", name, base, uSize, imp_alloc, imp_free); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(*pArena), (void **) &pArena, NULL) != PVRSRV_OK) goto arena_fail; pArena->name = name; pArena->pImportAlloc = (imp_alloc != NULL) ? imp_alloc : _RequestAllocFail; pArena->pImportFree = imp_free; pArena->pBackingStoreFree = backingstore_free; pArena->pImportHandle = pImportHandle; for (i = 0; i < FREE_TABLE_LIMIT; i++) pArena->aHeadFree[i] = NULL; pArena->pHeadSegment = NULL; pArena->pTailSegment = NULL; pArena->uQuantum = uQuantum; #ifdef RA_STATS pArena->sStatistics.uSpanCount = 0; pArena->sStatistics.uLiveSegmentCount = 0; pArena->sStatistics.uFreeSegmentCount = 0; pArena->sStatistics.uFreeResourceCount = 0; pArena->sStatistics.uTotalResourceCount = 0; pArena->sStatistics.uCumulativeAllocs = 0; pArena->sStatistics.uCumulativeFrees = 0; pArena->sStatistics.uImportCount = 0; pArena->sStatistics.uExportCount = 0; #endif #if defined(CONFIG_PROC_FS) && defined(CONFIG_PVR_DEBUG_EXTRA) if (strcmp(pArena->name, "") != 0) { int ret; int (*pfnCreateProcEntry) (const char *, read_proc_t, write_proc_t, void *); pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); pfnCreateProcEntry = pArena->bInitProcEntry ? CreateProcEntry : CreatePerProcessProcEntry; ret = snprintf(pArena->szProcInfoName, sizeof(pArena->szProcInfoName), "ra_info_%s", pArena->name); if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) { (void)pfnCreateProcEntry(ReplaceSpaces (pArena->szProcInfoName), RA_DumpInfo, NULL, pArena); } else { pArena->szProcInfoName[0] = 0; PVR_DPF(PVR_DBG_ERROR, "RA_Create: " "couldn't create ra_info proc entry for arena %s", pArena->name); } ret = snprintf(pArena->szProcSegsName, sizeof(pArena->szProcSegsName), "ra_segs_%s", pArena->name); if (ret > 0 && ret < sizeof(pArena->szProcInfoName)) { (void)pfnCreateProcEntry(ReplaceSpaces (pArena->szProcSegsName), RA_DumpSegs, NULL, pArena); } else { pArena->szProcSegsName[0] = 0; PVR_DPF(PVR_DBG_ERROR, "RA_Create: " "couldn't create ra_segs proc entry for arena %s", pArena->name); } } #endif pArena->pSegmentHash = HASH_Create(MINIMUM_HASH_SIZE); if (pArena->pSegmentHash == NULL) goto hash_fail; if (uSize > 0) { uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum; pBT = _InsertResource(pArena, base, uSize); if (pBT == NULL) goto insert_fail; pBT->psMapping = psMapping; } return pArena; insert_fail: HASH_Delete(pArena->pSegmentHash); hash_fail: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct RA_ARENA), pArena, NULL); arena_fail: return NULL; }
RA_ARENA * RA_Create (IMG_CHAR *name, IMG_UINTPTR_T base, IMG_SIZE_T uSize, BM_MAPPING *psMapping, IMG_SIZE_T uQuantum, IMG_BOOL (*imp_alloc)(IMG_VOID *, IMG_SIZE_T uSize, IMG_SIZE_T *pActualSize, BM_MAPPING **ppsMapping, IMG_UINT32 _flags, IMG_UINTPTR_T *pBase), IMG_VOID (*imp_free) (IMG_VOID *, IMG_UINTPTR_T, BM_MAPPING *), IMG_VOID (*backingstore_free) (IMG_VOID*, IMG_SIZE_T, IMG_SIZE_T, IMG_HANDLE), IMG_VOID *pImportHandle) { RA_ARENA *pArena; BT *pBT; IMG_INT i; PVR_DPF ((PVR_DBG_MESSAGE, "RA_Create: name='%s', base=0x%x, uSize=0x%x, alloc=0x%x, free=0x%x", name, base, uSize, (IMG_UINTPTR_T)imp_alloc, (IMG_UINTPTR_T)imp_free)); if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (*pArena), (IMG_VOID **)&pArena, IMG_NULL, "Resource Arena") != PVRSRV_OK) { goto arena_fail; } pArena->name = name; pArena->pImportAlloc = (imp_alloc!=IMG_NULL) ? imp_alloc : &_RequestAllocFail; pArena->pImportFree = imp_free; pArena->pBackingStoreFree = backingstore_free; pArena->pImportHandle = pImportHandle; for (i=0; i<FREE_TABLE_LIMIT; i++) pArena->aHeadFree[i] = IMG_NULL; pArena->pHeadSegment = IMG_NULL; pArena->pTailSegment = IMG_NULL; pArena->uQuantum = uQuantum; #ifdef RA_STATS pArena->sStatistics.uSpanCount = 0; pArena->sStatistics.uLiveSegmentCount = 0; pArena->sStatistics.uFreeSegmentCount = 0; pArena->sStatistics.uFreeResourceCount = 0; pArena->sStatistics.uTotalResourceCount = 0; pArena->sStatistics.uCumulativeAllocs = 0; pArena->sStatistics.uCumulativeFrees = 0; pArena->sStatistics.uImportCount = 0; pArena->sStatistics.uExportCount = 0; #endif #if defined(CONFIG_PROC_FS) && defined(DEBUG) if(strcmp(pArena->name,"") != 0) { IMG_INT ret; IMG_CHAR szProcInfoName[PROC_NAME_SIZE]; IMG_CHAR szProcSegsName[PROC_NAME_SIZE]; struct proc_dir_entry* (*pfnCreateProcEntrySeq)(const IMG_CHAR *, IMG_VOID*, pvr_next_proc_seq_t, pvr_show_proc_seq_t, pvr_off2element_proc_seq_t, pvr_startstop_proc_seq_t, write_proc_t); pArena->bInitProcEntry = !PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL); pfnCreateProcEntrySeq = pArena->bInitProcEntry ? CreateProcEntrySeq : CreatePerProcessProcEntrySeq; ret = snprintf(szProcInfoName, sizeof(szProcInfoName), "ra_info_%s", pArena->name); if (ret > 0 && ret < sizeof(szProcInfoName)) { pArena->pProcInfo = pfnCreateProcEntrySeq(ReplaceSpaces(szProcInfoName), pArena, NULL, RA_ProcSeqShowInfo, RA_ProcSeqOff2ElementInfo, NULL, NULL); } else { pArena->pProcInfo = 0; PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_info proc entry for arena %s", pArena->name)); } ret = snprintf(szProcSegsName, sizeof(szProcSegsName), "ra_segs_%s", pArena->name); if (ret > 0 && ret < sizeof(szProcInfoName)) { pArena->pProcSegs = pfnCreateProcEntrySeq(ReplaceSpaces(szProcSegsName), pArena, NULL, RA_ProcSeqShowRegs, RA_ProcSeqOff2ElementRegs, NULL, NULL); } else { pArena->pProcSegs = 0; PVR_DPF((PVR_DBG_ERROR, "RA_Create: couldn't create ra_segs proc entry for arena %s", pArena->name)); } } #endif pArena->pSegmentHash = HASH_Create (MINIMUM_HASH_SIZE); if (pArena->pSegmentHash==IMG_NULL) { goto hash_fail; } if (uSize>0) { uSize = (uSize + uQuantum - 1) / uQuantum * uQuantum; pBT = _InsertResource (pArena, base, uSize); if (pBT == IMG_NULL) { goto insert_fail; } pBT->psMapping = psMapping; } return pArena; insert_fail: HASH_Delete (pArena->pSegmentHash); hash_fail: OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(RA_ARENA), pArena, IMG_NULL); arena_fail: return IMG_NULL; }
IMG_INT BridgedDispatchKM(CONNECTION_DATA * psConnection, PVRSRV_BRIDGE_PACKAGE * psBridgePackageKM) { IMG_VOID * psBridgeIn; IMG_VOID * psBridgeOut; BridgeWrapperFunction pfBridgeHandler; IMG_UINT32 ui32BridgeID = psBridgePackageKM->ui32BridgeID; IMG_INT err = -EFAULT; #if defined(DEBUG_BRIDGE_KM_STOP_AT_DISPATCH) PVR_DBG_BREAK; #endif #if defined(DEBUG_BRIDGE_KM) PVR_DPF((PVR_DBG_MESSAGE, "%s: %s", __FUNCTION__, g_BridgeDispatchTable[ui32BridgeID].pszIOCName)); g_BridgeDispatchTable[ui32BridgeID].ui32CallCount++; g_BridgeGlobalStats.ui32IOCTLCount++; #endif if(!psConnection->bInitProcess) { if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) { if (ui32BridgeID == PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT)) { PVR_DPF((PVR_DBG_MESSAGE, "%s: Allowing release call through.", __FUNCTION__)); } else if (!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) { PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation failed. Driver unusable.", __FUNCTION__)); goto return_fault; } } else { if(PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) { PVR_DPF((PVR_DBG_ERROR, "%s: Initialisation is in progress", __FUNCTION__)); goto return_fault; } else { /* Only certain operations are allowed */ switch(ui32BridgeID) { case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_CONNECT): case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_DISCONNECT): case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_ACQUIREGLOBALEVENTOBJECT): case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_RELEASEGLOBALEVENTOBJECT): case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_INITSRVCONNECT): case PVRSRV_GET_BRIDGE_ID(PVRSRV_BRIDGE_SRVCORE_INITSRVDISCONNECT): break; default: PVR_DPF((PVR_DBG_ERROR, "%s: Driver initialisation not completed yet.", __FUNCTION__)); goto return_fault; } } } } #if defined(__linux__) { ENV_DATA *psEnvData = OSGetEnvData(); /* We have already set up some static buffers to store our ioctl data... */ psBridgeIn = psEnvData->pvBridgeData; psBridgeOut = (IMG_PVOID)((IMG_PBYTE)psBridgeIn + PVRSRV_MAX_BRIDGE_IN_SIZE); /* check we are not using a bigger bridge than allocated */ #if defined(DEBUG) PVR_ASSERT(psBridgePackageKM->ui32InBufferSize < PVRSRV_MAX_BRIDGE_IN_SIZE); PVR_ASSERT(psBridgePackageKM->ui32OutBufferSize < PVRSRV_MAX_BRIDGE_OUT_SIZE); #endif if(psBridgePackageKM->ui32InBufferSize > 0) { if(!OSAccessOK(PVR_VERIFY_READ, psBridgePackageKM->pvParamIn, psBridgePackageKM->ui32InBufferSize)) { PVR_DPF((PVR_DBG_ERROR, "%s: Invalid pvParamIn pointer", __FUNCTION__)); } if(CopyFromUserWrapper(psConnection, ui32BridgeID, psBridgeIn, psBridgePackageKM->pvParamIn, psBridgePackageKM->ui32InBufferSize) != PVRSRV_OK) { goto return_fault; } } } #else psBridgeIn = psBridgePackageKM->pvParamIn; psBridgeOut = psBridgePackageKM->pvParamOut; #endif if(ui32BridgeID >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) { PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is out if range!", __FUNCTION__, ui32BridgeID)); goto return_fault; } pfBridgeHandler = (BridgeWrapperFunction)g_BridgeDispatchTable[ui32BridgeID].pfFunction; if (pfBridgeHandler == NULL) { PVR_DPF((PVR_DBG_ERROR, "%s: ui32BridgeID = %d is not a registered function!", __FUNCTION__, ui32BridgeID)); goto return_fault; } err = pfBridgeHandler(ui32BridgeID, psBridgeIn, psBridgeOut, psConnection); if(err < 0) { goto return_fault; } #if defined(__linux__) /* This should always be true as a.t.m. all bridge calls have to return an error message, but this could change so we do this check to be safe. */ if(psBridgePackageKM->ui32OutBufferSize > 0) { if(CopyToUserWrapper(psConnection, ui32BridgeID, psBridgePackageKM->pvParamOut, psBridgeOut, psBridgePackageKM->ui32OutBufferSize) != PVRSRV_OK) { goto return_fault; } } #endif err = 0; return_fault: return err; }