/*************************************************************************/ /*!
@File
@Title          Server side connection management
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description    Handles connections coming from the client and the management
                connection based information
@License        Dual MIT/GPLv2

The contents of this file are subject to the MIT license as set out below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.

If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.

This License is also included in this distribution in the file called
"MIT-COPYING".

EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/

#include "handle.h"
#include "pvrsrv.h"
#include "connection_server.h"
#include "osconnection_server.h"
#include "allocmem.h"
#include "pvr_debug.h"
#include "sync_server.h"
#include "process_stats.h"
#include "pdump_km.h"
#include "lists.h"
#include "osfunc.h"
#include "tlstream.h"

/* PID associated with Connection currently being purged by Cleanup thread */
static IMG_PID gCurrentPurgeConnectionPid = 0;

static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection)
{
	PVRSRV_ERROR eError;
	PROCESS_HANDLE_BASE *psProcessHandleBase;
	IMG_UINT64 ui64MaxBridgeTime;
	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();

	if(psPVRSRVData->bUnload)
	{
		/* driver is unloading so do not allow the bridge lock to be released */
		ui64MaxBridgeTime = 0;
	}
	else
	{
		ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
	}

	if (psConnection == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR, "ConnectionDestroy: Missing connection!"));
		PVR_ASSERT(0);
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* Close the process statistics */
#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS)
	if (psConnection->hProcessStats != NULL)
	{
		PVRSRVStatsDeregisterProcess(psConnection->hProcessStats);
		psConnection->hProcessStats = NULL;
	}
#endif

	/* Close HWPerfClient stream here even though we created it in
	 * PVRSRVConnectKM(). */
	if (psConnection->hClientTLStream)
	{
		TLStreamClose(psConnection->hClientTLStream);
		psConnection->hClientTLStream = NULL;
		PVR_DPF((PVR_DBG_MESSAGE, "Destroyed private stream."));
	}

	/* Get process handle base to decrement the refcount */
	psProcessHandleBase = psConnection->psProcessHandleBase;

	if (psProcessHandleBase != NULL)
	{
		/* acquire the lock now to ensure unref and removal from the
		 * hash table is atomic.
		 * if the refcount becomes zero then the lock needs to be held
		 * until the entry is removed from the hash table.
		 */
		OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);

		/* In case the refcount becomes 0 we can remove the process handle base */
		if (OSAtomicDecrement(&psProcessHandleBase->iRefCount) == 0)
		{
			uintptr_t uiHashValue;

			uiHashValue = HASH_Remove(psPVRSRVData->psProcessHandleBase_Table, psConnection->pid);
			OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);

			if (!uiHashValue)
			{
				PVR_DPF((PVR_DBG_ERROR,
						"%s: Failed to remove handle base from hash table.",
						__func__));
				return PVRSRV_ERROR_UNABLE_TO_REMOVE_HASH_VALUE;
			}

			eError = PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, ui64MaxBridgeTime);
			if (eError != PVRSRV_OK)
			{
				if (eError != PVRSRV_ERROR_RETRY)
				{
					PVR_DPF((PVR_DBG_ERROR,
						 "ConnectionDataDestroy: Couldn't free handle base for process (%d)",
						 eError));
				}

				return eError;
			}

			OSFreeMem(psProcessHandleBase);
		}
		else
		{
			OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
		}

		psConnection->psProcessHandleBase = NULL;
	}

	/* Free handle base for this connection */
	if (psConnection->psHandleBase != NULL)
	{
		eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime);
		if (eError != PVRSRV_OK)
		{
			if (eError != PVRSRV_ERROR_RETRY)
			{
				PVR_DPF((PVR_DBG_ERROR,
					 "ConnectionDataDestroy: Couldn't free handle base for connection (%d)",
					 eError));
			}

			return eError;
		}

		psConnection->psHandleBase = NULL;
	}

	if (psConnection->psSyncConnectionData != NULL)
	{
		SyncUnregisterConnection(psConnection->psSyncConnectionData);
		psConnection->psSyncConnectionData = NULL;
	}

	if (psConnection->psPDumpConnectionData != NULL)
	{
		PDumpUnregisterConnection(psConnection->psPDumpConnectionData);
		psConnection->psPDumpConnectionData = NULL;
	}

	/* Call environment specific connection data deinit function */
	if (psConnection->hOsPrivateData != NULL)
	{
		eError = OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,
				 "PVRSRVConnectionDataDestroy: OSConnectionPrivateDataDeInit failed (%d)",
				 eError));

			return eError;
		}

		psConnection->hOsPrivateData = NULL;
	}

	OSFreeMem(psConnection);

	return PVRSRV_OK;
}

PVRSRV_ERROR PVRSRVConnectionConnect(void **ppvPrivData, void *pvOSData)
{
	CONNECTION_DATA *psConnection;
	PVRSRV_ERROR eError;
	PROCESS_HANDLE_BASE *psProcessHandleBase;
	PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();

	/* Allocate connection data area */
	psConnection = OSAllocZMem(sizeof(*psConnection));
	if (psConnection == NULL)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVConnectionConnect: Couldn't allocate connection data"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	/* Call environment specific connection data init function */
	eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData);
	if (eError != PVRSRV_OK)
	{
		 PVR_DPF((PVR_DBG_ERROR,
			  "PVRSRVConnectionConnect: OSConnectionPrivateDataInit failed (%d)",
			  eError));
		goto failure;
	}

	psConnection->pid = OSGetCurrentClientProcessIDKM();

	/* Register this connection with the sync core */
	eError = SyncRegisterConnection(&psConnection->psSyncConnectionData);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVConnectionConnect: Couldn't register the sync data"));
		goto failure;
	}

	/*
	 * Register this connection with the pdump core. Pass in the sync connection data
	 * as it will be needed later when we only get passed in the PDump connection data.
	 */
	eError = PDumpRegisterConnection(psConnection->psSyncConnectionData,
					 &psConnection->psPDumpConnectionData);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVConnectionConnect: Couldn't register the PDump data"));
		goto failure;
	}

	/* Allocate handle base for this connection */
	eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase,
	                               PVRSRV_HANDLE_BASE_TYPE_CONNECTION);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVConnectionConnect: Couldn't allocate handle base for connection (%d)",
			 eError));
		goto failure;
	}

	/* Try to get process handle base if it already exists */
	OSLockAcquire(psPVRSRVData->hProcessHandleBase_Lock);
	psProcessHandleBase = (PROCESS_HANDLE_BASE*) HASH_Retrieve(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
	                                                           psConnection->pid);

	/* In case there is none we are going to allocate one */
	if (psProcessHandleBase == NULL)
	{
		psProcessHandleBase = OSAllocZMem(sizeof(PROCESS_HANDLE_BASE));
		if (psProcessHandleBase == NULL)
		{
			PVR_DPF((PVR_DBG_ERROR,
					"%s: Failed to allocate handle base, oom.",
					__func__));
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto failureLock;
		}

		/* Allocate handle base for this process */
		eError = PVRSRVAllocHandleBase(&psProcessHandleBase->psHandleBase,
		                               PVRSRV_HANDLE_BASE_TYPE_PROCESS);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,
			         "%s: Couldn't allocate handle base for process (%d)",
			         __func__,
			         eError));
			OSFreeMem(psProcessHandleBase);
			goto failureLock;
		}

		/* Insert the handle base into the global hash table */
		if (!HASH_Insert(PVRSRVGetPVRSRVData()->psProcessHandleBase_Table,
		                 psConnection->pid,
		                 (uintptr_t) psProcessHandleBase))
		{

			eError = PVRSRV_ERROR_UNABLE_TO_INSERT_HASH_VALUE;

			PVRSRVFreeHandleBase(psProcessHandleBase->psHandleBase, 0);

			OSFreeMem(psProcessHandleBase);
			goto failureLock;
		}
	}
	OSAtomicIncrement(&psProcessHandleBase->iRefCount);

	OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);

	psConnection->psProcessHandleBase = psProcessHandleBase;


	/* Allocate process statistics */
#if defined(PVRSRV_ENABLE_PROCESS_STATS) && !defined(PVRSRV_DEBUG_LINUX_MEMORY_STATS)
	eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "PVRSRVConnectionConnect: Couldn't register process statistics (%d)",
			 eError));
		goto failure;
	}
#endif

	*ppvPrivData = psConnection;

	return eError;

failureLock:
	OSLockRelease(psPVRSRVData->hProcessHandleBase_Lock);
failure:
	ConnectionDataDestroy(psConnection);

	return eError;
}

static PVRSRV_ERROR _CleanupThreadPurgeConnectionData(void *pvConnectionData)
{
	PVRSRV_ERROR eErrorConnection, eErrorKernel;
	CONNECTION_DATA *psConnectionData = pvConnectionData;

#if defined(PVRSRV_USE_BRIDGE_LOCK)
	OSAcquireBridgeLock();
#endif

	gCurrentPurgeConnectionPid = psConnectionData->pid;

	eErrorConnection = ConnectionDataDestroy(psConnectionData);
	if (eErrorConnection != PVRSRV_OK)
	{
		if (eErrorConnection == PVRSRV_ERROR_RETRY)
		{
			PVR_DPF((PVR_DBG_MESSAGE,
				 "_CleanupThreadPurgeConnectionData: Failed to purge connection data %p "
				 "(deferring destruction)",
				 psConnectionData));
		}
	}
	else
	{
		PVR_DPF((PVR_DBG_MESSAGE,
			 "_CleanupThreadPurgeConnectionData: Connection data %p deferred destruction finished",
			 psConnectionData));
	}

	/* Check if possible resize the global handle base */
	eErrorKernel = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
	if (eErrorKernel != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
			 "_CleanupThreadPurgeConnectionData: Purge of global handle pool failed (%d)",
			 eErrorKernel));
	}

	gCurrentPurgeConnectionPid = 0;

#if defined(PVRSRV_USE_BRIDGE_LOCK)
	OSReleaseBridgeLock();
#endif

	return eErrorConnection;
}

void PVRSRVConnectionDisconnect(void *pvDataPtr)
{
	CONNECTION_DATA *psConnectionData = pvDataPtr;

	/* Notify the PDump core if the pdump control client is disconnecting */
	if (psConnectionData->ui32ClientFlags & SRV_FLAGS_PDUMPCTRL)
	{
		PDumpDisconnectionNotify();
	}
#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
	if (PVRSRVGetPVRSRVData()->eServicesState == PVRSRV_SERVICES_STATE_OK)
#endif
	{
		/* Defer the release of the connection data */
		psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
		psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
		psConnectionData->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
		psConnectionData->sCleanupThreadFn.bDependsOnHW = IMG_FALSE;
		PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
	}
}

IMG_PID PVRSRVGetPurgeConnectionPid(void)
{
	return gCurrentPurgeConnectionPid;
}
