aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/perproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/perproc.c')
-rw-r--r--drivers/gpu/pvr/perproc.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/perproc.c b/drivers/gpu/pvr/perproc.c
new file mode 100644
index 00000000000..62f4a3f1144
--- /dev/null
+++ b/drivers/gpu/pvr/perproc.c
@@ -0,0 +1,283 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#include "services_headers.h"
28#include "resman.h"
29#include "handle.h"
30#include "perproc.h"
31#include "osperproc.h"
32
33#define HASH_TAB_INIT_SIZE 32
34
35static HASH_TABLE *psHashTab = IMG_NULL;
36
37static PVRSRV_ERROR FreePerProcessData(PVRSRV_PER_PROCESS_DATA *psPerProc)
38{
39 PVRSRV_ERROR eError;
40 IMG_UINTPTR_T uiPerProc;
41
42 PVR_ASSERT(psPerProc != IMG_NULL);
43
44 if (psPerProc == IMG_NULL)
45 {
46 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: invalid parameter"));
47 return PVRSRV_ERROR_INVALID_PARAMS;
48 }
49
50 uiPerProc = HASH_Remove(psHashTab, (IMG_UINTPTR_T)psPerProc->ui32PID);
51 if (uiPerProc == 0)
52 {
53 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't find process in per-process data hash table"));
54
55 PVR_ASSERT(psPerProc->ui32PID == 0);
56 }
57 else
58 {
59 PVR_ASSERT((PVRSRV_PER_PROCESS_DATA *)uiPerProc == psPerProc);
60 PVR_ASSERT(((PVRSRV_PER_PROCESS_DATA *)uiPerProc)->ui32PID == psPerProc->ui32PID);
61 }
62
63
64 if (psPerProc->psHandleBase != IMG_NULL)
65 {
66 eError = PVRSRVFreeHandleBase(psPerProc->psHandleBase);
67 if (eError != PVRSRV_OK)
68 {
69 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free handle base for process (%d)", eError));
70 return eError;
71 }
72 }
73
74
75 if (psPerProc->hPerProcData != IMG_NULL)
76 {
77 eError = PVRSRVReleaseHandle(KERNEL_HANDLE_BASE, psPerProc->hPerProcData, PVRSRV_HANDLE_TYPE_PERPROC_DATA);
78
79 if (eError != PVRSRV_OK)
80 {
81 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't release per-process data handle (%d)", eError));
82 return eError;
83 }
84 }
85
86
87 eError = OSPerProcessPrivateDataDeInit(psPerProc->hOsPrivateData);
88 if (eError != PVRSRV_OK)
89 {
90 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: OSPerProcessPrivateDataDeInit failed (%d)", eError));
91 return eError;
92 }
93
94 eError = OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
95 sizeof(*psPerProc),
96 psPerProc,
97 psPerProc->hBlockAlloc);
98
99 if (eError != PVRSRV_OK)
100 {
101 PVR_DPF((PVR_DBG_ERROR, "FreePerProcessData: Couldn't free per-process data (%d)", eError));
102 return eError;
103 }
104
105 return PVRSRV_OK;
106}
107
108
109PVRSRV_PER_PROCESS_DATA *PVRSRVPerProcessData(IMG_UINT32 ui32PID)
110{
111 PVRSRV_PER_PROCESS_DATA *psPerProc;
112
113 PVR_ASSERT(psHashTab != IMG_NULL);
114
115
116 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
117 return psPerProc;
118}
119
120
121PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32 ui32PID)
122{
123 PVRSRV_PER_PROCESS_DATA *psPerProc;
124 IMG_HANDLE hBlockAlloc;
125 PVRSRV_ERROR eError = PVRSRV_OK;
126
127 PVR_ASSERT(psHashTab != IMG_NULL);
128
129
130 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
131
132 if (psPerProc == IMG_NULL)
133 {
134
135 eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
136 sizeof(*psPerProc),
137 (IMG_PVOID *)&psPerProc,
138 &hBlockAlloc,
139 "Per Process Data");
140 if (eError != PVRSRV_OK)
141 {
142 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
143 return eError;
144 }
145 OSMemSet(psPerProc, 0, sizeof(*psPerProc));
146 psPerProc->hBlockAlloc = hBlockAlloc;
147
148 if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
149 {
150 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
151 eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
152 goto failure;
153 }
154
155 psPerProc->ui32PID = ui32PID;
156 psPerProc->ui32RefCount = 0;
157
158
159 eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
160 if (eError != PVRSRV_OK)
161 {
162 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
163 goto failure;
164 }
165
166
167 eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
168 &psPerProc->hPerProcData,
169 psPerProc,
170 PVRSRV_HANDLE_TYPE_PERPROC_DATA,
171 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
172 if (eError != PVRSRV_OK)
173 {
174 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
175 goto failure;
176 }
177
178
179 eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
180 if (eError != PVRSRV_OK)
181 {
182 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
183 goto failure;
184 }
185
186
187 eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
188 if (eError != PVRSRV_OK)
189 {
190 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
191 goto failure;
192 }
193
194
195 eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
196 if (eError != PVRSRV_OK)
197 {
198 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
199 goto failure;
200 }
201 }
202
203 psPerProc->ui32RefCount++;
204 PVR_DPF((PVR_DBG_MESSAGE,
205 "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
206 ui32PID, psPerProc->ui32RefCount));
207
208 return eError;
209
210failure:
211 (IMG_VOID)FreePerProcessData(psPerProc);
212 return eError;
213}
214
215
216IMG_VOID PVRSRVPerProcessDataDisconnect(IMG_UINT32 ui32PID)
217{
218 PVRSRV_ERROR eError;
219 PVRSRV_PER_PROCESS_DATA *psPerProc;
220
221 PVR_ASSERT(psHashTab != IMG_NULL);
222
223 psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);
224 if (psPerProc == IMG_NULL)
225 {
226 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDealloc: Couldn't locate per-process data for PID %u", ui32PID));
227 }
228 else
229 {
230 psPerProc->ui32RefCount--;
231 if (psPerProc->ui32RefCount == 0)
232 {
233 PVR_DPF((PVR_DBG_MESSAGE, "PVRSRVPerProcessDataDisconnect: "
234 "Last close from process 0x%x received", ui32PID));
235
236
237 PVRSRVResManDisconnect(psPerProc->hResManContext, IMG_FALSE);
238
239
240 eError = FreePerProcessData(psPerProc);
241 if (eError != PVRSRV_OK)
242 {
243 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Error freeing per-process data"));
244 }
245 }
246 }
247
248 eError = PVRSRVPurgeHandles(KERNEL_HANDLE_BASE);
249 if (eError != PVRSRV_OK)
250 {
251 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataDisconnect: Purge of global handle pool failed (%d)", eError));
252 }
253}
254
255
256PVRSRV_ERROR PVRSRVPerProcessDataInit(IMG_VOID)
257{
258 PVR_ASSERT(psHashTab == IMG_NULL);
259
260
261 psHashTab = HASH_Create(HASH_TAB_INIT_SIZE);
262 if (psHashTab == IMG_NULL)
263 {
264 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataInit: Couldn't create per-process data hash table"));
265 return PVRSRV_ERROR_UNABLE_TO_CREATE_HASH_TABLE;
266 }
267
268 return PVRSRV_OK;
269}
270
271PVRSRV_ERROR PVRSRVPerProcessDataDeInit(IMG_VOID)
272{
273
274 if (psHashTab != IMG_NULL)
275 {
276
277 HASH_Delete(psHashTab);
278 psHashTab = IMG_NULL;
279 }
280
281 return PVRSRV_OK;
282}
283