diff options
Diffstat (limited to 'drivers/gpu/pvr/pvr_bridge_k.c')
-rw-r--r-- | drivers/gpu/pvr/pvr_bridge_k.c | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/pvr_bridge_k.c b/drivers/gpu/pvr/pvr_bridge_k.c new file mode 100644 index 00000000000..81a0201113b --- /dev/null +++ b/drivers/gpu/pvr/pvr_bridge_k.c | |||
@@ -0,0 +1,570 @@ | |||
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 "img_defs.h" | ||
28 | #include "services.h" | ||
29 | #include "pvr_bridge.h" | ||
30 | #include "perproc.h" | ||
31 | #include "mutex.h" | ||
32 | #include "syscommon.h" | ||
33 | #include "pvr_debug.h" | ||
34 | #include "proc.h" | ||
35 | #include "private_data.h" | ||
36 | #include "linkage.h" | ||
37 | #include "pvr_bridge_km.h" | ||
38 | |||
39 | #if defined(SUPPORT_DRI_DRM) | ||
40 | #include <drm/drmP.h> | ||
41 | #include "pvr_drm.h" | ||
42 | #if defined(PVR_SECURE_DRM_AUTH_EXPORT) | ||
43 | #include "env_perproc.h" | ||
44 | #endif | ||
45 | #endif | ||
46 | |||
47 | #if defined(SUPPORT_VGX) | ||
48 | #include "vgx_bridge.h" | ||
49 | #endif | ||
50 | |||
51 | #if defined(SUPPORT_SGX) | ||
52 | #include "sgx_bridge.h" | ||
53 | #endif | ||
54 | |||
55 | #include "bridged_pvr_bridge.h" | ||
56 | |||
57 | #ifdef MODULE_TEST | ||
58 | #include "pvr_test_bridge.h" | ||
59 | #include "kern_test.h" | ||
60 | #endif | ||
61 | |||
62 | |||
63 | #if defined(SUPPORT_DRI_DRM) | ||
64 | #define PRIVATE_DATA(pFile) ((pFile)->driver_priv) | ||
65 | #else | ||
66 | #define PRIVATE_DATA(pFile) ((pFile)->private_data) | ||
67 | #endif | ||
68 | |||
69 | #if defined(DEBUG_BRIDGE_KM) | ||
70 | |||
71 | static struct proc_dir_entry *g_ProcBridgeStats =0; | ||
72 | static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off); | ||
73 | static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el); | ||
74 | static void* ProcSeqOff2ElementBridgeStats(struct seq_file * sfile, loff_t off); | ||
75 | static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start); | ||
76 | |||
77 | #endif | ||
78 | |||
79 | extern PVRSRV_LINUX_MUTEX gPVRSRVLock; | ||
80 | |||
81 | #if defined(SUPPORT_MEMINFO_IDS) | ||
82 | static IMG_UINT64 ui64Stamp; | ||
83 | #endif | ||
84 | |||
85 | PVRSRV_ERROR | ||
86 | LinuxBridgeInit(IMG_VOID) | ||
87 | { | ||
88 | #if defined(DEBUG_BRIDGE_KM) | ||
89 | { | ||
90 | g_ProcBridgeStats = CreateProcReadEntrySeq( | ||
91 | "bridge_stats", | ||
92 | NULL, | ||
93 | ProcSeqNextBridgeStats, | ||
94 | ProcSeqShowBridgeStats, | ||
95 | ProcSeqOff2ElementBridgeStats, | ||
96 | ProcSeqStartstopBridgeStats | ||
97 | ); | ||
98 | if(!g_ProcBridgeStats) | ||
99 | { | ||
100 | return PVRSRV_ERROR_OUT_OF_MEMORY; | ||
101 | } | ||
102 | } | ||
103 | #endif | ||
104 | return CommonBridgeInit(); | ||
105 | } | ||
106 | |||
107 | IMG_VOID | ||
108 | LinuxBridgeDeInit(IMG_VOID) | ||
109 | { | ||
110 | #if defined(DEBUG_BRIDGE_KM) | ||
111 | RemoveProcEntrySeq(g_ProcBridgeStats); | ||
112 | #endif | ||
113 | } | ||
114 | |||
115 | #if defined(DEBUG_BRIDGE_KM) | ||
116 | |||
117 | static void ProcSeqStartstopBridgeStats(struct seq_file *sfile,IMG_BOOL start) | ||
118 | { | ||
119 | if(start) | ||
120 | { | ||
121 | LinuxLockMutex(&gPVRSRVLock); | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | LinuxUnLockMutex(&gPVRSRVLock); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | |||
130 | static void* ProcSeqOff2ElementBridgeStats(struct seq_file *sfile, loff_t off) | ||
131 | { | ||
132 | if(!off) | ||
133 | { | ||
134 | return PVR_PROC_SEQ_START_TOKEN; | ||
135 | } | ||
136 | |||
137 | if(off > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT) | ||
138 | { | ||
139 | return (void*)0; | ||
140 | } | ||
141 | |||
142 | |||
143 | return (void*)&g_BridgeDispatchTable[off-1]; | ||
144 | } | ||
145 | |||
146 | static void* ProcSeqNextBridgeStats(struct seq_file *sfile,void* el,loff_t off) | ||
147 | { | ||
148 | return ProcSeqOff2ElementBridgeStats(sfile,off); | ||
149 | } | ||
150 | |||
151 | |||
152 | static void ProcSeqShowBridgeStats(struct seq_file *sfile,void* el) | ||
153 | { | ||
154 | PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY*)el; | ||
155 | |||
156 | if(el == PVR_PROC_SEQ_START_TOKEN) | ||
157 | { | ||
158 | seq_printf(sfile, | ||
159 | "Total ioctl call count = %u\n" | ||
160 | "Total number of bytes copied via copy_from_user = %u\n" | ||
161 | "Total number of bytes copied via copy_to_user = %u\n" | ||
162 | "Total number of bytes copied via copy_*_user = %u\n\n" | ||
163 | "%-45s | %-40s | %10s | %20s | %10s\n", | ||
164 | g_BridgeGlobalStats.ui32IOCTLCount, | ||
165 | g_BridgeGlobalStats.ui32TotalCopyFromUserBytes, | ||
166 | g_BridgeGlobalStats.ui32TotalCopyToUserBytes, | ||
167 | g_BridgeGlobalStats.ui32TotalCopyFromUserBytes+g_BridgeGlobalStats.ui32TotalCopyToUserBytes, | ||
168 | "Bridge Name", | ||
169 | "Wrapper Function", | ||
170 | "Call Count", | ||
171 | "copy_from_user Bytes", | ||
172 | "copy_to_user Bytes" | ||
173 | ); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | seq_printf(sfile, | ||
178 | "%-45s %-40s %-10u %-20u %-10u\n", | ||
179 | psEntry->pszIOCName, | ||
180 | psEntry->pszFunctionName, | ||
181 | psEntry->ui32CallCount, | ||
182 | psEntry->ui32CopyFromUserTotalBytes, | ||
183 | psEntry->ui32CopyToUserTotalBytes); | ||
184 | } | ||
185 | |||
186 | #endif | ||
187 | |||
188 | |||
189 | #if defined(SUPPORT_DRI_DRM) | ||
190 | IMG_INT | ||
191 | PVRSRV_BridgeDispatchKM(struct drm_device *dev, IMG_VOID *arg, struct drm_file *pFile) | ||
192 | #else | ||
193 | IMG_INT32 | ||
194 | PVRSRV_BridgeDispatchKM(struct file *pFile, IMG_UINT unref__ ioctlCmd, IMG_UINT32 arg) | ||
195 | #endif | ||
196 | { | ||
197 | IMG_UINT32 cmd; | ||
198 | #if !defined(SUPPORT_DRI_DRM) | ||
199 | PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg; | ||
200 | PVRSRV_BRIDGE_PACKAGE sBridgePackageKM; | ||
201 | #endif | ||
202 | PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM; | ||
203 | IMG_UINT32 ui32PID = OSGetCurrentProcessIDKM(); | ||
204 | PVRSRV_PER_PROCESS_DATA *psPerProc; | ||
205 | IMG_INT err = -EFAULT; | ||
206 | |||
207 | LinuxLockMutex(&gPVRSRVLock); | ||
208 | |||
209 | #if defined(SUPPORT_DRI_DRM) | ||
210 | PVR_UNREFERENCED_PARAMETER(dev); | ||
211 | |||
212 | psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg; | ||
213 | PVR_ASSERT(psBridgePackageKM != IMG_NULL); | ||
214 | #else | ||
215 | PVR_UNREFERENCED_PARAMETER(ioctlCmd); | ||
216 | |||
217 | psBridgePackageKM = &sBridgePackageKM; | ||
218 | |||
219 | if(!OSAccessOK(PVR_VERIFY_WRITE, | ||
220 | psBridgePackageUM, | ||
221 | sizeof(PVRSRV_BRIDGE_PACKAGE))) | ||
222 | { | ||
223 | PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments", | ||
224 | __FUNCTION__)); | ||
225 | |||
226 | goto unlock_and_return; | ||
227 | } | ||
228 | |||
229 | |||
230 | if(OSCopyFromUser(IMG_NULL, | ||
231 | psBridgePackageKM, | ||
232 | psBridgePackageUM, | ||
233 | sizeof(PVRSRV_BRIDGE_PACKAGE)) | ||
234 | != PVRSRV_OK) | ||
235 | { | ||
236 | goto unlock_and_return; | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | cmd = psBridgePackageKM->ui32BridgeID; | ||
241 | |||
242 | #if defined(MODULE_TEST) | ||
243 | switch (cmd) | ||
244 | { | ||
245 | case PVRSRV_BRIDGE_SERVICES_TEST_MEM1: | ||
246 | { | ||
247 | PVRSRV_ERROR eError = MemTest1(); | ||
248 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
249 | { | ||
250 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
251 | pReturn->eError = eError; | ||
252 | } | ||
253 | } | ||
254 | err = 0; | ||
255 | goto unlock_and_return; | ||
256 | case PVRSRV_BRIDGE_SERVICES_TEST_MEM2: | ||
257 | { | ||
258 | PVRSRV_ERROR eError = MemTest2(); | ||
259 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
260 | { | ||
261 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
262 | pReturn->eError = eError; | ||
263 | } | ||
264 | } | ||
265 | err = 0; | ||
266 | goto unlock_and_return; | ||
267 | |||
268 | case PVRSRV_BRIDGE_SERVICES_TEST_RESOURCE: | ||
269 | { | ||
270 | PVRSRV_ERROR eError = ResourceTest(); | ||
271 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
272 | { | ||
273 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
274 | pReturn->eError = eError; | ||
275 | } | ||
276 | } | ||
277 | err = 0; | ||
278 | goto unlock_and_return; | ||
279 | |||
280 | case PVRSRV_BRIDGE_SERVICES_TEST_EVENTOBJECT: | ||
281 | { | ||
282 | PVRSRV_ERROR eError = EventObjectTest(); | ||
283 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
284 | { | ||
285 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
286 | pReturn->eError = eError; | ||
287 | } | ||
288 | } | ||
289 | err = 0; | ||
290 | goto unlock_and_return; | ||
291 | |||
292 | case PVRSRV_BRIDGE_SERVICES_TEST_MEMMAPPING: | ||
293 | { | ||
294 | PVRSRV_ERROR eError = MemMappingTest(); | ||
295 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
296 | { | ||
297 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
298 | pReturn->eError = eError; | ||
299 | } | ||
300 | } | ||
301 | err = 0; | ||
302 | goto unlock_and_return; | ||
303 | |||
304 | case PVRSRV_BRIDGE_SERVICES_TEST_PROCESSID: | ||
305 | { | ||
306 | PVRSRV_ERROR eError = ProcessIDTest(); | ||
307 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
308 | { | ||
309 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
310 | pReturn->eError = eError; | ||
311 | } | ||
312 | } | ||
313 | err = 0; | ||
314 | goto unlock_and_return; | ||
315 | |||
316 | case PVRSRV_BRIDGE_SERVICES_TEST_CLOCKUSWAITUS: | ||
317 | { | ||
318 | PVRSRV_ERROR eError = ClockusWaitusTest(); | ||
319 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
320 | { | ||
321 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
322 | pReturn->eError = eError; | ||
323 | } | ||
324 | } | ||
325 | err = 0; | ||
326 | goto unlock_and_return; | ||
327 | |||
328 | case PVRSRV_BRIDGE_SERVICES_TEST_TIMER: | ||
329 | { | ||
330 | PVRSRV_ERROR eError = TimerTest(); | ||
331 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
332 | { | ||
333 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
334 | pReturn->eError = eError; | ||
335 | } | ||
336 | } | ||
337 | err = 0; | ||
338 | goto unlock_and_return; | ||
339 | |||
340 | case PVRSRV_BRIDGE_SERVICES_TEST_PRIVSRV: | ||
341 | { | ||
342 | PVRSRV_ERROR eError = PrivSrvTest(); | ||
343 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
344 | { | ||
345 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
346 | pReturn->eError = eError; | ||
347 | } | ||
348 | } | ||
349 | err = 0; | ||
350 | goto unlock_and_return; | ||
351 | case PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA: | ||
352 | { | ||
353 | IMG_UINT32 ui32PID; | ||
354 | PVRSRV_PER_PROCESS_DATA *psPerProc; | ||
355 | PVRSRV_ERROR eError; | ||
356 | |||
357 | ui32PID = OSGetCurrentProcessIDKM(); | ||
358 | |||
359 | PVRSRVTrace("PVRSRV_BRIDGE_SERVICES_TEST_COPYDATA %d", ui32PID); | ||
360 | |||
361 | psPerProc = PVRSRVPerProcessData(ui32PID); | ||
362 | |||
363 | eError = CopyDataTest(psBridgePackageKM->pvParamIn, psBridgePackageKM->pvParamOut, psPerProc); | ||
364 | |||
365 | *(PVRSRV_ERROR*)psBridgePackageKM->pvParamOut = eError; | ||
366 | err = 0; | ||
367 | goto unlock_and_return; | ||
368 | } | ||
369 | |||
370 | |||
371 | case PVRSRV_BRIDGE_SERVICES_TEST_POWERMGMT: | ||
372 | { | ||
373 | PVRSRV_ERROR eError = PowerMgmtTest(); | ||
374 | if (psBridgePackageKM->ui32OutBufferSize == sizeof(PVRSRV_BRIDGE_RETURN)) | ||
375 | { | ||
376 | PVRSRV_BRIDGE_RETURN* pReturn = (PVRSRV_BRIDGE_RETURN*)psBridgePackageKM->pvParamOut ; | ||
377 | pReturn->eError = eError; | ||
378 | } | ||
379 | } | ||
380 | err = 0; | ||
381 | goto unlock_and_return; | ||
382 | |||
383 | } | ||
384 | #endif | ||
385 | |||
386 | if(cmd != PVRSRV_BRIDGE_CONNECT_SERVICES) | ||
387 | { | ||
388 | PVRSRV_ERROR eError; | ||
389 | |||
390 | eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE, | ||
391 | (IMG_PVOID *)&psPerProc, | ||
392 | psBridgePackageKM->hKernelServices, | ||
393 | PVRSRV_HANDLE_TYPE_PERPROC_DATA); | ||
394 | if(eError != PVRSRV_OK) | ||
395 | { | ||
396 | PVR_DPF((PVR_DBG_ERROR, "%s: Invalid kernel services handle (%d)", | ||
397 | __FUNCTION__, eError)); | ||
398 | goto unlock_and_return; | ||
399 | } | ||
400 | |||
401 | if(psPerProc->ui32PID != ui32PID) | ||
402 | { | ||
403 | PVR_DPF((PVR_DBG_ERROR, "%s: Process %d tried to access data " | ||
404 | "belonging to process %d", __FUNCTION__, ui32PID, | ||
405 | psPerProc->ui32PID)); | ||
406 | goto unlock_and_return; | ||
407 | } | ||
408 | } | ||
409 | else | ||
410 | { | ||
411 | |||
412 | psPerProc = PVRSRVPerProcessData(ui32PID); | ||
413 | if(psPerProc == IMG_NULL) | ||
414 | { | ||
415 | PVR_DPF((PVR_DBG_ERROR, "PVRSRV_BridgeDispatchKM: " | ||
416 | "Couldn't create per-process data area")); | ||
417 | goto unlock_and_return; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID); | ||
422 | |||
423 | #if defined(PVR_SECURE_FD_EXPORT) | ||
424 | switch(cmd) | ||
425 | { | ||
426 | case PVRSRV_BRIDGE_EXPORT_DEVICEMEM: | ||
427 | { | ||
428 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); | ||
429 | |||
430 | if(psPrivateData->hKernelMemInfo) | ||
431 | { | ||
432 | PVR_DPF((PVR_DBG_ERROR, "%s: Can only export one MemInfo " | ||
433 | "per file descriptor", __FUNCTION__)); | ||
434 | err = -EINVAL; | ||
435 | goto unlock_and_return; | ||
436 | } | ||
437 | break; | ||
438 | } | ||
439 | |||
440 | case PVRSRV_BRIDGE_MAP_DEV_MEMORY: | ||
441 | { | ||
442 | PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN = | ||
443 | (PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamIn; | ||
444 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); | ||
445 | |||
446 | if(!psPrivateData->hKernelMemInfo) | ||
447 | { | ||
448 | PVR_DPF((PVR_DBG_ERROR, "%s: File descriptor has no " | ||
449 | "associated MemInfo handle", __FUNCTION__)); | ||
450 | err = -EINVAL; | ||
451 | goto unlock_and_return; | ||
452 | } | ||
453 | |||
454 | psMapDevMemIN->hKernelMemInfo = psPrivateData->hKernelMemInfo; | ||
455 | break; | ||
456 | } | ||
457 | |||
458 | default: | ||
459 | { | ||
460 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); | ||
461 | |||
462 | if(psPrivateData->hKernelMemInfo) | ||
463 | { | ||
464 | PVR_DPF((PVR_DBG_ERROR, "%s: Import/Export handle tried " | ||
465 | "to use privileged service", __FUNCTION__)); | ||
466 | goto unlock_and_return; | ||
467 | } | ||
468 | break; | ||
469 | } | ||
470 | } | ||
471 | #endif | ||
472 | #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT) | ||
473 | switch(cmd) | ||
474 | { | ||
475 | case PVRSRV_BRIDGE_MAP_DEV_MEMORY: | ||
476 | case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY: | ||
477 | { | ||
478 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData; | ||
479 | int authenticated = pFile->authenticated; | ||
480 | PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc; | ||
481 | |||
482 | if (authenticated) | ||
483 | { | ||
484 | break; | ||
485 | } | ||
486 | |||
487 | |||
488 | psEnvPerProc = (PVRSRV_ENV_PER_PROCESS_DATA *)PVRSRVProcessPrivateData(psPerProc); | ||
489 | if (psEnvPerProc == IMG_NULL) | ||
490 | { | ||
491 | PVR_DPF((PVR_DBG_ERROR, "%s: Process private data not allocated", __FUNCTION__)); | ||
492 | err = -EFAULT; | ||
493 | goto unlock_and_return; | ||
494 | } | ||
495 | |||
496 | list_for_each_entry(psPrivateData, &psEnvPerProc->sDRMAuthListHead, sDRMAuthListItem) | ||
497 | { | ||
498 | struct drm_file *psDRMFile = psPrivateData->psDRMFile; | ||
499 | |||
500 | if (pFile->master == psDRMFile->master) | ||
501 | { | ||
502 | authenticated |= psDRMFile->authenticated; | ||
503 | if (authenticated) | ||
504 | { | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 | if (!authenticated) | ||
511 | { | ||
512 | PVR_DPF((PVR_DBG_ERROR, "%s: Not authenticated for mapping device or device class memory", __FUNCTION__)); | ||
513 | err = -EPERM; | ||
514 | goto unlock_and_return; | ||
515 | } | ||
516 | break; | ||
517 | } | ||
518 | default: | ||
519 | break; | ||
520 | } | ||
521 | #endif | ||
522 | |||
523 | err = BridgedDispatchKM(psPerProc, psBridgePackageKM); | ||
524 | if(err != PVRSRV_OK) | ||
525 | goto unlock_and_return; | ||
526 | |||
527 | switch(cmd) | ||
528 | { | ||
529 | #if defined(PVR_SECURE_FD_EXPORT) | ||
530 | case PVRSRV_BRIDGE_EXPORT_DEVICEMEM: | ||
531 | { | ||
532 | PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT = | ||
533 | (PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *)psBridgePackageKM->pvParamOut; | ||
534 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); | ||
535 | |||
536 | psPrivateData->hKernelMemInfo = psExportDeviceMemOUT->hMemInfo; | ||
537 | #if defined(SUPPORT_MEMINFO_IDS) | ||
538 | psExportDeviceMemOUT->ui64Stamp = psPrivateData->ui64Stamp = ++ui64Stamp; | ||
539 | #endif | ||
540 | break; | ||
541 | } | ||
542 | #endif | ||
543 | |||
544 | #if defined(SUPPORT_MEMINFO_IDS) | ||
545 | case PVRSRV_BRIDGE_MAP_DEV_MEMORY: | ||
546 | { | ||
547 | PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDeviceMemoryOUT = | ||
548 | (PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *)psBridgePackageKM->pvParamOut; | ||
549 | PVRSRV_FILE_PRIVATE_DATA *psPrivateData = PRIVATE_DATA(pFile); | ||
550 | psMapDeviceMemoryOUT->sDstClientMemInfo.ui64Stamp = psPrivateData->ui64Stamp; | ||
551 | break; | ||
552 | } | ||
553 | |||
554 | case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY: | ||
555 | { | ||
556 | PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psDeviceClassMemoryOUT = | ||
557 | (PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *)psBridgePackageKM->pvParamOut; | ||
558 | psDeviceClassMemoryOUT->sClientMemInfo.ui64Stamp = ++ui64Stamp; | ||
559 | break; | ||
560 | } | ||
561 | #endif | ||
562 | |||
563 | default: | ||
564 | break; | ||
565 | } | ||
566 | |||
567 | unlock_and_return: | ||
568 | LinuxUnLockMutex(&gPVRSRVLock); | ||
569 | return err; | ||
570 | } | ||