IMG_INTERNAL
IMG_VOID _DevmemImportStructRelease(DEVMEM_IMPORT *psImport)
{
	PVR_ASSERT(psImport->ui32RefCount != 0);

	OSLockAcquire(psImport->hLock);
	DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
					__FUNCTION__,
					psImport,
					psImport->ui32RefCount,
					psImport->ui32RefCount-1);

	if (--psImport->ui32RefCount == 0)
	{
		OSLockRelease(psImport->hLock);

		BridgePMRUnrefPMR(psImport->hBridge,
						  psImport->hPMR);
		OSLockDestroy(psImport->sCPUImport.hLock);
		OSLockDestroy(psImport->sDeviceImport.hLock);
		OSLockDestroy(psImport->hLock);
		OSFreeMem(psImport);
	}
	else
	{
		OSLockRelease(psImport->hLock);
	}
}
IMG_INTERNAL
IMG_VOID _DevmemImportDiscard(DEVMEM_IMPORT *psImport)
{
	PVR_ASSERT(psImport->ui32RefCount == 0);
	OSLockDestroy(psImport->sCPUImport.hLock);
	OSLockDestroy(psImport->sDeviceImport.hLock);
	OSLockDestroy(psImport->hLock);
	OSFreeMem(psImport);
}
IMG_INTERNAL
IMG_VOID _DevmemMemDescDiscard(DEVMEM_MEMDESC *psMemDesc)
{
	PVR_ASSERT(psMemDesc->ui32RefCount == 0);

	OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
	OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
	OSLockDestroy(psMemDesc->hLock);
	OSFreeMem(psMemDesc);
}
Exemple #4
0
IMG_VOID ServerSyncDeinit(IMG_VOID)
{
	PVRSRVUnregisterDbgRequestNotify(g_hNotify);
	OSLockDestroy(g_hListLock);
#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
	OSLockAcquire(g_hSyncRecordListLock);
	dllist_foreach_node(&g_sSyncRecordList, _SyncRecordListDestroy, IMG_NULL);
	OSLockRelease(g_hSyncRecordListLock);
	PVRSRVUnregisterDbgRequestNotify(g_hSyncRecordNotify);
	OSLockDestroy(g_hSyncRecordListLock);
#endif
}
IMG_INTERNAL
PVRSRV_ERROR _DevmemMemDescAlloc(DEVMEM_MEMDESC **ppsMemDesc)
{
	DEVMEM_MEMDESC *psMemDesc;
	PVRSRV_ERROR eError;

	psMemDesc = OSAllocMem(sizeof(DEVMEM_MEMDESC));

	if (psMemDesc == IMG_NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto failAlloc;
	}
	
	/* Structure must be zero'd incase it needs to be freed before it is initialised! */
	OSMemSet(psMemDesc, 0, sizeof(DEVMEM_MEMDESC));

	eError = OSLockCreate(&psMemDesc->hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failMDLock;
	}

	eError = OSLockCreate(&psMemDesc->sDeviceMemDesc.hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failDMDLock;
	}

	eError = OSLockCreate(&psMemDesc->sCPUMemDesc.hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failCMDLock;
	}

	*ppsMemDesc = psMemDesc;

	return PVRSRV_OK;

failCMDLock:
	OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
failDMDLock:
	OSLockDestroy(psMemDesc->hLock);
failMDLock:
	OSFreeMem(psMemDesc);
failAlloc:
	PVR_ASSERT(eError != PVRSRV_OK);

	return eError;
}
Exemple #6
0
IMG_VOID
ServerSyncUnref(SERVER_SYNC_PRIMITIVE *psSync)
{
	IMG_UINT32 ui32RefCount;

	OSLockAcquire(psSync->hLock);
	ui32RefCount = --psSync->ui32RefCount;
	OSLockRelease(psSync->hLock);

	if (ui32RefCount == 0)
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, ui32RefCount);

		/* Remove the sync from the global list */
		OSLockAcquire(g_hListLock);
		dllist_remove_node(&psSync->sNode);
		OSLockRelease(g_hListLock);

		OSLockDestroy(psSync->hLock);
		SyncPrimFree(psSync->psSync);
		OSFreeMem(psSync);
	}
	else
	{
		SYNC_REFCOUNT_PRINT("%s: Server sync %p, refcount = %d",
							__FUNCTION__, psSync, ui32RefCount);
	}
}
Exemple #7
0
static
IMG_VOID _SyncPrimitiveBlockUnref(SYNC_PRIMITIVE_BLOCK *psSyncBlk)
{
	IMG_UINT32 ui32RefCount;

	OSLockAcquire(psSyncBlk->hLock);
	ui32RefCount = --psSyncBlk->ui32RefCount;
	OSLockRelease(psSyncBlk->hLock);

	if (ui32RefCount == 0)
	{
		PVRSRV_DEVICE_NODE *psDevNode = psSyncBlk->psDevNode;

		SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d (remove)",
							__FUNCTION__, psSyncBlk, ui32RefCount);

		_SyncConnectionRemoveBlock(psSyncBlk);
		OSLockDestroy(psSyncBlk->hLock);
		DevmemUnexport(psSyncBlk->psMemDesc, &psSyncBlk->sExportCookie);
		DevmemReleaseCpuVirtAddr(psSyncBlk->psMemDesc);
		psDevNode->pfnFreeUFOBlock(psDevNode, psSyncBlk->psMemDesc);
		OSFreeMem(psSyncBlk);
	}
	else
	{
		SYNC_REFCOUNT_PRINT("%s: Sync block %p, refcount = %d",
							__FUNCTION__, psSyncBlk, ui32RefCount);
	}
}
Exemple #8
0
static PVRSRV_ERROR SyncRecordListInit(IMG_VOID)
{
	PVRSRV_ERROR eError;

	eError = OSLockCreate(&g_hSyncRecordListLock, LOCK_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		goto fail_lock_create;
	}
	dllist_init(&g_sSyncRecordList);

	eError = PVRSRVRegisterDbgRequestNotify(&g_hSyncRecordNotify,
											_SyncRecordRequest,
											DEBUG_REQUEST_SERVERSYNC,
											IMG_NULL);

	if (eError != PVRSRV_OK)
	{
		goto fail_dbg_register;
	}

	return PVRSRV_OK;

fail_dbg_register:
	OSLockDestroy(g_hSyncRecordListLock);;
fail_lock_create:
	return eError;
}
PVRSRV_ERROR ServerSyncInit(IMG_VOID)
{
	PVRSRV_ERROR eError;

	eError = OSLockCreate(&g_hListLock, LOCK_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		goto fail_lock_create;
	}
	dllist_init(&g_sAllServerSyncs);

	eError = PVRSRVRegisterDbgRequestNotify(&g_hNotify,
											_ServerSyncDebugRequest,
											DEBUG_REQUEST_SERVERSYNC,
											IMG_NULL);
	if (eError != PVRSRV_OK)
	{
		goto fail_dbg_register;
	}

	return PVRSRV_OK;

fail_dbg_register:
	OSLockDestroy(g_hListLock);;
fail_lock_create:
	return eError;
}
IMG_INTERNAL
IMG_VOID _DevmemMemDescRelease(DEVMEM_MEMDESC *psMemDesc)
{
	PVR_ASSERT(psMemDesc != NULL);
	PVR_ASSERT(psMemDesc->ui32RefCount != 0);

	OSLockAcquire(psMemDesc->hLock);
	DEVMEM_REFCOUNT_PRINT("%s (%p) %d->%d",
					__FUNCTION__,
					psMemDesc,
					psMemDesc->ui32RefCount,
					psMemDesc->ui32RefCount-1);

	if (--psMemDesc->ui32RefCount == 0)
	{
		OSLockRelease(psMemDesc->hLock);

		if (!psMemDesc->psImport->bExportable)
		{
			RA_Free(psMemDesc->psImport->sDeviceImport.psHeap->psSubAllocRA,
					psMemDesc->psImport->sDeviceImport.sDevVAddr.uiAddr +
					psMemDesc->uiOffset);
		}
		else
		{
			_DevmemImportStructRelease(psMemDesc->psImport);
		}

		OSLockDestroy(psMemDesc->sCPUMemDesc.hLock);
		OSLockDestroy(psMemDesc->sDeviceMemDesc.hLock);
		OSLockDestroy(psMemDesc->hLock);
		OSFreeMem(psMemDesc);
	}
	else
	{
		OSLockRelease(psMemDesc->hLock);
	}
}
Exemple #11
0
/*
	SCPDestroy
*/
IMG_EXPORT
IMG_VOID IMG_CALLCONV SCPDestroy(SCP_CONTEXT *psContext)
{
	/*
		The caller must ensure that they completed all queued operations
		before calling this function
	*/
	
	PVR_ASSERT(psContext->ui32ReadOffset == psContext->ui32WriteOffset);

	PVRSRVServerSyncRequesterUnregisterKM(psContext->psSyncRequesterID);
	OSLockDestroy(psContext->hLock);
	psContext->hLock = IMG_NULL;
	OSFreeMem(psContext->pvCCB);
	psContext->pvCCB = IMG_NULL;
	OSFreeMem(psContext);
}
IMG_VOID
TLDeInit(IMG_VOID)
{
	PVR_DPF_ENTERED;

	if (sTLGlobalData.uiClientCnt)
	{
		PVR_DPF((PVR_DBG_ERROR, "TLDeInit transport layer but %d client streams are still connected", sTLGlobalData.uiClientCnt));
		sTLGlobalData.uiClientCnt = 0;
	}

	/* Clean up the SNODE list */
	if (sTLGlobalData.psHead)
	{
		while (sTLGlobalData.psHead)
		{
			RemoveAndFreeStreamNode(sTLGlobalData.psHead);
		}
		/* Leave psHead NULL on loop exit */
	}

	/* Clean up the TL global event object */
	if (sTLGlobalData.hTLEventObj)
	{
		OSEventObjectDestroy(sTLGlobalData.hTLEventObj);
		sTLGlobalData.hTLEventObj = NULL;
	}

	/* Destroy the TL global data lock */
	if (sTLGlobalData.hTLGDLock)
	{
		OSLockDestroy (sTLGlobalData.hTLGDLock);
		sTLGlobalData.hTLGDLock = NULL;
	}

	sTLGlobalData.psRgxDevNode = NULL;

	PVR_DPF_RETURN;
}
Exemple #13
0
PVRSRV_ERROR ServerSyncInit(IMG_VOID)
{
	PVRSRV_ERROR eError;

	eError = OSLockCreate(&g_hListLock, LOCK_TYPE_NONE);
	if (eError != PVRSRV_OK)
	{
		goto fail_lock_create;
	}
	dllist_init(&g_sAllServerSyncs);

	eError = PVRSRVRegisterDbgRequestNotify(&g_hNotify,
											_ServerSyncDebugRequest,
											DEBUG_REQUEST_SERVERSYNC,
											IMG_NULL);
	if (eError != PVRSRV_OK)
	{
		goto fail_dbg_register;
	}

#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
	eError = SyncRecordListInit();
	if (eError != PVRSRV_OK)
	{
		goto fail_record_list;
	}
#endif

	return PVRSRV_OK;

#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
fail_record_list:
	PVRSRVUnregisterDbgRequestNotify(g_hNotify);
#endif
fail_dbg_register:
	OSLockDestroy(g_hListLock);;
fail_lock_create:
	return eError;
}
/* TLInit must only be called once at driver initialisation for one device.
 * An assert is provided to check this condition on debug builds.
 */
PVRSRV_ERROR
TLInit(PVRSRV_DEVICE_NODE *psDevNode)
{
	PVRSRV_ERROR eError;

	PVR_DPF_ENTERED;

	PVR_ASSERT(psDevNode);
	PVR_ASSERT(sTLGlobalData.psRgxDevNode==0);

	/* Store the RGX device node for later use in devmem buffer allocations */
	sTLGlobalData.psRgxDevNode = (IMG_VOID*)psDevNode;

	/* Allocate a lock for TL global data, to be used while updating the TL data.
	 * This is for making TL global data muti-thread safe */
	eError = OSLockCreate (&sTLGlobalData.hTLGDLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto e0;
	}
	
	/* Allocate the event object used to signal global TL events such as
	 * new stream created */
	eError = OSEventObjectCreate("TLGlobalEventObj", &sTLGlobalData.hTLEventObj);
	if (eError != PVRSRV_OK)
	{
		goto e1;
	}
	
	PVR_DPF_RETURN_OK;

/* Don't allow the driver to start up on error */
e1:
	OSLockDestroy (sTLGlobalData.hTLGDLock);
	sTLGlobalData.hTLGDLock = NULL;
e0:
	PVR_DPF_RETURN_RC (eError);
}
Exemple #15
0
static
IMG_VOID _SyncConnectionUnref(SYNC_CONNECTION_DATA *psSyncConnectionData)
{
	IMG_UINT32 ui32RefCount;

	OSLockAcquire(psSyncConnectionData->hLock);
	ui32RefCount = --psSyncConnectionData->ui32RefCount;
	OSLockRelease(psSyncConnectionData->hLock);

	if (ui32RefCount == 0)
	{
		SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d",
							__FUNCTION__, psSyncConnectionData, ui32RefCount);

		PVR_ASSERT(dllist_is_empty(&psSyncConnectionData->sListHead));
		OSLockDestroy(psSyncConnectionData->hLock);
		OSFreeMem(psSyncConnectionData);
	}
	else
	{
		SYNC_REFCOUNT_PRINT("%s: Sync connection %p, refcount = %d",
							__FUNCTION__, psSyncConnectionData, ui32RefCount);
	}
}
/*
	Allocate and init an import structure
*/
IMG_INTERNAL
PVRSRV_ERROR _DevmemImportStructAlloc(IMG_HANDLE hBridge,
									  IMG_BOOL bExportable,
									  DEVMEM_IMPORT **ppsImport)
{
	DEVMEM_IMPORT *psImport;
	PVRSRV_ERROR eError;

    psImport = OSAllocMem(sizeof *psImport);
    if (psImport == IMG_NULL)
    {
        return PVRSRV_ERROR_OUT_OF_MEMORY;
    }

	/* Setup some known bad values for things we don't have yet */
	psImport->sDeviceImport.hReservation = LACK_OF_RESERVATION_POISON;
    psImport->sDeviceImport.hMapping = LACK_OF_MAPPING_POISON;
    psImport->sDeviceImport.psHeap = IMG_NULL;
    psImport->sDeviceImport.bMapped = IMG_FALSE;

	eError = OSLockCreate(&psImport->sDeviceImport.hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failDIOSLockCreate;
	}

	psImport->sCPUImport.hOSMMapData = IMG_NULL;
	psImport->sCPUImport.pvCPUVAddr = IMG_NULL;

	eError = OSLockCreate(&psImport->sCPUImport.hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failCIOSLockCreate;
	}

	/* Set up common elements */
    psImport->hBridge = hBridge;
    psImport->bExportable = bExportable;

	/* Setup refcounts */
    psImport->sDeviceImport.ui32RefCount = 0;
    psImport->sCPUImport.ui32RefCount = 0;
    psImport->ui32RefCount = 0;

	/* Create the lock */
	eError = OSLockCreate(&psImport->hLock, LOCK_TYPE_PASSIVE);
	if (eError != PVRSRV_OK)
	{
		goto failILockAlloc;
	}

#if !defined(__KERNEL__) && defined(SUPPORT_ION)
	psImport->sCPUImport.iDmaBufFd = -1;
#endif

    *ppsImport = psImport;
    
    return PVRSRV_OK;

failILockAlloc:
	OSLockDestroy(psImport->sCPUImport.hLock);
failCIOSLockCreate:
	OSLockDestroy(psImport->sDeviceImport.hLock);
failDIOSLockCreate:
	OSFreeMem(psImport);
	PVR_ASSERT(eError != PVRSRV_OK);

	return eError;
}
IMG_VOID ServerSyncDeinit(IMG_VOID)
{
	PVRSRVUnregisterDbgRequestNotify(g_hNotify);
	OSLockDestroy(g_hListLock);
}