RK3368 GPU version Rogue M 1.28
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue_m / services / server / env / linux / pvr_bridge_k.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          PVR Bridge Module (kernel side)
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Receives calls from the user portion of services and
6                 despatches them to functions in the kernel portion.
7 @License        Dual MIT/GPLv2
8
9 The contents of this file are subject to the MIT license as set out below.
10
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:
17
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
20
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.
24
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.
32
33 This License is also included in this distribution in the file called
34 "MIT-COPYING".
35
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 */ /**************************************************************************/
44 #include "img_defs.h"
45 #include "pvr_bridge.h"
46 #include "connection_server.h"
47 #include "syscommon.h"
48 #include "pvr_debug.h"
49 #include "pvr_debugfs.h"
50 #include "private_data.h"
51 #include "linkage.h"
52
53 #if defined(SUPPORT_DRM)
54 #include <drm/drmP.h>
55 #include "pvr_drm.h"
56 #endif /* defined(SUPPORT_DRM) */
57
58 /* RGX: */
59 #if defined(SUPPORT_RGX)
60 #include "rgx_bridge.h"
61 #endif
62
63 #include "srvcore.h"
64 #include "common_srvcore_bridge.h"
65 #include "cache_defines.h"
66
67 #if defined(MODULE_TEST)
68 /************************************************************************/
69 // additional includes for services testing
70 /************************************************************************/
71 #include "pvr_test_bridge.h"
72 #include "kern_test.h"
73 /************************************************************************/
74 // end of additional includes
75 /************************************************************************/
76 #endif
77
78 #if defined(DEBUG_BRIDGE_KM)
79 static PVR_DEBUGFS_ENTRY_DATA *gpsPVRDebugFSBridgeStatsEntry = NULL;
80 static struct seq_operations gsBridgeStatsReadOps;
81 #endif
82
83 /* These will go when full bridge gen comes in */
84 PVRSRV_ERROR InitPDUMPCTRLBridge(void);
85 PVRSRV_ERROR DeinitPDUMPCTRLBridge(void);
86 #if defined(SUPPORT_DISPLAY_CLASS)
87 PVRSRV_ERROR InitDCBridge(void);
88 PVRSRV_ERROR DeinitDCBridge(void);
89 #endif
90 PVRSRV_ERROR InitMMBridge(void);
91 PVRSRV_ERROR DeinitMMBridge(void);
92 PVRSRV_ERROR InitCMMBridge(void);
93 PVRSRV_ERROR DeinitCMMBridge(void);
94 PVRSRV_ERROR InitPDUMPMMBridge(void);
95 PVRSRV_ERROR DeinitPDUMPMMBridge(void);
96 PVRSRV_ERROR InitPDUMPBridge(void);
97 PVRSRV_ERROR DeinitPDUMPBridge(void);
98 PVRSRV_ERROR InitSRVCOREBridge(void);
99 PVRSRV_ERROR DeinitSRVCOREBridge(void);
100 PVRSRV_ERROR InitSYNCBridge(void);
101 PVRSRV_ERROR DeinitSYNCBridge(void);
102 #if defined(SUPPORT_INSECURE_EXPORT)
103 PVRSRV_ERROR InitSYNCEXPORTBridge(void);
104 PVRSRV_ERROR DeinitSYNCEXPORTBridge(void);
105 #endif
106 #if defined(SUPPORT_SECURE_EXPORT)
107 PVRSRV_ERROR InitSYNCSEXPORTBridge(void);
108 PVRSRV_ERROR DeinitSYNCSEXPORTBridge(void);
109 #endif
110 #if defined (SUPPORT_RGX)
111 PVRSRV_ERROR InitRGXINITBridge(void);
112 PVRSRV_ERROR DeinitRGXINITBridge(void);
113 PVRSRV_ERROR InitRGXTA3DBridge(void);
114 PVRSRV_ERROR DeinitRGXTA3DBridge(void);
115 PVRSRV_ERROR InitRGXTQBridge(void);
116 PVRSRV_ERROR DeinitRGXTQBridge(void);
117 PVRSRV_ERROR InitRGXCMPBridge(void);
118 PVRSRV_ERROR DeinitRGXCMPBridge(void);
119 PVRSRV_ERROR InitBREAKPOINTBridge(void);
120 PVRSRV_ERROR DeinitBREAKPOINTBridge(void);
121 PVRSRV_ERROR InitDEBUGMISCBridge(void);
122 PVRSRV_ERROR DeinitDEBUGMISCBridge(void);
123 PVRSRV_ERROR InitRGXPDUMPBridge(void);
124 PVRSRV_ERROR DeinitRGXPDUMPBridge(void);
125 PVRSRV_ERROR InitRGXHWPERFBridge(void);
126 PVRSRV_ERROR DeinitRGXHWPERFBridge(void);
127 #if defined(RGX_FEATURE_RAY_TRACING)
128 PVRSRV_ERROR InitRGXRAYBridge(void);
129 PVRSRV_ERROR DeinitRGXRAYBridge(void);
130 #endif /* RGX_FEATURE_RAY_TRACING */
131 PVRSRV_ERROR InitREGCONFIGBridge(void);
132 PVRSRV_ERROR DeinitREGCONFIGBridge(void);
133 PVRSRV_ERROR InitTIMERQUERYBridge(void);
134 PVRSRV_ERROR DeinitTIMERQUERYBridge(void);
135 #endif /* SUPPORT_RGX */
136 #if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
137 PVRSRV_ERROR InitCACHEGENERICBridge(void);
138 PVRSRV_ERROR DeinitCACHEGENERICBridge(void);
139 #endif
140 #if defined(SUPPORT_SECURE_EXPORT)
141 PVRSRV_ERROR InitSMMBridge(void);
142 PVRSRV_ERROR DeinitSMMBridge(void);
143 #endif
144 PVRSRV_ERROR InitPVRTLBridge(void);
145 PVRSRV_ERROR DeinitPVRTLBridge(void);
146 #if defined(PVR_RI_DEBUG)
147 PVRSRV_ERROR InitRIBridge(void);
148 PVRSRV_ERROR DeinitRIBridge(void);
149 #endif
150 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
151 PVRSRV_ERROR InitDEVICEMEMHISTORYBridge(IMG_VOID);
152 PVRSRV_ERROR DeinitDEVICEMEMHISTORYBridge(IMG_VOID);
153 #endif
154 #if defined(SUPPORT_ION)
155 PVRSRV_ERROR InitDMABUFBridge(void);
156 PVRSRV_ERROR DeinitDMABUFBridge(void);
157 #endif
158 #if defined(SUPPORT_VALIDATION)
159 PVRSRV_ERROR InitVALIDATIONBridge(void);
160 #endif
161 #if defined(PVR_TESTING_UTILS)
162 PVRSRV_ERROR InitTUTILSBridge(void);
163 PVRSRV_ERROR DeinitTUTILSBridge(void);
164 #endif
165
166 PVRSRV_ERROR
167 LinuxBridgeInit(void)
168 {
169         PVRSRV_ERROR eError;
170 #if defined(DEBUG_BRIDGE_KM)
171         IMG_INT iResult;
172
173         iResult = PVRDebugFSCreateEntry("bridge_stats",
174                                         NULL,
175                                         &gsBridgeStatsReadOps,
176                                         NULL,
177                                         &g_BridgeDispatchTable[0],
178                                         &gpsPVRDebugFSBridgeStatsEntry);
179         if (iResult != 0)
180         {
181                 return PVRSRV_ERROR_OUT_OF_MEMORY;
182         }
183 #endif
184
185         eError = InitSRVCOREBridge();
186         if (eError != PVRSRV_OK)
187         {
188                 return eError;
189         }
190
191         eError = InitSYNCBridge();
192         if (eError != PVRSRV_OK)
193         {
194                 return eError;
195         }
196
197 #if defined(SUPPORT_INSECURE_EXPORT)
198         eError = InitSYNCEXPORTBridge();
199         if (eError != PVRSRV_OK)
200         {
201                 return eError;
202         }
203 #endif
204 #if defined(SUPPORT_SECURE_EXPORT)
205         eError = InitSYNCSEXPORTBridge();
206         if (eError != PVRSRV_OK)
207         {
208                 return eError;
209         }
210 #endif
211
212         eError = InitPDUMPCTRLBridge();
213         if (eError != PVRSRV_OK)
214         {
215                 return eError;
216         }
217         eError = InitMMBridge();
218         if (eError != PVRSRV_OK)
219         {
220                 return eError;
221         }
222         eError = InitCMMBridge();
223         if (eError != PVRSRV_OK)
224         {
225                 return eError;
226         }
227         eError = InitPDUMPMMBridge();
228         if (eError != PVRSRV_OK)
229         {
230                 return eError;
231         }
232         eError = InitPDUMPBridge();
233         if (eError != PVRSRV_OK)
234         {
235                 return eError;
236         }
237
238 #if defined(SUPPORT_ION)
239         eError = InitDMABUFBridge();
240         if (eError != PVRSRV_OK)
241         {
242                 return eError;
243         }
244 #endif
245
246 #if defined(SUPPORT_DISPLAY_CLASS)
247         eError = InitDCBridge();
248         if (eError != PVRSRV_OK)
249         {
250                 return eError;
251         }
252 #endif
253
254 #if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
255         eError = InitCACHEGENERICBridge();
256         if (eError != PVRSRV_OK)
257         {
258                 return eError;
259         }
260 #endif
261
262 #if defined(SUPPORT_SECURE_EXPORT)
263         eError = InitSMMBridge();
264         if (eError != PVRSRV_OK)
265         {
266                 return eError;
267         }
268 #endif
269
270         eError = InitPVRTLBridge();
271         if (eError != PVRSRV_OK)
272         {
273                 return eError;
274         }
275
276         #if defined(PVR_RI_DEBUG)
277         eError = InitRIBridge();
278         if (eError != PVRSRV_OK)
279         {
280                 return eError;
281         }
282         #endif
283
284 #if defined(SUPPORT_VALIDATION)
285         eError = InitVALIDATIONBridge();
286         if (eError != PVRSRV_OK)
287         {
288                 return eError;
289         }
290 #endif
291
292 #if defined(PVR_TESTING_UTILS)
293         eError = InitTUTILSBridge();
294         if (eError != PVRSRV_OK)
295         {
296                 return eError;
297         }
298 #endif
299
300 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
301         eError = InitDEVICEMEMHISTORYBridge();
302         if (eError != PVRSRV_OK)
303         {
304                 return eError;
305         }
306 #endif
307
308         #if defined (SUPPORT_RGX)
309         eError = InitRGXTQBridge();
310         if (eError != PVRSRV_OK)
311         {
312                 return eError;
313         }
314
315         eError = InitRGXCMPBridge();
316         if (eError != PVRSRV_OK)
317         {
318                 return eError;
319         }
320
321         eError = InitRGXINITBridge();
322         if (eError != PVRSRV_OK)
323         {
324                 return eError;
325         }
326
327         eError = InitRGXTA3DBridge();
328         if (eError != PVRSRV_OK)
329         {
330                 return eError;
331         }
332
333         eError = InitBREAKPOINTBridge();
334         if (eError != PVRSRV_OK)
335         {
336                 return eError;
337         }
338
339         eError = InitDEBUGMISCBridge();
340         if (eError != PVRSRV_OK)
341         {
342                 return eError;
343         }
344         
345         eError = InitRGXPDUMPBridge();
346         if (eError != PVRSRV_OK)
347         {
348                 return eError;
349         }
350
351         eError = InitRGXHWPERFBridge();
352         if (eError != PVRSRV_OK)
353         {
354                 return eError;
355         }
356
357 #if defined(RGX_FEATURE_RAY_TRACING)
358         eError = InitRGXRAYBridge();
359         if (eError != PVRSRV_OK)
360         {
361                 return eError;
362         }
363 #endif /* RGX_FEATURE_RAY_TRACING */
364
365         eError = InitREGCONFIGBridge();
366         if (eError != PVRSRV_OK)
367         {
368                 return eError;
369         }
370
371         eError = InitTIMERQUERYBridge();
372         if (eError != PVRSRV_OK)
373         {
374                 return eError;
375         }
376
377 #endif /* SUPPORT_RGX */
378
379         return eError;
380 }
381
382 PVRSRV_ERROR
383 LinuxBridgeDeInit(void)
384 {
385         PVRSRV_ERROR eError;
386 #if defined(DEBUG_BRIDGE_KM)
387         if (gpsPVRDebugFSBridgeStatsEntry != NULL)
388         {
389                 PVRDebugFSRemoveEntry(gpsPVRDebugFSBridgeStatsEntry);
390                 gpsPVRDebugFSBridgeStatsEntry = NULL;
391         }
392 #endif
393
394         eError = DeinitSRVCOREBridge();
395         if (eError != PVRSRV_OK)
396         {
397                 return eError;
398         }
399
400         eError = DeinitSYNCBridge();
401         if (eError != PVRSRV_OK)
402         {
403                 return eError;
404         }
405
406 #if defined(SUPPORT_INSECURE_EXPORT)
407         eError = DeinitSYNCEXPORTBridge();
408         if (eError != PVRSRV_OK)
409         {
410                 return eError;
411         }
412 #endif
413 #if defined(SUPPORT_SECURE_EXPORT)
414         eError = DeinitSYNCSEXPORTBridge();
415         if (eError != PVRSRV_OK)
416         {
417                 return eError;
418         }
419 #endif
420
421         eError = DeinitPDUMPCTRLBridge();
422         if (eError != PVRSRV_OK)
423         {
424                 return eError;
425         }
426         eError = DeinitMMBridge();
427         if (eError != PVRSRV_OK)
428         {
429                 return eError;
430         }
431         eError = DeinitCMMBridge();
432         if (eError != PVRSRV_OK)
433         {
434                 return eError;
435         }
436         eError = DeinitPDUMPMMBridge();
437         if (eError != PVRSRV_OK)
438         {
439                 return eError;
440         }
441         eError = DeinitPDUMPBridge();
442         if (eError != PVRSRV_OK)
443         {
444                 return eError;
445         }
446
447 #if defined(SUPPORT_ION)
448         eError = DeinitDMABUFBridge();
449         if (eError != PVRSRV_OK)
450         {
451                 return eError;
452         }
453 #endif
454
455 #if defined(PVR_TESTING_UTILS)
456         eError = DeinitTUTILSBridge();
457         if (eError != PVRSRV_OK)
458         {
459                 return eError;
460         }
461 #endif
462
463 #if defined(SUPPORT_DISPLAY_CLASS)
464         eError = DeinitDCBridge();
465         if (eError != PVRSRV_OK)
466         {
467                 return eError;
468         }
469 #endif
470
471 #if (CACHEFLUSH_TYPE == CACHEFLUSH_GENERIC)
472         eError = DeinitCACHEGENERICBridge();
473         if (eError != PVRSRV_OK)
474         {
475                 return eError;
476         }
477 #endif
478
479 #if defined(SUPPORT_SECURE_EXPORT)
480         eError = DeinitSMMBridge();
481         if (eError != PVRSRV_OK)
482         {
483                 return eError;
484         }
485 #endif
486
487         eError = DeinitPVRTLBridge();
488         if (eError != PVRSRV_OK)
489         {
490                 return eError;
491         }
492
493         #if defined(PVR_RI_DEBUG)
494         eError = DeinitRIBridge();
495         if (eError != PVRSRV_OK)
496         {
497                 return eError;
498         }
499         #endif
500
501 #if defined(SUPPORT_PAGE_FAULT_DEBUG)
502         eError = DeinitDEVICEMEMHISTORYBridge();
503         if (eError != PVRSRV_OK)
504         {
505                 return eError;
506         }
507 #endif
508
509         #if defined (SUPPORT_RGX)
510         eError = DeinitRGXTQBridge();
511         if (eError != PVRSRV_OK)
512         {
513                 return eError;
514         }
515
516         eError = DeinitRGXCMPBridge();
517         if (eError != PVRSRV_OK)
518         {
519                 return eError;
520         }
521
522         eError = DeinitRGXINITBridge();
523         if (eError != PVRSRV_OK)
524         {
525                 return eError;
526         }
527
528         eError = DeinitRGXTA3DBridge();
529         if (eError != PVRSRV_OK)
530         {
531                 return eError;
532         }
533
534         eError = DeinitBREAKPOINTBridge();
535         if (eError != PVRSRV_OK)
536         {
537                 return eError;
538         }
539
540         eError = DeinitDEBUGMISCBridge();
541         if (eError != PVRSRV_OK)
542         {
543                 return eError;
544         }
545         
546         eError = DeinitRGXPDUMPBridge();
547         if (eError != PVRSRV_OK)
548         {
549                 return eError;
550         }
551
552         eError = DeinitRGXHWPERFBridge();
553         if (eError != PVRSRV_OK)
554         {
555                 return eError;
556         }
557
558 #if defined(RGX_FEATURE_RAY_TRACING)
559         eError = DeinitRGXRAYBridge();
560         if (eError != PVRSRV_OK)
561         {
562                 return eError;
563         }
564 #endif /* RGX_FEATURE_RAY_TRACING */
565
566         eError = DeinitREGCONFIGBridge();
567         if (eError != PVRSRV_OK)
568         {
569                 return eError;
570         }
571
572         eError = DeinitTIMERQUERYBridge();
573         if (eError != PVRSRV_OK)
574         {
575                 return eError;
576         }
577
578 #endif /* SUPPORT_RGX */
579
580         return eError;
581 }
582
583 #if defined(DEBUG_BRIDGE_KM)
584 static void *BridgeStatsSeqStart(struct seq_file *psSeqFile, loff_t *puiPosition)
585 {
586         PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
587
588         OSAcquireBridgeLock();
589
590         if (psDispatchTable == NULL || (*puiPosition) > BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
591         {
592                 return NULL;
593         }
594
595         if ((*puiPosition) == 0) 
596         {
597                 return SEQ_START_TOKEN;
598         }
599
600         return &(psDispatchTable[(*puiPosition) - 1]);
601 }
602
603 static void BridgeStatsSeqStop(struct seq_file *psSeqFile, void *pvData)
604 {
605         PVR_UNREFERENCED_PARAMETER(psSeqFile);
606         PVR_UNREFERENCED_PARAMETER(pvData);
607
608         OSReleaseBridgeLock();
609 }
610
611 static void *BridgeStatsSeqNext(struct seq_file *psSeqFile,
612                                void *pvData,
613                                loff_t *puiPosition)
614 {
615         PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psDispatchTable = (PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)psSeqFile->private;
616         loff_t uiItemAskedFor = *puiPosition; /* puiPosition on entry is the index to return */
617
618         PVR_UNREFERENCED_PARAMETER(pvData);
619
620         /* Is the item asked for (starts at 0) a valid table index? */
621         if (uiItemAskedFor < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)
622         {
623                 (*puiPosition)++; /* on exit it is the next seq index to ask for */
624                 return &(psDispatchTable[uiItemAskedFor]);
625         }
626
627         /* Now passed the end of the table to indicate stop */
628         return IMG_NULL;
629 }
630
631 static int BridgeStatsSeqShow(struct seq_file *psSeqFile, void *pvData)
632 {
633         if (pvData == SEQ_START_TOKEN)
634         {
635                 seq_printf(psSeqFile,
636                            "Total ioctl call count = %u\n"
637                            "Total number of bytes copied via copy_from_user = %u\n"
638                            "Total number of bytes copied via copy_to_user = %u\n"
639                            "Total number of bytes copied via copy_*_user = %u\n\n"
640                            "%-60s | %-48s | %10s | %20s | %10s\n",
641                            g_BridgeGlobalStats.ui32IOCTLCount,
642                            g_BridgeGlobalStats.ui32TotalCopyFromUserBytes,
643                            g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
644                            g_BridgeGlobalStats.ui32TotalCopyFromUserBytes + g_BridgeGlobalStats.ui32TotalCopyToUserBytes,
645                            "  #: Bridge Name",
646                            "Wrapper Function",
647                            "Call Count",
648                            "copy_from_user Bytes",
649                            "copy_to_user Bytes");
650         }
651         else if (pvData != NULL)
652         {
653                 PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *psEntry = ( PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY *)pvData;
654
655                 seq_printf(psSeqFile,
656                            "%3d: %-60s   %-48s   %-10u   %-20u   %-10u\n",
657                            (IMG_UINT32)(((IMG_SIZE_T)psEntry-(IMG_SIZE_T)g_BridgeDispatchTable)/sizeof(PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY)),
658                            psEntry->pszIOCName,
659                            psEntry->pszFunctionName,
660                            psEntry->ui32CallCount,
661                            psEntry->ui32CopyFromUserTotalBytes,
662                            psEntry->ui32CopyToUserTotalBytes);
663         }
664
665         return 0;
666 }
667
668 static struct seq_operations gsBridgeStatsReadOps =
669 {
670         .start = BridgeStatsSeqStart,
671         .stop = BridgeStatsSeqStop,
672         .next = BridgeStatsSeqNext,
673         .show = BridgeStatsSeqShow,
674 };
675 #endif /* defined(DEBUG_BRIDGE_KM) */
676
677
678 #if defined(SUPPORT_DRM)
679 int
680 PVRSRV_BridgeDispatchKM(struct drm_device unref__ *dev, void *arg, struct drm_file *pDRMFile)
681 #else
682 long
683 PVRSRV_BridgeDispatchKM(struct file *pFile, unsigned int ioctlCmd, unsigned long arg)
684 #endif
685 {
686 #if defined(SUPPORT_DRM)
687         struct file *pFile = PVR_FILE_FROM_DRM_FILE(pDRMFile);
688 #else
689         PVRSRV_BRIDGE_PACKAGE *psBridgePackageUM = (PVRSRV_BRIDGE_PACKAGE *)arg;
690         PVRSRV_BRIDGE_PACKAGE sBridgePackageKM;
691 #endif
692         PVRSRV_BRIDGE_PACKAGE *psBridgePackageKM;
693         CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile);
694
695         if(psConnection == IMG_NULL)
696         {
697                 PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
698                 return -EFAULT;
699         }
700
701         if(OSGetDriverSuspended())
702         {
703                 return -EINTR;
704         }
705
706 #if defined(SUPPORT_DRM)
707         psBridgePackageKM = (PVRSRV_BRIDGE_PACKAGE *)arg;
708         PVR_ASSERT(psBridgePackageKM != IMG_NULL);
709 #else
710
711         psBridgePackageKM = &sBridgePackageKM;
712
713         if (!OSAccessOK(PVR_VERIFY_WRITE,
714                                    psBridgePackageUM,
715                                    sizeof(PVRSRV_BRIDGE_PACKAGE)))
716         {
717                 PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
718                                  __FUNCTION__));
719
720                 return -EFAULT;
721         }
722         
723         /* FIXME - Currently the CopyFromUserWrapper which collects stats about
724          * how much data is shifted to/from userspace isn't available to us
725          * here. */
726         if (OSCopyFromUser(IMG_NULL,
727                                           psBridgePackageKM,
728                                           psBridgePackageUM,
729                                           sizeof(PVRSRV_BRIDGE_PACKAGE))
730           != PVRSRV_OK)
731         {
732                 return -EFAULT;
733         }
734
735         if (PVRSRV_GET_BRIDGE_ID(ioctlCmd) != psBridgePackageKM->ui32BridgeID ||
736             psBridgePackageKM->ui32Size != sizeof(PVRSRV_BRIDGE_PACKAGE))
737         {
738                 PVR_DPF((PVR_DBG_ERROR, "%s: Inconsistent data passed from user space",
739                                 __FUNCTION__));
740                 return PVRSRV_ERROR_INVALID_PARAMS;
741         }
742 #endif
743
744 #if defined(DEBUG_BRIDGE_CALLS)
745         {
746                 IMG_UINT32 mangledID;
747                 mangledID = psBridgePackageKM->ui32BridgeID;
748
749                 psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
750
751                 PVR_DPF((PVR_DBG_WARNING, "%s: Bridge ID (x%8x) %8u (mangled: x%8x) ", __FUNCTION__, psBridgePackageKM->ui32BridgeID, psBridgePackageKM->ui32BridgeID, mangledID));
752         }
753 #else
754                 psBridgePackageKM->ui32BridgeID = PVRSRV_GET_BRIDGE_ID(psBridgePackageKM->ui32BridgeID);
755 #endif
756
757         return BridgedDispatchKM(psConnection, psBridgePackageKM);
758 }
759
760
761 #if defined(CONFIG_COMPAT)
762 #if defined(SUPPORT_DRM)
763 int
764 #else
765 long
766 #endif
767 PVRSRV_BridgeCompatDispatchKM(struct file *pFile,
768                               unsigned int ioctlCmd,
769                               unsigned long arg)
770 {
771         struct bridge_package_from_32
772         {
773                 IMG_UINT32                              bridge_id;                      /*!< ioctl bridge group */
774                 IMG_UINT32                              function_id;        /*!< ioctl function index */
775                 IMG_UINT32                              size;                           /*!< size of structure */
776                 IMG_UINT32                              addr_param_in;          /*!< input data buffer */ 
777                 IMG_UINT32                              in_buffer_size;         /*!< size of input data buffer */
778                 IMG_UINT32                              addr_param_out;         /*!< output data buffer */
779                 IMG_UINT32                              out_buffer_size;        /*!< size of output data buffer */
780         };
781
782         PVRSRV_BRIDGE_PACKAGE params_for_64;
783         struct bridge_package_from_32 params;
784         struct bridge_package_from_32 * const params_addr = &params;
785         CONNECTION_DATA *psConnection = LinuxConnectionFromFile(pFile);
786
787         if(psConnection == IMG_NULL)
788         {
789                 PVR_DPF((PVR_DBG_ERROR, "%s: Connection is closed", __FUNCTION__));
790                 return -EFAULT;
791         }
792
793         if(OSGetDriverSuspended())
794         {
795                 return -EINTR;
796         }
797
798         /* make sure there is no padding inserted by compiler */
799         BUILD_BUG_ON(sizeof(struct bridge_package_from_32) != 7 * sizeof(IMG_UINT32));
800
801         if(!OSAccessOK(PVR_VERIFY_READ, (void *) arg,
802                                    sizeof(struct bridge_package_from_32)))
803         {
804                 PVR_DPF((PVR_DBG_ERROR, "%s: Received invalid pointer to function arguments",
805                                  __FUNCTION__));
806
807                 return -EFAULT;
808         }
809         
810         if(OSCopyFromUser(NULL, params_addr, (void*) arg,
811                                           sizeof(struct bridge_package_from_32))
812            != PVRSRV_OK)
813         {
814                 return -EFAULT;
815         }
816
817 #if defined(SUPPORT_DRM)
818         if (params_addr->size != sizeof(struct bridge_package_from_32))
819 #else
820         if (PVRSRV_GET_BRIDGE_ID(ioctlCmd) != PVRSRV_GET_BRIDGE_ID(params_addr->bridge_id) ||
821             params_addr->size != sizeof(struct bridge_package_from_32))
822 #endif
823         {
824                 PVR_DPF((PVR_DBG_ERROR, "%s: Inconsistent data passed from user space",
825                         __FUNCTION__));
826                 return PVRSRV_ERROR_INVALID_PARAMS;
827         }
828
829         params_for_64.ui32BridgeID = PVRSRV_GET_BRIDGE_ID(params_addr->bridge_id);
830         params_for_64.ui32FunctionID = params_addr->function_id;
831         params_for_64.ui32Size = sizeof(params_for_64);
832         params_for_64.pvParamIn = (void*) ((size_t) params_addr->addr_param_in);
833         params_for_64.pvParamOut = (void*) ((size_t) params_addr->addr_param_out);
834         params_for_64.ui32InBufferSize = params_addr->in_buffer_size;
835         params_for_64.ui32OutBufferSize = params_addr->out_buffer_size;
836
837         return BridgedDispatchKM(psConnection, &params_for_64);
838 }
839 #endif /* defined(CONFIG_COMPAT) */