예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
/*!
******************************************************************************

 @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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
파일: ra.c 프로젝트: AdiPat/i9003_Kernel
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;
}
예제 #11
0
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;
}