1 /*************************************************************************/ /*!
3 @Title Server side connection management
4 @Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description Handles connections coming from the client and the management
6 connection based information
7 @License Dual MIT/GPLv2
9 The contents of this file are subject to the MIT license as set out below.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
33 This License is also included in this distribution in the file called
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
47 #include "connection_server.h"
48 #include "osconnection_server.h"
50 #include "pvr_debug.h"
51 #include "sync_server.h"
52 #include "process_stats.h"
56 /* PID associated with Connection currently being purged by Cleanup thread */
57 static IMG_PID gCurrentPurgeConnectionPid = 0;
59 static PVRSRV_ERROR ConnectionDataDestroy(CONNECTION_DATA *psConnection)
63 if (psConnection == IMG_NULL)
65 PVR_DPF((PVR_DBG_ERROR, "ConnectionDestroy: Missing connection!"));
67 return PVRSRV_ERROR_INVALID_PARAMS;
70 /* Close the process statistics */
71 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
72 if (psConnection->hProcessStats != IMG_NULL)
74 PVRSRVStatsDeregisterProcess(psConnection->hProcessStats);
75 psConnection->hProcessStats = IMG_NULL;
79 /* Free handle base for this connection */
80 if (psConnection->psHandleBase != IMG_NULL)
82 PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
83 IMG_UINT64 ui64MaxBridgeTime;
85 if(psPVRSRVData->bUnload)
87 /* driver is unloading so do not allow the bridge lock to be released */
88 ui64MaxBridgeTime = 0;
92 ui64MaxBridgeTime = CONNECTION_DEFERRED_CLEANUP_TIMESLICE_NS;
95 eError = PVRSRVFreeHandleBase(psConnection->psHandleBase, ui64MaxBridgeTime);
96 if (eError != PVRSRV_OK)
98 if (eError != PVRSRV_ERROR_RETRY)
100 PVR_DPF((PVR_DBG_ERROR,
101 "ConnectionDataDestroy: Couldn't free handle base for connection (%d)",
108 psConnection->psHandleBase = IMG_NULL;
111 if (psConnection->psSyncConnectionData != IMG_NULL)
113 SyncUnregisterConnection(psConnection->psSyncConnectionData);
114 psConnection->psSyncConnectionData = IMG_NULL;
117 if (psConnection->psPDumpConnectionData != IMG_NULL)
119 PDumpUnregisterConnection(psConnection->psPDumpConnectionData);
120 psConnection->psPDumpConnectionData = IMG_NULL;
123 /* Call environment specific connection data deinit function */
124 if (psConnection->hOsPrivateData != IMG_NULL)
126 eError = OSConnectionPrivateDataDeInit(psConnection->hOsPrivateData);
127 if (eError != PVRSRV_OK)
129 PVR_DPF((PVR_DBG_ERROR,
130 "PVRSRVConnectionDataDestroy: OSConnectionPrivateDataDeInit failed (%d)",
136 psConnection->hOsPrivateData = IMG_NULL;
139 OSFreeMem(psConnection);
144 PVRSRV_ERROR PVRSRVConnectionConnect(IMG_PVOID *ppvPrivData, IMG_PVOID pvOSData)
146 CONNECTION_DATA *psConnection;
149 /* Allocate connection data area */
150 psConnection = OSAllocZMem(sizeof(*psConnection));
151 if (psConnection == IMG_NULL)
153 PVR_DPF((PVR_DBG_ERROR,
154 "PVRSRVConnectionConnect: Couldn't allocate connection data"));
155 return PVRSRV_ERROR_OUT_OF_MEMORY;
158 /* Call environment specific connection data init function */
159 eError = OSConnectionPrivateDataInit(&psConnection->hOsPrivateData, pvOSData);
160 if (eError != PVRSRV_OK)
162 PVR_DPF((PVR_DBG_ERROR,
163 "PVRSRVConnectionConnect: OSConnectionPrivateDataInit failed (%d)",
168 psConnection->pid = OSGetCurrentProcessID();
170 /* Register this connection with the sync core */
171 eError = SyncRegisterConnection(&psConnection->psSyncConnectionData);
172 if (eError != PVRSRV_OK)
174 PVR_DPF((PVR_DBG_ERROR,
175 "PVRSRVConnectionConnect: Couldn't register the sync data"));
180 * Register this connection with the pdump core. Pass in the sync connection data
181 * as it will be needed later when we only get passed in the PDump connection data.
183 eError = PDumpRegisterConnection(psConnection->psSyncConnectionData,
184 &psConnection->psPDumpConnectionData);
185 if (eError != PVRSRV_OK)
187 PVR_DPF((PVR_DBG_ERROR,
188 "PVRSRVConnectionConnect: Couldn't register the PDump data"));
192 /* Allocate handle base for this connection */
193 eError = PVRSRVAllocHandleBase(&psConnection->psHandleBase);
194 if (eError != PVRSRV_OK)
196 PVR_DPF((PVR_DBG_ERROR,
197 "PVRSRVConnectionConnect: Couldn't allocate handle base for connection (%d)",
202 /* Allocate process statistics */
203 #if defined(PVRSRV_ENABLE_PROCESS_STATS)
204 eError = PVRSRVStatsRegisterProcess(&psConnection->hProcessStats);
205 if (eError != PVRSRV_OK)
207 PVR_DPF((PVR_DBG_ERROR,
208 "PVRSRVConnectionConnect: Couldn't register process statistics (%d)",
214 *ppvPrivData = psConnection;
219 ConnectionDataDestroy(psConnection);
224 static PVRSRV_ERROR _CleanupThreadPurgeConnectionData(void *pvConnectionData)
226 PVRSRV_ERROR eErrorConnection, eErrorKernel;
227 CONNECTION_DATA *psConnectionData = pvConnectionData;
229 OSAcquireBridgeLock();
231 gCurrentPurgeConnectionPid = psConnectionData->pid;
233 eErrorConnection = ConnectionDataDestroy(psConnectionData);
234 if (eErrorConnection != PVRSRV_OK)
236 if (eErrorConnection == PVRSRV_ERROR_RETRY)
238 PVR_DPF((PVR_DBG_MESSAGE,
239 "_CleanupThreadPurgeConnectionData: Failed to purge connection data %p "
240 "(deferring destruction)",
246 PVR_DPF((PVR_DBG_MESSAGE,
247 "_CleanupThreadPurgeConnectionData: Connection data %p deferred destruction finished",
251 /* Check if possible resize the global handle base */
252 eErrorKernel = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
253 if (eErrorKernel != PVRSRV_OK)
255 PVR_DPF((PVR_DBG_ERROR,
256 "_CleanupThreadPurgeConnectionData: Purge of global handle pool failed (%d)",
260 gCurrentPurgeConnectionPid = 0;
262 OSReleaseBridgeLock();
264 return eErrorConnection;
267 void PVRSRVConnectionDisconnect(void *pvDataPtr)
269 CONNECTION_DATA *psConnectionData = pvDataPtr;
271 /* Notify the PDump core if the pdump control client is disconnecting */
272 if (psConnectionData->ui32ClientFlags & SRV_FLAGS_PDUMPCTRL)
274 PDumpDisconnectionNotify();
277 /* Defer the release of the connection data */
278 psConnectionData->sCleanupThreadFn.pfnFree = _CleanupThreadPurgeConnectionData;
279 psConnectionData->sCleanupThreadFn.pvData = psConnectionData;
280 psConnectionData->sCleanupThreadFn.ui32RetryCount = CLEANUP_THREAD_RETRY_COUNT_DEFAULT;
281 PVRSRVCleanupThreadAddWork(&psConnectionData->sCleanupThreadFn);
284 PVRSRV_ERROR PVRSRVConnectionInit(void)
289 PVRSRV_ERROR PVRSRVConnectionDeInit(void)
294 IMG_PID PVRSRVGetPurgeConnectionPid(void)
296 return gCurrentPurgeConnectionPid;