diff options
Diffstat (limited to 'drivers/gpu/pvr/perproc.c')
-rw-r--r-- | drivers/gpu/pvr/perproc.c | 283 |
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 | |||
35 | static HASH_TABLE *psHashTab = IMG_NULL; | ||
36 | |||
37 | static 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 | |||
109 | PVRSRV_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 | |||
121 | PVRSRV_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 | |||
210 | failure: | ||
211 | (IMG_VOID)FreePerProcessData(psPerProc); | ||
212 | return eError; | ||
213 | } | ||
214 | |||
215 | |||
216 | IMG_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 | |||
256 | PVRSRV_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 | |||
271 | PVRSRV_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 | |||