gpu: pvr: improve per process procfs entry/dir handling
[sgx.git] / pvr / bridged_pvr_bridge.c
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 <stddef.h>
28
29 #include "img_defs.h"
30 #include "services.h"
31 #include "pvr_bridge_km.h"
32 #include "pvr_debug.h"
33 #include "ra.h"
34 #include "pvr_bridge.h"
35 #include "sgx_bridge.h"
36 #include "perproc.h"
37 #include "device.h"
38 #include "buffer_manager.h"
39
40 #include "pdump_km.h"
41 #include "syscommon.h"
42
43 #include "bridged_pvr_bridge.h"
44 #include "bridged_sgx_bridge.h"
45 #include "env_data.h"
46
47 #include "mmap.h"
48
49 #include <linux/kernel.h>
50 #include <linux/pagemap.h>      /* for cache flush */
51 #include <linux/mm.h>
52 #include <linux/sched.h>
53
54 struct PVRSRV_BRIDGE_DISPATCH_TABLE_ENTRY
55     g_BridgeDispatchTable[BRIDGE_DISPATCH_TABLE_ENTRY_COUNT];
56
57 #if defined(DEBUG_BRIDGE_KM)
58 struct PVRSRV_BRIDGE_GLOBAL_STATS g_BridgeGlobalStats;
59 #endif
60
61 static IMG_BOOL abSharedDeviceMemHeap[PVRSRV_MAX_CLIENT_HEAPS];
62 static IMG_BOOL *pbSharedDeviceMemHeap = abSharedDeviceMemHeap;
63
64 #if defined(DEBUG_BRIDGE_KM)
65 enum PVRSRV_ERROR
66 CopyFromUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData,
67                     u32 ui32BridgeID, void *pvDest, void __user *pvSrc,
68                     u32 ui32Size)
69 {
70         g_BridgeDispatchTable[ui32BridgeID].ui32CopyFromUserTotalBytes +=
71             ui32Size;
72         g_BridgeGlobalStats.ui32TotalCopyFromUserBytes += ui32Size;
73         return OSCopyFromUser(pProcData, pvDest, pvSrc, ui32Size);
74 }
75
76 enum PVRSRV_ERROR CopyToUserWrapper(struct PVRSRV_PER_PROCESS_DATA *pProcData,
77                   u32 ui32BridgeID, void __user *pvDest, void *pvSrc,
78                   u32 ui32Size)
79 {
80         g_BridgeDispatchTable[ui32BridgeID].ui32CopyToUserTotalBytes +=
81             ui32Size;
82         g_BridgeGlobalStats.ui32TotalCopyToUserBytes += ui32Size;
83         return OSCopyToUser(pProcData, pvDest, pvSrc, ui32Size);
84 }
85 #endif
86
87 static int PVRSRVEnumerateDevicesBW(u32 ui32BridgeID, void *psBridgeIn,
88                          struct PVRSRV_BRIDGE_OUT_ENUMDEVICE *psEnumDeviceOUT,
89                          struct PVRSRV_PER_PROCESS_DATA *psPerProc)
90 {
91         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_DEVICES);
92
93         PVR_UNREFERENCED_PARAMETER(psPerProc);
94         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
95
96         psEnumDeviceOUT->eError =
97             PVRSRVEnumerateDevicesKM(&psEnumDeviceOUT->ui32NumDevices,
98                                      psEnumDeviceOUT->asDeviceIdentifier);
99
100         return 0;
101 }
102
103 static int PVRSRVAcquireDeviceDataBW(u32 ui32BridgeID,
104         struct PVRSRV_BRIDGE_IN_ACQUIRE_DEVICEINFO *psAcquireDevInfoIN,
105         struct PVRSRV_BRIDGE_OUT_ACQUIRE_DEVICEINFO *psAcquireDevInfoOUT,
106         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
107 {
108         void *hDevCookieInt;
109
110         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
111                                  PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO);
112
113         psAcquireDevInfoOUT->eError =
114             PVRSRVAcquireDeviceDataKM(psAcquireDevInfoIN->uiDevIndex,
115                                       psAcquireDevInfoIN->eDeviceType,
116                                       &hDevCookieInt);
117         if (psAcquireDevInfoOUT->eError != PVRSRV_OK)
118                 return 0;
119
120         psAcquireDevInfoOUT->eError = PVRSRVAllocHandle(psPerProc->psHandleBase,
121                                               &psAcquireDevInfoOUT->hDevCookie,
122                                               hDevCookieInt,
123                                               PVRSRV_HANDLE_TYPE_DEV_NODE,
124                                               PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
125
126         return 0;
127 }
128
129 static int PVRSRVCreateDeviceMemContextBW(u32 ui32BridgeID,
130        struct PVRSRV_BRIDGE_IN_CREATE_DEVMEMCONTEXT *psCreateDevMemContextIN,
131        struct PVRSRV_BRIDGE_OUT_CREATE_DEVMEMCONTEXT *psCreateDevMemContextOUT,
132        struct PVRSRV_PER_PROCESS_DATA *psPerProc)
133 {
134         void *hDevCookieInt;
135         void *hDevMemContextInt;
136         u32 i;
137         IMG_BOOL bCreated;
138
139         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
140                         PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT);
141
142         NEW_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError, psPerProc,
143                         PVRSRV_MAX_CLIENT_HEAPS + 1);
144
145         psCreateDevMemContextOUT->eError = PVRSRVLookupHandle(
146                                 psPerProc->psHandleBase, &hDevCookieInt,
147                                 psCreateDevMemContextIN->hDevCookie,
148                                 PVRSRV_HANDLE_TYPE_DEV_NODE);
149
150         if (psCreateDevMemContextOUT->eError != PVRSRV_OK)
151                 return 0;
152
153         psCreateDevMemContextOUT->eError = PVRSRVCreateDeviceMemContextKM(
154                                 hDevCookieInt, psPerProc,
155                                 &hDevMemContextInt,
156                                 &psCreateDevMemContextOUT->ui32ClientHeapCount,
157                                 &psCreateDevMemContextOUT->sHeapInfo[0],
158                                 &bCreated, pbSharedDeviceMemHeap);
159
160         if (psCreateDevMemContextOUT->eError != PVRSRV_OK)
161                 return 0;
162
163         if (bCreated) {
164                 PVRSRVAllocHandleNR(psPerProc->psHandleBase,
165                                 &psCreateDevMemContextOUT->hDevMemContext,
166                                 hDevMemContextInt,
167                                 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT,
168                                 PVRSRV_HANDLE_ALLOC_FLAG_NONE);
169         } else {
170                 psCreateDevMemContextOUT->eError =
171                         PVRSRVFindHandle(psPerProc->psHandleBase,
172                                 &psCreateDevMemContextOUT->hDevMemContext,
173                                 hDevMemContextInt,
174                                 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
175                 if (psCreateDevMemContextOUT->eError != PVRSRV_OK)
176                         return 0;
177         }
178
179         for (i = 0; i < psCreateDevMemContextOUT->ui32ClientHeapCount; i++) {
180                 void *hDevMemHeapExt;
181
182                 if (abSharedDeviceMemHeap[i]) {
183                         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
184                                         &hDevMemHeapExt,
185                                         psCreateDevMemContextOUT->
186                                         sHeapInfo[i].hDevMemHeap,
187                                         PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
188                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
189                 } else {
190                         if (bCreated) {
191                                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
192                                         &hDevMemHeapExt,
193                                         psCreateDevMemContextOUT->sHeapInfo[i].
194                                                                 hDevMemHeap,
195                                         PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
196                                         PVRSRV_HANDLE_ALLOC_FLAG_NONE,
197                                         psCreateDevMemContextOUT->
198                                                                 hDevMemContext);
199                         } else {
200                                 psCreateDevMemContextOUT->eError =
201                                         PVRSRVFindHandle(
202                                             psPerProc->psHandleBase,
203                                             &hDevMemHeapExt,
204                                             psCreateDevMemContextOUT->
205                                             sHeapInfo[i].hDevMemHeap,
206                                             PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
207                                 if (psCreateDevMemContextOUT->eError !=
208                                                 PVRSRV_OK)
209                                         return 0;
210                         }
211                 }
212                 psCreateDevMemContextOUT->sHeapInfo[i].hDevMemHeap =
213                                                                 hDevMemHeapExt;
214         }
215
216         COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDevMemContextOUT->eError,
217                                                                 psPerProc);
218
219         return 0;
220 }
221
222 static int PVRSRVDestroyDeviceMemContextBW(u32 ui32BridgeID,
223         struct PVRSRV_BRIDGE_IN_DESTROY_DEVMEMCONTEXT *psDestroyDevMemContextIN,
224         struct PVRSRV_BRIDGE_RETURN *psRetOUT,
225         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
226 {
227         void *hDevCookieInt;
228         void *hDevMemContextInt;
229         IMG_BOOL bDestroyed;
230
231         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
232                         PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT);
233
234         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
235                                 &hDevCookieInt,
236                                 psDestroyDevMemContextIN->hDevCookie,
237                                 PVRSRV_HANDLE_TYPE_DEV_NODE);
238
239         if (psRetOUT->eError != PVRSRV_OK)
240                 return 0;
241
242         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
243                                 &hDevMemContextInt,
244                                 psDestroyDevMemContextIN->hDevMemContext,
245                                 PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
246
247         if (psRetOUT->eError != PVRSRV_OK)
248                 return 0;
249
250         psRetOUT->eError = PVRSRVDestroyDeviceMemContextKM(hDevCookieInt,
251                                                 hDevMemContextInt, &bDestroyed);
252
253         if (psRetOUT->eError != PVRSRV_OK)
254                 return 0;
255
256         if (bDestroyed)
257                 psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
258                                         psDestroyDevMemContextIN->
259                                         hDevMemContext,
260                                         PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
261
262         return 0;
263 }
264
265 static int PVRSRVGetDeviceMemHeapInfoBW(u32 ui32BridgeID,
266            struct PVRSRV_BRIDGE_IN_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoIN,
267            struct PVRSRV_BRIDGE_OUT_GET_DEVMEM_HEAPINFO *psGetDevMemHeapInfoOUT,
268            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
269 {
270         void *hDevCookieInt;
271         void *hDevMemContextInt;
272         u32 i;
273
274         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
275                                  PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO);
276
277         NEW_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc,
278                                   PVRSRV_MAX_CLIENT_HEAPS);
279
280         psGetDevMemHeapInfoOUT->eError =
281             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
282                                psGetDevMemHeapInfoIN->hDevCookie,
283                                PVRSRV_HANDLE_TYPE_DEV_NODE);
284
285         if (psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
286                 return 0;
287
288         psGetDevMemHeapInfoOUT->eError =
289             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
290                                psGetDevMemHeapInfoIN->hDevMemContext,
291                                PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
292
293         if (psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
294                 return 0;
295
296         psGetDevMemHeapInfoOUT->eError =
297             PVRSRVGetDeviceMemHeapInfoKM(hDevCookieInt,
298                                  hDevMemContextInt,
299                                  &psGetDevMemHeapInfoOUT->ui32ClientHeapCount,
300                                  &psGetDevMemHeapInfoOUT->sHeapInfo[0],
301                                          pbSharedDeviceMemHeap);
302
303         if (psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
304                 return 0;
305
306         for (i = 0; i < psGetDevMemHeapInfoOUT->ui32ClientHeapCount; i++) {
307                 void *hDevMemHeapExt;
308                 if (abSharedDeviceMemHeap[i]) {
309                         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
310                                &hDevMemHeapExt,
311                                psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap,
312                                PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP,
313                                PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
314                 } else {
315                         psGetDevMemHeapInfoOUT->eError =
316                             PVRSRVFindHandle(psPerProc->psHandleBase,
317                                              &hDevMemHeapExt,
318                                              psGetDevMemHeapInfoOUT->
319                                              sHeapInfo[i].hDevMemHeap,
320                                              PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
321                         if (psGetDevMemHeapInfoOUT->eError != PVRSRV_OK)
322                                 return 0;
323                 }
324                 psGetDevMemHeapInfoOUT->sHeapInfo[i].hDevMemHeap =
325                     hDevMemHeapExt;
326         }
327
328         COMMIT_HANDLE_BATCH_OR_ERROR(psGetDevMemHeapInfoOUT->eError, psPerProc);
329
330         return 0;
331 }
332
333 static int PVRSRVAllocDeviceMemBW(u32 ui32BridgeID,
334                struct PVRSRV_BRIDGE_IN_ALLOCDEVICEMEM *psAllocDeviceMemIN,
335                struct PVRSRV_BRIDGE_OUT_ALLOCDEVICEMEM *psAllocDeviceMemOUT,
336                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
337 {
338         struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
339         void *hDevCookieInt;
340         void *hDevMemHeapInt;
341
342         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ALLOC_DEVICEMEM);
343
344         NEW_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc, 2);
345
346         psAllocDeviceMemOUT->eError =
347             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
348                                psAllocDeviceMemIN->hDevCookie,
349                                PVRSRV_HANDLE_TYPE_DEV_NODE);
350
351         if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
352                 return 0;
353
354         psAllocDeviceMemOUT->eError =
355             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemHeapInt,
356                                psAllocDeviceMemIN->hDevMemHeap,
357                                PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
358
359         if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
360                 return 0;
361
362         psAllocDeviceMemOUT->eError =
363             PVRSRVAllocDeviceMemKM(hDevCookieInt, psPerProc, hDevMemHeapInt,
364                                    psAllocDeviceMemIN->ui32Attribs,
365                                    psAllocDeviceMemIN->ui32Size,
366                                    psAllocDeviceMemIN->ui32Alignment,
367                                    &psMemInfo);
368
369         if (psAllocDeviceMemOUT->eError != PVRSRV_OK)
370                 return 0;
371
372         OSMemSet(&psAllocDeviceMemOUT->sClientMemInfo, 0,
373                  sizeof(psAllocDeviceMemOUT->sClientMemInfo));
374
375         psAllocDeviceMemOUT->sClientMemInfo.pvLinAddrKM =
376                     psMemInfo->pvLinAddrKM;
377
378         psAllocDeviceMemOUT->sClientMemInfo.pvLinAddr = NULL;
379         psAllocDeviceMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
380         psAllocDeviceMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
381         psAllocDeviceMemOUT->sClientMemInfo.ui32AllocSize =
382                                                     psMemInfo->ui32AllocSize;
383         psAllocDeviceMemOUT->sClientMemInfo.hMappingInfo =
384                                             psMemInfo->sMemBlk.hOSMemHandle;
385
386         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
387                             &psAllocDeviceMemOUT->sClientMemInfo.hKernelMemInfo,
388                             psMemInfo,
389                             PVRSRV_HANDLE_TYPE_MEM_INFO,
390                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
391
392         if (psAllocDeviceMemIN->ui32Attribs & PVRSRV_MEM_NO_SYNCOBJ) {
393                 OSMemSet(&psAllocDeviceMemOUT->sClientSyncInfo, 0,
394                          sizeof(struct PVRSRV_CLIENT_SYNC_INFO));
395                 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo = NULL;
396                 psAllocDeviceMemOUT->psKernelSyncInfo = NULL;
397         } else {
398
399                 psAllocDeviceMemOUT->psKernelSyncInfo =
400                                             psMemInfo->psKernelSyncInfo;
401
402                 psAllocDeviceMemOUT->sClientSyncInfo.psSyncData =
403                     psMemInfo->psKernelSyncInfo->psSyncData;
404                 psAllocDeviceMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
405                     psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
406                 psAllocDeviceMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
407                     psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
408
409                 psAllocDeviceMemOUT->sClientSyncInfo.hMappingInfo =
410                     psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.
411                                                                 hOSMemHandle;
412
413                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
414                                        &psAllocDeviceMemOUT->sClientSyncInfo.
415                                        hKernelSyncInfo,
416                                        psMemInfo->psKernelSyncInfo,
417                                        PVRSRV_HANDLE_TYPE_SYNC_INFO,
418                                        PVRSRV_HANDLE_ALLOC_FLAG_NONE,
419                                        psAllocDeviceMemOUT->sClientMemInfo.
420                                        hKernelMemInfo);
421
422                 psAllocDeviceMemOUT->sClientMemInfo.psClientSyncInfo =
423                     &psAllocDeviceMemOUT->sClientSyncInfo;
424
425         }
426
427         COMMIT_HANDLE_BATCH_OR_ERROR(psAllocDeviceMemOUT->eError, psPerProc);
428
429         return 0;
430 }
431
432
433 static int PVRSRVFreeDeviceMemBW(u32 ui32BridgeID,
434                       struct PVRSRV_BRIDGE_IN_FREEDEVICEMEM *psFreeDeviceMemIN,
435                       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
436                       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
437 {
438         void *hDevCookieInt;
439         void *pvKernelMemInfo;
440         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
441
442         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_FREE_DEVICEMEM);
443
444         psRetOUT->eError =
445             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
446                                psFreeDeviceMemIN->hDevCookie,
447                                PVRSRV_HANDLE_TYPE_DEV_NODE);
448
449         if (psRetOUT->eError != PVRSRV_OK)
450                 return 0;
451
452         psRetOUT->eError =
453             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
454                                psFreeDeviceMemIN->psKernelMemInfo,
455                                PVRSRV_HANDLE_TYPE_MEM_INFO);
456
457         if (psRetOUT->eError != PVRSRV_OK)
458                 return 0;
459
460         psKernelMemInfo = (struct PVRSRV_KERNEL_MEM_INFO *)pvKernelMemInfo;
461         if (psKernelMemInfo->ui32RefCount != 1) {
462                 PVR_DPF(PVR_DBG_ERROR, "PVRSRVFreeDeviceMemBW: "
463                                         "mappings are open in other processes");
464                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
465                 return 0;
466         }
467
468         psRetOUT->eError = PVRSRVFreeDeviceMemKM(hDevCookieInt,
469                                                  pvKernelMemInfo);
470
471         if (psRetOUT->eError != PVRSRV_OK)
472                 return 0;
473
474         psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
475                                         psFreeDeviceMemIN->psKernelMemInfo,
476                                         PVRSRV_HANDLE_TYPE_MEM_INFO);
477
478         return 0;
479 }
480
481 static int PVRSRVExportDeviceMemBW(u32 ui32BridgeID,
482            struct PVRSRV_BRIDGE_IN_EXPORTDEVICEMEM *psExportDeviceMemIN,
483            struct PVRSRV_BRIDGE_OUT_EXPORTDEVICEMEM *psExportDeviceMemOUT,
484            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
485 {
486         void *hDevCookieInt;
487         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
488
489         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EXPORT_DEVICEMEM);
490
491         psExportDeviceMemOUT->eError =
492             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
493                                psExportDeviceMemIN->hDevCookie,
494                                PVRSRV_HANDLE_TYPE_DEV_NODE);
495
496         if (psExportDeviceMemOUT->eError != PVRSRV_OK) {
497                 PVR_DPF(PVR_DBG_ERROR,
498                          "PVRSRVExportDeviceMemBW: can't find devcookie");
499                 return 0;
500         }
501
502         psExportDeviceMemOUT->eError =
503             PVRSRVLookupHandle(psPerProc->psHandleBase,
504                                (void **)&psKernelMemInfo,
505                                psExportDeviceMemIN->psKernelMemInfo,
506                                PVRSRV_HANDLE_TYPE_MEM_INFO);
507
508         if (psExportDeviceMemOUT->eError != PVRSRV_OK) {
509                 PVR_DPF(PVR_DBG_ERROR,
510                          "PVRSRVExportDeviceMemBW: can't find kernel meminfo");
511                 return 0;
512         }
513
514         psExportDeviceMemOUT->eError =
515             PVRSRVFindHandle(KERNEL_HANDLE_BASE,
516                              &psExportDeviceMemOUT->hMemInfo,
517                              psKernelMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO);
518         if (psExportDeviceMemOUT->eError == PVRSRV_OK) {
519                 PVR_DPF(PVR_DBG_MESSAGE, "PVRSRVExportDeviceMemBW: "
520                                           "allocation is already exported");
521                 return 0;
522         }
523
524         psExportDeviceMemOUT->eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
525                                          &psExportDeviceMemOUT->hMemInfo,
526                                          psKernelMemInfo,
527                                          PVRSRV_HANDLE_TYPE_MEM_INFO,
528                                          PVRSRV_HANDLE_ALLOC_FLAG_NONE);
529         if (psExportDeviceMemOUT->eError != PVRSRV_OK) {
530                 PVR_DPF(PVR_DBG_ERROR, "PVRSRVExportDeviceMemBW: "
531                         "failed to allocate handle from global handle list");
532                 return 0;
533         }
534
535         psKernelMemInfo->ui32Flags |= PVRSRV_MEM_EXPORTED;
536
537         return 0;
538 }
539
540 static int PVRSRVMapDeviceMemoryBW(u32 ui32BridgeID,
541                         struct PVRSRV_BRIDGE_IN_MAP_DEV_MEMORY *psMapDevMemIN,
542                         struct PVRSRV_BRIDGE_OUT_MAP_DEV_MEMORY *psMapDevMemOUT,
543                         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
544 {
545         struct PVRSRV_KERNEL_MEM_INFO *psSrcKernelMemInfo = NULL;
546         struct PVRSRV_KERNEL_MEM_INFO *psDstKernelMemInfo = NULL;
547         void *hDstDevMemHeap = NULL;
548
549         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_DEV_MEMORY);
550
551         NEW_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc, 2);
552
553         psMapDevMemOUT->eError = PVRSRVLookupHandle(KERNEL_HANDLE_BASE,
554                                             (void **)&psSrcKernelMemInfo,
555                                             psMapDevMemIN->hKernelMemInfo,
556                                             PVRSRV_HANDLE_TYPE_MEM_INFO);
557         if (psMapDevMemOUT->eError != PVRSRV_OK)
558                 return 0;
559
560         psMapDevMemOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
561                                             &hDstDevMemHeap,
562                                             psMapDevMemIN->hDstDevMemHeap,
563                                             PVRSRV_HANDLE_TYPE_DEV_MEM_HEAP);
564         if (psMapDevMemOUT->eError != PVRSRV_OK)
565                 return 0;
566
567         psMapDevMemOUT->eError = PVRSRVMapDeviceMemoryKM(psPerProc,
568                                                          psSrcKernelMemInfo,
569                                                          hDstDevMemHeap,
570                                                          &psDstKernelMemInfo);
571         if (psMapDevMemOUT->eError != PVRSRV_OK)
572                 return 0;
573
574         OSMemSet(&psMapDevMemOUT->sDstClientMemInfo, 0,
575                  sizeof(psMapDevMemOUT->sDstClientMemInfo));
576         OSMemSet(&psMapDevMemOUT->sDstClientSyncInfo, 0,
577                  sizeof(psMapDevMemOUT->sDstClientSyncInfo));
578
579         psMapDevMemOUT->sDstClientMemInfo.pvLinAddrKM =
580                                     psDstKernelMemInfo->pvLinAddrKM;
581
582         psMapDevMemOUT->sDstClientMemInfo.pvLinAddr = NULL;
583         psMapDevMemOUT->sDstClientMemInfo.sDevVAddr =
584                                     psDstKernelMemInfo->sDevVAddr;
585         psMapDevMemOUT->sDstClientMemInfo.ui32Flags =
586                                     psDstKernelMemInfo->ui32Flags;
587         psMapDevMemOUT->sDstClientMemInfo.ui32AllocSize =
588                                     psDstKernelMemInfo->ui32AllocSize;
589         psMapDevMemOUT->sDstClientMemInfo.hMappingInfo =
590                                     psDstKernelMemInfo->sMemBlk.hOSMemHandle;
591
592         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
593                             &psMapDevMemOUT->sDstClientMemInfo.hKernelMemInfo,
594                             psDstKernelMemInfo,
595                             PVRSRV_HANDLE_TYPE_MEM_INFO,
596                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
597         psMapDevMemOUT->sDstClientSyncInfo.hKernelSyncInfo = NULL;
598         psMapDevMemOUT->psDstKernelSyncInfo = NULL;
599
600         if (psDstKernelMemInfo->psKernelSyncInfo) {
601                 psMapDevMemOUT->psDstKernelSyncInfo =
602                     psDstKernelMemInfo->psKernelSyncInfo;
603
604                 psMapDevMemOUT->sDstClientSyncInfo.psSyncData =
605                     psDstKernelMemInfo->psKernelSyncInfo->psSyncData;
606                 psMapDevMemOUT->sDstClientSyncInfo.sWriteOpsCompleteDevVAddr =
607                     psDstKernelMemInfo->psKernelSyncInfo->
608                                                     sWriteOpsCompleteDevVAddr;
609                 psMapDevMemOUT->sDstClientSyncInfo.sReadOpsCompleteDevVAddr =
610                     psDstKernelMemInfo->psKernelSyncInfo->
611                                                     sReadOpsCompleteDevVAddr;
612
613                 psMapDevMemOUT->sDstClientSyncInfo.hMappingInfo =
614                     psDstKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->
615                                                     sMemBlk.hOSMemHandle;
616
617                 psMapDevMemOUT->sDstClientMemInfo.psClientSyncInfo =
618                     &psMapDevMemOUT->sDstClientSyncInfo;
619
620                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
621                                        &psMapDevMemOUT->sDstClientSyncInfo.
622                                                                 hKernelSyncInfo,
623                                        psDstKernelMemInfo->psKernelSyncInfo,
624                                        PVRSRV_HANDLE_TYPE_SYNC_INFO,
625                                        PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
626                                        psMapDevMemOUT->sDstClientMemInfo.
627                                                                hKernelMemInfo);
628         }
629
630         COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevMemOUT->eError, psPerProc);
631
632         return 0;
633 }
634
635 static int PVRSRVUnmapDeviceMemoryBW(u32 ui32BridgeID,
636                   struct PVRSRV_BRIDGE_IN_UNMAP_DEV_MEMORY *psUnmapDevMemIN,
637                   struct PVRSRV_BRIDGE_RETURN *psRetOUT,
638                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
639 {
640         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo = NULL;
641
642         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNMAP_DEV_MEMORY);
643
644         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
645                                               (void **) &psKernelMemInfo,
646                                               psUnmapDevMemIN->psKernelMemInfo,
647                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
648         if (psRetOUT->eError != PVRSRV_OK)
649                 return 0;
650
651         psRetOUT->eError = PVRSRVUnmapDeviceMemoryKM(psKernelMemInfo);
652         if (psRetOUT->eError != PVRSRV_OK)
653                 return 0;
654
655         psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
656                                                psUnmapDevMemIN->psKernelMemInfo,
657                                                PVRSRV_HANDLE_TYPE_MEM_INFO);
658
659         return 0;
660 }
661
662 static int FlushCacheDRI(u32 ui32Type, u32 ui32Virt, u32 ui32Length)
663 {
664         switch (ui32Type) {
665         case DRM_PVR2D_CFLUSH_FROM_GPU:
666                 PVR_DPF(PVR_DBG_MESSAGE,
667                          "DRM_PVR2D_CFLUSH_FROM_GPU 0x%08x, length 0x%08x\n",
668                          ui32Virt, ui32Length);
669 #ifdef CONFIG_ARM
670                 dmac_map_area((const void *)ui32Virt, ui32Length, DMA_FROM_DEVICE);
671 #endif
672                 return 0;
673         case DRM_PVR2D_CFLUSH_TO_GPU:
674                 PVR_DPF(PVR_DBG_MESSAGE,
675                          "DRM_PVR2D_CFLUSH_TO_GPU 0x%08x, length 0x%08x\n",
676                          ui32Virt, ui32Length);
677 #ifdef CONFIG_ARM
678                 dmac_map_area((const void *)ui32Virt, ui32Length, DMA_TO_DEVICE);
679 #endif
680                 return 0;
681         default:
682                 PVR_DPF(PVR_DBG_ERROR, "Invalid cflush type 0x%x\n",
683                          ui32Type);
684                 return -EINVAL;
685         }
686
687         return 0;
688 }
689
690 static int PVRSRVCacheFlushDRIBW(u32 ui32BridgeID,
691               struct PVRSRV_BRIDGE_IN_CACHEFLUSHDRMFROMUSER *psCacheFlushIN,
692               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
693               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
694 {
695         struct vm_area_struct *vma;
696         unsigned long start;
697         size_t len;
698         int type;
699         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CACHE_FLUSH_DRM);
700
701         start = psCacheFlushIN->ui32Virt;
702         len = psCacheFlushIN->ui32Length;
703         type = psCacheFlushIN->ui32Type;
704
705         down_read(&current->mm->mmap_sem);
706         vma = find_vma(current->mm, start);
707         if (vma == NULL || vma->vm_start > start ||
708             vma->vm_end < start + len)
709                 pr_err("PVR: %s: invalid address %08lx %zu %c\n",
710                                 __func__, start, len,
711                                 type == DRM_PVR2D_CFLUSH_TO_GPU ? 'c' :
712                                 type == DRM_PVR2D_CFLUSH_FROM_GPU ? 'i' :
713                                 '?');
714         else
715                 psRetOUT->eError = FlushCacheDRI(type, start, len);
716
717         up_read(&current->mm->mmap_sem);
718
719         return 0;
720 }
721
722 static int PVRSRVMapDeviceClassMemoryBW(u32 ui32BridgeID,
723            struct PVRSRV_BRIDGE_IN_MAP_DEVICECLASS_MEMORY *psMapDevClassMemIN,
724            struct PVRSRV_BRIDGE_OUT_MAP_DEVICECLASS_MEMORY *psMapDevClassMemOUT,
725            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
726 {
727         struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
728         void *hOSMapInfo;
729         void *hDeviceClassBufferInt;
730         void *hDevMemContextInt;
731         enum PVRSRV_HANDLE_TYPE eHandleType;
732
733         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
734                         PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY);
735
736         NEW_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc, 2);
737
738         psMapDevClassMemOUT->eError =
739                 PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
740                                 &hDeviceClassBufferInt, &eHandleType,
741                                 psMapDevClassMemIN->hDeviceClassBuffer);
742
743         if (psMapDevClassMemOUT->eError != PVRSRV_OK)
744                 return 0;
745
746         psMapDevClassMemOUT->eError =
747             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
748                                psMapDevClassMemIN->hDevMemContext,
749                                PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
750
751         if (psMapDevClassMemOUT->eError != PVRSRV_OK)
752                 return 0;
753
754         switch (eHandleType) {
755         case PVRSRV_HANDLE_TYPE_DISP_BUFFER:
756         case PVRSRV_HANDLE_TYPE_BUF_BUFFER:
757                 break;
758         default:
759                 psMapDevClassMemOUT->eError = PVRSRV_ERROR_GENERIC;
760                 return 0;
761         }
762
763         psMapDevClassMemOUT->eError =
764                 PVRSRVMapDeviceClassMemoryKM(psPerProc, hDevMemContextInt,
765                                 hDeviceClassBufferInt, &psMemInfo, &hOSMapInfo);
766
767         if (psMapDevClassMemOUT->eError != PVRSRV_OK)
768                 return 0;
769
770         OSMemSet(&psMapDevClassMemOUT->sClientMemInfo, 0,
771                  sizeof(psMapDevClassMemOUT->sClientMemInfo));
772         OSMemSet(&psMapDevClassMemOUT->sClientSyncInfo, 0,
773                  sizeof(psMapDevClassMemOUT->sClientSyncInfo));
774
775         psMapDevClassMemOUT->sClientMemInfo.pvLinAddrKM =
776                                                 psMemInfo->pvLinAddrKM;
777
778         psMapDevClassMemOUT->sClientMemInfo.pvLinAddr = NULL;
779         psMapDevClassMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
780         psMapDevClassMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
781         psMapDevClassMemOUT->sClientMemInfo.ui32AllocSize =
782                                                 psMemInfo->ui32AllocSize;
783         psMapDevClassMemOUT->sClientMemInfo.hMappingInfo =
784                                                 psMemInfo->sMemBlk.hOSMemHandle;
785
786         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
787                         &psMapDevClassMemOUT->sClientMemInfo.hKernelMemInfo,
788                         psMemInfo,
789                         PVRSRV_HANDLE_TYPE_MEM_INFO,
790                         PVRSRV_HANDLE_ALLOC_FLAG_NONE,
791                         psMapDevClassMemIN->hDeviceClassBuffer);
792
793         psMapDevClassMemOUT->sClientSyncInfo.hKernelSyncInfo = NULL;
794         psMapDevClassMemOUT->psKernelSyncInfo = NULL;
795
796         if (psMemInfo->psKernelSyncInfo) {
797                 psMapDevClassMemOUT->psKernelSyncInfo =
798                         psMemInfo->psKernelSyncInfo;
799
800                 psMapDevClassMemOUT->sClientSyncInfo.psSyncData =
801                         psMemInfo->psKernelSyncInfo->psSyncData;
802                 psMapDevClassMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
803                         psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
804                 psMapDevClassMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
805                         psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
806
807                 psMapDevClassMemOUT->sClientSyncInfo.hMappingInfo =
808                                 psMemInfo->psKernelSyncInfo->
809                                      psSyncDataMemInfoKM->sMemBlk.hOSMemHandle;
810
811                 psMapDevClassMemOUT->sClientMemInfo.psClientSyncInfo =
812                         &psMapDevClassMemOUT->sClientSyncInfo;
813
814                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
815                                 &psMapDevClassMemOUT->sClientSyncInfo.
816                                                                 hKernelSyncInfo,
817                                 psMemInfo->psKernelSyncInfo,
818                                 PVRSRV_HANDLE_TYPE_SYNC_INFO,
819                                 PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
820                                 psMapDevClassMemOUT->sClientMemInfo.
821                                                                 hKernelMemInfo);
822         }
823
824         COMMIT_HANDLE_BATCH_OR_ERROR(psMapDevClassMemOUT->eError, psPerProc);
825
826         return 0;
827 }
828
829 static int PVRSRVUnmapDeviceClassMemoryBW(u32 ui32BridgeID,
830          struct PVRSRV_BRIDGE_IN_UNMAP_DEVICECLASS_MEMORY *psUnmapDevClassMemIN,
831          struct PVRSRV_BRIDGE_RETURN *psRetOUT,
832          struct PVRSRV_PER_PROCESS_DATA *psPerProc)
833 {
834         void *pvKernelMemInfo;
835
836         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
837                                  PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY);
838
839         psRetOUT->eError =
840             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvKernelMemInfo,
841                                psUnmapDevClassMemIN->psKernelMemInfo,
842                                PVRSRV_HANDLE_TYPE_MEM_INFO);
843         if (psRetOUT->eError != PVRSRV_OK)
844                 return 0;
845
846         psRetOUT->eError = PVRSRVUnmapDeviceClassMemoryKM(pvKernelMemInfo);
847
848         if (psRetOUT->eError != PVRSRV_OK)
849                 return 0;
850
851         psRetOUT->eError =
852             PVRSRVReleaseHandle(psPerProc->psHandleBase,
853                                 psUnmapDevClassMemIN->psKernelMemInfo,
854                                 PVRSRV_HANDLE_TYPE_MEM_INFO);
855
856         return 0;
857 }
858
859 static int PVRSRVWrapExtMemoryBW(u32 ui32BridgeID,
860                       struct PVRSRV_BRIDGE_IN_WRAP_EXT_MEMORY *psWrapExtMemIN,
861                       struct PVRSRV_BRIDGE_OUT_WRAP_EXT_MEMORY *psWrapExtMemOUT,
862                       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
863 {
864         void *hDevCookieInt;
865         void *hDevMemContextInt;
866         struct PVRSRV_KERNEL_MEM_INFO *psMemInfo;
867         u32 ui32PageTableSize = 0;
868         struct IMG_SYS_PHYADDR *psSysPAddr = NULL;
869
870         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_WRAP_EXT_MEMORY);
871
872         NEW_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc, 2);
873
874         psWrapExtMemOUT->eError =
875             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevCookieInt,
876                                psWrapExtMemIN->hDevCookie,
877                                PVRSRV_HANDLE_TYPE_DEV_NODE);
878         if (psWrapExtMemOUT->eError != PVRSRV_OK)
879                 return 0;
880
881         psWrapExtMemOUT->eError =
882             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
883                                psWrapExtMemIN->hDevMemContext,
884                                PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
885
886         if (psWrapExtMemOUT->eError != PVRSRV_OK)
887                 return 0;
888
889         if (psWrapExtMemIN->ui32NumPageTableEntries) {
890                 ui32PageTableSize = psWrapExtMemIN->ui32NumPageTableEntries
891                     * sizeof(struct IMG_SYS_PHYADDR);
892
893                 ASSIGN_AND_EXIT_ON_ERROR(psWrapExtMemOUT->eError,
894                                          OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
895                                                    ui32PageTableSize,
896                                                    (void **)&psSysPAddr, NULL));
897
898                 if (CopyFromUserWrapper(psPerProc, ui32BridgeID, psSysPAddr,
899                                         psWrapExtMemIN->psSysPAddr,
900                                         ui32PageTableSize) != PVRSRV_OK) {
901                         OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize,
902                                   (void *) psSysPAddr, NULL);
903                         return -EFAULT;
904                 }
905         }
906
907         psWrapExtMemOUT->eError = PVRSRVWrapExtMemoryKM(hDevCookieInt,
908                                   psPerProc, hDevMemContextInt,
909                                   psWrapExtMemIN->ui32ByteSize,
910                                   psWrapExtMemIN->ui32PageOffset,
911                                   psWrapExtMemIN->bPhysContig,
912                                   psSysPAddr, psWrapExtMemIN->pvLinAddr,
913                                   &psMemInfo);
914         if (psWrapExtMemIN->ui32NumPageTableEntries)
915                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, ui32PageTableSize,
916                           (void *)psSysPAddr, NULL);
917         if (psWrapExtMemOUT->eError != PVRSRV_OK)
918                 return 0;
919
920         psWrapExtMemOUT->sClientMemInfo.pvLinAddrKM = psMemInfo->pvLinAddrKM;
921
922         psWrapExtMemOUT->sClientMemInfo.pvLinAddr = NULL;
923         psWrapExtMemOUT->sClientMemInfo.sDevVAddr = psMemInfo->sDevVAddr;
924         psWrapExtMemOUT->sClientMemInfo.ui32Flags = psMemInfo->ui32Flags;
925         psWrapExtMemOUT->sClientMemInfo.ui32AllocSize =
926                                                     psMemInfo->ui32AllocSize;
927         psWrapExtMemOUT->sClientMemInfo.hMappingInfo =
928                                             psMemInfo->sMemBlk.hOSMemHandle;
929
930         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
931                             &psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo,
932                             psMemInfo, PVRSRV_HANDLE_TYPE_MEM_INFO,
933                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
934
935         psWrapExtMemOUT->sClientSyncInfo.psSyncData =
936             psMemInfo->psKernelSyncInfo->psSyncData;
937         psWrapExtMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
938             psMemInfo->psKernelSyncInfo->sWriteOpsCompleteDevVAddr;
939         psWrapExtMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
940             psMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
941
942         psWrapExtMemOUT->sClientSyncInfo.hMappingInfo =
943             psMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->sMemBlk.
944                                                             hOSMemHandle;
945
946         psWrapExtMemOUT->sClientMemInfo.psClientSyncInfo =
947             &psWrapExtMemOUT->sClientSyncInfo;
948
949         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
950                                &psWrapExtMemOUT->sClientSyncInfo.
951                                                                hKernelSyncInfo,
952                                (void *)psMemInfo->psKernelSyncInfo,
953                                PVRSRV_HANDLE_TYPE_SYNC_INFO,
954                                PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
955                                psWrapExtMemOUT->sClientMemInfo.hKernelMemInfo);
956
957         COMMIT_HANDLE_BATCH_OR_ERROR(psWrapExtMemOUT->eError, psPerProc);
958
959         return 0;
960 }
961
962 static int PVRSRVUnwrapExtMemoryBW(u32 ui32BridgeID,
963                 struct PVRSRV_BRIDGE_IN_UNWRAP_EXT_MEMORY *psUnwrapExtMemIN,
964                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
965                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
966 {
967         void *pvMemInfo;
968
969         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY);
970
971         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
972                                &pvMemInfo, psUnwrapExtMemIN->hKernelMemInfo,
973                                PVRSRV_HANDLE_TYPE_MEM_INFO);
974         if (psRetOUT->eError != PVRSRV_OK)
975                 return 0;
976
977         psRetOUT->eError =
978             PVRSRVUnwrapExtMemoryKM((struct PVRSRV_KERNEL_MEM_INFO *)pvMemInfo);
979         if (psRetOUT->eError != PVRSRV_OK)
980                 return 0;
981
982         psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
983                                 psUnwrapExtMemIN->hKernelMemInfo,
984                                 PVRSRV_HANDLE_TYPE_MEM_INFO);
985
986         return 0;
987 }
988
989 static int PVRSRVGetFreeDeviceMemBW(u32 ui32BridgeID,
990          struct PVRSRV_BRIDGE_IN_GETFREEDEVICEMEM *psGetFreeDeviceMemIN,
991          struct PVRSRV_BRIDGE_OUT_GETFREEDEVICEMEM *psGetFreeDeviceMemOUT,
992          struct PVRSRV_PER_PROCESS_DATA *psPerProc)
993 {
994         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GETFREE_DEVICEMEM);
995
996         PVR_UNREFERENCED_PARAMETER(psPerProc);
997
998         psGetFreeDeviceMemOUT->eError =
999             PVRSRVGetFreeDeviceMemKM(psGetFreeDeviceMemIN->ui32Flags,
1000                                      &psGetFreeDeviceMemOUT->ui32Total,
1001                                      &psGetFreeDeviceMemOUT->ui32Free,
1002                                      &psGetFreeDeviceMemOUT->ui32LargestBlock);
1003
1004         return 0;
1005 }
1006
1007 static int PVRMMapOSMemHandleToMMapDataBW(u32 ui32BridgeID,
1008           struct PVRSRV_BRIDGE_IN_MHANDLE_TO_MMAP_DATA *psMMapDataIN,
1009           struct PVRSRV_BRIDGE_OUT_MHANDLE_TO_MMAP_DATA *psMMapDataOUT,
1010           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1011 {
1012         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1013                                  PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA);
1014
1015         psMMapDataOUT->eError =
1016             PVRMMapOSMemHandleToMMapData(psPerProc, psMMapDataIN->hMHandle,
1017                                          &psMMapDataOUT->ui32MMapOffset,
1018                                          &psMMapDataOUT->ui32ByteOffset,
1019                                          &psMMapDataOUT->ui32RealByteSize,
1020                                          &psMMapDataOUT->ui32UserVAddr);
1021         return 0;
1022 }
1023
1024 static int PVRMMapReleaseMMapDataBW(u32 ui32BridgeID,
1025                     struct PVRSRV_BRIDGE_IN_RELEASE_MMAP_DATA *psMMapDataIN,
1026                     struct PVRSRV_BRIDGE_OUT_RELEASE_MMAP_DATA *psMMapDataOUT,
1027                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1028 {
1029         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_RELEASE_MMAP_DATA);
1030
1031         psMMapDataOUT->eError = PVRMMapReleaseMMapData(psPerProc,
1032                                            psMMapDataIN->hMHandle,
1033                                            &psMMapDataOUT->bMUnmap,
1034                                            &psMMapDataOUT->ui32RealByteSize,
1035                                            &psMMapDataOUT->ui32UserVAddr);
1036         return 0;
1037 }
1038
1039 #ifdef PDUMP
1040 static int PDumpIsCaptureFrameBW(u32 ui32BridgeID, void *psBridgeIn,
1041               struct PVRSRV_BRIDGE_OUT_PDUMP_ISCAPTURING *psPDumpIsCapturingOUT,
1042               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1043 {
1044         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_ISCAPTURING);
1045         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1046         PVR_UNREFERENCED_PARAMETER(psPerProc);
1047
1048         psPDumpIsCapturingOUT->bIsCapturing = PDumpIsCaptureFrameKM();
1049         psPDumpIsCapturingOUT->eError = PVRSRV_OK;
1050
1051         return 0;
1052 }
1053
1054 static int PDumpCommentBW(u32 ui32BridgeID,
1055                struct PVRSRV_BRIDGE_IN_PDUMP_COMMENT *psPDumpCommentIN,
1056                struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1057                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1058 {
1059         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_COMMENT);
1060         PVR_UNREFERENCED_PARAMETER(psPerProc);
1061
1062         psRetOUT->eError = PDumpCommentKM(&psPDumpCommentIN->szComment[0],
1063                                           psPDumpCommentIN->ui32Flags);
1064         return 0;
1065 }
1066
1067 static int PDumpSetFrameBW(u32 ui32BridgeID,
1068                 struct PVRSRV_BRIDGE_IN_PDUMP_SETFRAME *psPDumpSetFrameIN,
1069                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1070                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1071 {
1072         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SETFRAME);
1073         PVR_UNREFERENCED_PARAMETER(psPerProc);
1074
1075         psRetOUT->eError = PDumpSetFrameKM(psPDumpSetFrameIN->ui32Frame);
1076
1077         return 0;
1078 }
1079
1080 static int PDumpRegWithFlagsBW(u32 ui32BridgeID,
1081                     struct PVRSRV_BRIDGE_IN_PDUMP_DUMPREG *psPDumpRegDumpIN,
1082                     struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1083                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1084 {
1085         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REG);
1086         PVR_UNREFERENCED_PARAMETER(psPerProc);
1087
1088         psRetOUT->eError =
1089             PDumpRegWithFlagsKM(psPDumpRegDumpIN->sHWReg.ui32RegAddr,
1090                                 psPDumpRegDumpIN->sHWReg.ui32RegVal,
1091                                 psPDumpRegDumpIN->ui32Flags);
1092
1093         return 0;
1094 }
1095
1096 static int PDumpRegPolBW(u32 ui32BridgeID,
1097               struct PVRSRV_BRIDGE_IN_PDUMP_REGPOL *psPDumpRegPolIN,
1098               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1099               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1100 {
1101         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_REGPOL);
1102         PVR_UNREFERENCED_PARAMETER(psPerProc);
1103
1104         psRetOUT->eError =
1105             PDumpRegPolWithFlagsKM(psPDumpRegPolIN->sHWReg.ui32RegAddr,
1106                                    psPDumpRegPolIN->sHWReg.ui32RegVal,
1107                                    psPDumpRegPolIN->ui32Mask,
1108                                    psPDumpRegPolIN->ui32Flags);
1109
1110         return 0;
1111 }
1112
1113 static int PDumpMemPolBW(u32 ui32BridgeID,
1114               struct PVRSRV_BRIDGE_IN_PDUMP_MEMPOL *psPDumpMemPolIN,
1115               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1116               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1117 {
1118         void *pvMemInfo;
1119
1120         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_MEMPOL);
1121
1122         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1123                                               &pvMemInfo,
1124                                               psPDumpMemPolIN->psKernelMemInfo,
1125                                               PVRSRV_HANDLE_TYPE_MEM_INFO);
1126         if (psRetOUT->eError != PVRSRV_OK)
1127                 return 0;
1128
1129         psRetOUT->eError =
1130             PDumpMemPolKM(((struct PVRSRV_KERNEL_MEM_INFO *)pvMemInfo),
1131                           psPDumpMemPolIN->ui32Offset,
1132                           psPDumpMemPolIN->ui32Value,
1133                           psPDumpMemPolIN->ui32Mask,
1134                           PDUMP_POLL_OPERATOR_EQUAL,
1135                           psPDumpMemPolIN->bLastFrame,
1136                           psPDumpMemPolIN->bOverwrite,
1137                           MAKEUNIQUETAG(pvMemInfo));
1138
1139         return 0;
1140 }
1141
1142 static int PDumpMemBW(u32 ui32BridgeID,
1143            struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
1144            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1145            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1146 {
1147         void *pvMemInfo;
1148
1149         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
1150
1151         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1152                                         &pvMemInfo,
1153                                         psPDumpMemDumpIN->psKernelMemInfo,
1154                                         PVRSRV_HANDLE_TYPE_MEM_INFO);
1155         if (psRetOUT->eError != PVRSRV_OK)
1156                 return 0;
1157
1158         psRetOUT->eError = PDumpMemUM(psPerProc, psPDumpMemDumpIN->pvAltLinAddr,
1159                                        psPDumpMemDumpIN->pvLinAddr,
1160                                        pvMemInfo, psPDumpMemDumpIN->ui32Offset,
1161                                        psPDumpMemDumpIN->ui32Bytes,
1162                                        psPDumpMemDumpIN->ui32Flags,
1163                                                       MAKEUNIQUETAG(pvMemInfo));
1164
1165         return 0;
1166 }
1167
1168 static int PDumpBitmapBW(u32 ui32BridgeID,
1169               struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
1170               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1171               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1172 {
1173         PVR_UNREFERENCED_PARAMETER(psPerProc);
1174         PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
1175
1176         psRetOUT->eError = PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0],
1177                           psPDumpBitmapIN->ui32FileOffset,
1178                           psPDumpBitmapIN->ui32Width,
1179                           psPDumpBitmapIN->ui32Height,
1180                           psPDumpBitmapIN->ui32StrideInBytes,
1181                           psPDumpBitmapIN->sDevBaseAddr,
1182                           psPDumpBitmapIN->ui32Size,
1183                           psPDumpBitmapIN->ePixelFormat,
1184                           psPDumpBitmapIN->eMemFormat,
1185                           psPDumpBitmapIN->ui32Flags);
1186
1187         return 0;
1188 }
1189
1190 static int PDumpReadRegBW(u32 ui32BridgeID,
1191                struct PVRSRV_BRIDGE_IN_PDUMP_READREG *psPDumpReadRegIN,
1192                struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1193                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1194 {
1195         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPREADREG);
1196         PVR_UNREFERENCED_PARAMETER(psPerProc);
1197
1198         psRetOUT->eError = PDumpReadRegKM(&psPDumpReadRegIN->szFileName[0],
1199                            psPDumpReadRegIN->ui32FileOffset,
1200                            psPDumpReadRegIN->ui32Address,
1201                            psPDumpReadRegIN->ui32Size,
1202                            psPDumpReadRegIN->ui32Flags);
1203
1204         return 0;
1205 }
1206
1207 static int PDumpDriverInfoBW(u32 ui32BridgeID,
1208                   struct PVRSRV_BRIDGE_IN_PDUMP_DRIVERINFO *psPDumpDriverInfoIN,
1209                   struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1210                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1211 {
1212         u32 ui32PDumpFlags;
1213
1214         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DRIVERINFO);
1215         PVR_UNREFERENCED_PARAMETER(psPerProc);
1216
1217         ui32PDumpFlags = 0;
1218         if (psPDumpDriverInfoIN->bContinuous)
1219                 ui32PDumpFlags |= PDUMP_FLAGS_CONTINUOUS;
1220         psRetOUT->eError = PDumpDriverInfoKM(&psPDumpDriverInfoIN->szString[0],
1221                                              ui32PDumpFlags);
1222
1223         return 0;
1224 }
1225
1226 static int PDumpSyncDumpBW(u32 ui32BridgeID,
1227                 struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
1228                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1229                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1230 {
1231         u32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
1232         void *pvSyncInfo;
1233
1234         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
1235
1236         psRetOUT->eError =
1237             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1238                                psPDumpSyncDumpIN->psKernelSyncInfo,
1239                                PVRSRV_HANDLE_TYPE_SYNC_INFO);
1240         if (psRetOUT->eError != PVRSRV_OK)
1241                 return 0;
1242
1243         psRetOUT->eError =
1244             PDumpMemUM(psPerProc, psPDumpSyncDumpIN->pvAltLinAddr, NULL,
1245                         ((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->
1246                                                         psSyncDataMemInfoKM,
1247                         psPDumpSyncDumpIN->ui32Offset, ui32Bytes, 0,
1248                         MAKEUNIQUETAG(((struct PVRSRV_KERNEL_SYNC_INFO *)
1249                                             pvSyncInfo)->psSyncDataMemInfoKM));
1250
1251         return 0;
1252 }
1253
1254 static int PDumpSyncPolBW(u32 ui32BridgeID,
1255                struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
1256                struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1257                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1258 {
1259         u32 ui32Offset;
1260         void *pvSyncInfo;
1261
1262         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
1263
1264         psRetOUT->eError =
1265             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1266                                psPDumpSyncPolIN->psKernelSyncInfo,
1267                                PVRSRV_HANDLE_TYPE_SYNC_INFO);
1268         if (psRetOUT->eError != PVRSRV_OK)
1269                 return 0;
1270
1271         if (psPDumpSyncPolIN->bIsRead)
1272                 ui32Offset = offsetof(struct PVRSRV_SYNC_DATA,
1273                                       ui32ReadOpsComplete);
1274         else
1275                 ui32Offset = offsetof(struct PVRSRV_SYNC_DATA,
1276                                       ui32WriteOpsComplete);
1277
1278         psRetOUT->eError =
1279             PDumpMemPolKM(((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->
1280                           psSyncDataMemInfoKM, ui32Offset,
1281                           psPDumpSyncPolIN->ui32Value,
1282                           psPDumpSyncPolIN->ui32Mask, PDUMP_POLL_OPERATOR_EQUAL,
1283                           IMG_FALSE, IMG_FALSE,
1284                           MAKEUNIQUETAG(((struct PVRSRV_KERNEL_SYNC_INFO *)
1285                                           pvSyncInfo)->psSyncDataMemInfoKM));
1286
1287         return 0;
1288 }
1289
1290 static int PDumpPDRegBW(u32 ui32BridgeID,
1291              struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG *psPDumpPDRegDumpIN,
1292              struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1293              struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1294 {
1295         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_PDREG);
1296         PVR_UNREFERENCED_PARAMETER(psPerProc);
1297
1298         PDumpPDReg(psPDumpPDRegDumpIN->sHWReg.ui32RegAddr,
1299                    psPDumpPDRegDumpIN->sHWReg.ui32RegVal, PDUMP_PD_UNIQUETAG);
1300
1301         psRetOUT->eError = PVRSRV_OK;
1302         return 0;
1303 }
1304
1305 static int PDumpCycleCountRegReadBW(u32 ui32BridgeID,
1306                 struct PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ
1307                                         *psPDumpCycleCountRegReadIN,
1308                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1309                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1310 {
1311         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1312                                  PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
1313         PVR_UNREFERENCED_PARAMETER(psPerProc);
1314
1315         PDumpCycleCountRegRead(psPDumpCycleCountRegReadIN->ui32RegOffset,
1316                                psPDumpCycleCountRegReadIN->bLastFrame);
1317
1318         psRetOUT->eError = PVRSRV_OK;
1319
1320         return 0;
1321 }
1322
1323 static int PDumpPDDevPAddrBW(u32 ui32BridgeID,
1324           struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
1325           struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1326           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1327 {
1328         void *pvMemInfo;
1329
1330         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1331                                  PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
1332
1333         psRetOUT->eError =
1334             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
1335                                psPDumpPDDevPAddrIN->hKernelMemInfo,
1336                                PVRSRV_HANDLE_TYPE_MEM_INFO);
1337         if (psRetOUT->eError != PVRSRV_OK)
1338                 return 0;
1339
1340         psRetOUT->eError =
1341             PDumpPDDevPAddrKM((struct PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
1342                               psPDumpPDDevPAddrIN->ui32Offset,
1343                               psPDumpPDDevPAddrIN->sPDDevPAddr,
1344                               MAKEUNIQUETAG(pvMemInfo), PDUMP_PD_UNIQUETAG);
1345         return 0;
1346 }
1347
1348 static int PDumpStartInitPhaseBW(u32 ui32BridgeID, void *psBridgeIn,
1349                        struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1350                        struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1351 {
1352         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1353                                  PVRSRV_BRIDGE_PDUMP_STARTINITPHASE);
1354         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1355         PVR_UNREFERENCED_PARAMETER(psPerProc);
1356
1357         psRetOUT->eError = PDumpStartInitPhaseKM();
1358
1359         return 0;
1360 }
1361
1362 static int PDumpStopInitPhaseBW(u32 ui32BridgeID, void *psBridgeIn,
1363         struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1364         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1365 {
1366         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1367                                  PVRSRV_BRIDGE_PDUMP_STOPINITPHASE);
1368         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1369         PVR_UNREFERENCED_PARAMETER(psPerProc);
1370
1371         psRetOUT->eError = PDumpStopInitPhaseKM();
1372
1373         return 0;
1374 }
1375
1376 #endif
1377
1378 static int PVRSRVGetMiscInfoBW(u32 ui32BridgeID,
1379                     struct PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
1380                     struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
1381                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1382 {
1383         enum PVRSRV_ERROR eError;
1384
1385         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
1386
1387         OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, &psGetMiscInfoIN->sMiscInfo,
1388                   sizeof(struct PVRSRV_MISC_INFO));
1389
1390         if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1391                 PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
1392             ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1393                 PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) {
1394
1395                 psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1396                 return 0;
1397         }
1398
1399         if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1400                 PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
1401             ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1402                 PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) {
1403
1404                 ASSIGN_AND_EXIT_ON_ERROR(
1405                         psGetMiscInfoOUT->eError,
1406                         OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1407                            psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1408                            (void **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1409                            NULL));
1410
1411                 psGetMiscInfoOUT->eError =
1412                     PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1413
1414                 eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
1415                                 (void __force __user *)
1416                                         psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
1417                                 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1418                                 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
1419
1420                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1421                           psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1422                           (void *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1423                           NULL);
1424
1425                 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr =
1426                                         psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
1427
1428                 if (eError != PVRSRV_OK) {
1429                         PVR_DPF(PVR_DBG_ERROR,
1430                                  "PVRSRVGetMiscInfoBW Error copy to user");
1431                         return -EFAULT;
1432                 }
1433         } else {
1434                 psGetMiscInfoOUT->eError =
1435                             PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1436         }
1437
1438         if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1439                 return 0;
1440
1441         if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1442             PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) {
1443                 psGetMiscInfoOUT->eError =
1444                     PVRSRVAllocHandle(psPerProc->psHandleBase,
1445                                       &psGetMiscInfoOUT->sMiscInfo.
1446                                               sGlobalEventObject.hOSEventKM,
1447                                       psGetMiscInfoOUT->sMiscInfo.
1448                                               sGlobalEventObject.hOSEventKM,
1449                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
1450                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1451
1452                 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1453                         return 0;
1454         }
1455
1456         if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle) {
1457                 psGetMiscInfoOUT->eError =
1458                     PVRSRVAllocHandle(psPerProc->psHandleBase,
1459                                       &psGetMiscInfoOUT->sMiscInfo.
1460                                               hSOCTimerRegisterOSMemHandle,
1461                                       psGetMiscInfoOUT->sMiscInfo.
1462                                               hSOCTimerRegisterOSMemHandle,
1463                                       PVRSRV_HANDLE_TYPE_SOC_TIMER,
1464                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1465
1466                 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1467                         return 0;
1468         }
1469
1470         return 0;
1471 }
1472
1473 static int PVRSRVConnectBW(u32 ui32BridgeID, void *psBridgeIn,
1474                 struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
1475                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1476 {
1477         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1478
1479         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
1480
1481         psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
1482         psConnectServicesOUT->eError = PVRSRV_OK;
1483
1484 #if defined(PDUMP)
1485
1486         {
1487                 struct SYS_DATA *psSysData;
1488                 SysAcquireData(&psSysData);
1489                 psSysData->bPowerUpPDumped = IMG_FALSE;
1490         }
1491 #endif
1492
1493         return 0;
1494 }
1495
1496 static int PVRSRVDisconnectBW(u32 ui32BridgeID, void *psBridgeIn,
1497                    struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1498                    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1499 {
1500         PVR_UNREFERENCED_PARAMETER(psPerProc);
1501         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1502
1503         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1504                                  PVRSRV_BRIDGE_DISCONNECT_SERVICES);
1505
1506         psRetOUT->eError = PVRSRV_OK;
1507
1508         return 0;
1509 }
1510
1511 static int PVRSRVEnumerateDCBW(u32 ui32BridgeID,
1512                     struct PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
1513                     struct PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
1514                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1515 {
1516         PVR_UNREFERENCED_PARAMETER(psPerProc);
1517
1518         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
1519
1520         psEnumDispClassOUT->eError =
1521             PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
1522                                 &psEnumDispClassOUT->ui32NumDevices,
1523                                 &psEnumDispClassOUT->ui32DevID[0]);
1524
1525         return 0;
1526 }
1527
1528 static int PVRSRVOpenDCDeviceBW(u32 ui32BridgeID,
1529      struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
1530      struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
1531      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1532 {
1533         void *hDevCookieInt;
1534         void *hDispClassInfoInt;
1535
1536         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1537                                  PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
1538
1539         NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc,
1540                                   1);
1541
1542         psOpenDispClassDeviceOUT->eError =
1543             PVRSRVLookupHandle(psPerProc->psHandleBase,
1544                                &hDevCookieInt,
1545                                psOpenDispClassDeviceIN->hDevCookie,
1546                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1547         if (psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1548                 return 0;
1549
1550         psOpenDispClassDeviceOUT->eError = PVRSRVOpenDCDeviceKM(psPerProc,
1551                                  psOpenDispClassDeviceIN->ui32DeviceID,
1552                                  hDevCookieInt, &hDispClassInfoInt);
1553
1554         if (psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1555                 return 0;
1556
1557         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1558                             &psOpenDispClassDeviceOUT->hDeviceKM,
1559                             hDispClassInfoInt,
1560                             PVRSRV_HANDLE_TYPE_DISP_INFO,
1561                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1562         COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError,
1563                                      psPerProc);
1564
1565         return 0;
1566 }
1567
1568 static int PVRSRVCloseDCDeviceBW(u32 ui32BridgeID,
1569      struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
1570      struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1571      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1572 {
1573         void *pvDispClassInfoInt;
1574
1575         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1576                                  PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
1577
1578         psRetOUT->eError =
1579             PVRSRVLookupHandle(psPerProc->psHandleBase,
1580                                &pvDispClassInfoInt,
1581                                psCloseDispClassDeviceIN->hDeviceKM,
1582                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1583
1584         if (psRetOUT->eError != PVRSRV_OK)
1585                 return 0;
1586
1587         psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
1588         if (psRetOUT->eError != PVRSRV_OK)
1589                 return 0;
1590
1591         psRetOUT->eError =
1592             PVRSRVReleaseHandle(psPerProc->psHandleBase,
1593                                 psCloseDispClassDeviceIN->hDeviceKM,
1594                                 PVRSRV_HANDLE_TYPE_DISP_INFO);
1595         return 0;
1596 }
1597
1598 static int PVRSRVEnumDCFormatsBW(u32 ui32BridgeID,
1599      struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
1600      struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
1601      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1602 {
1603         void *pvDispClassInfoInt;
1604
1605         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1606                                  PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
1607
1608         psEnumDispClassFormatsOUT->eError =
1609             PVRSRVLookupHandle(psPerProc->psHandleBase,
1610                                &pvDispClassInfoInt,
1611                                psEnumDispClassFormatsIN->hDeviceKM,
1612                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1613         if (psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
1614                 return 0;
1615
1616         psEnumDispClassFormatsOUT->eError =
1617             PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
1618                                   &psEnumDispClassFormatsOUT->ui32Count,
1619                                   psEnumDispClassFormatsOUT->asFormat);
1620
1621         return 0;
1622 }
1623
1624 static int PVRSRVEnumDCDimsBW(u32 ui32BridgeID,
1625            struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
1626            struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
1627            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1628 {
1629         void *pvDispClassInfoInt;
1630
1631         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1632                                  PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
1633
1634         psEnumDispClassDimsOUT->eError =
1635             PVRSRVLookupHandle(psPerProc->psHandleBase,
1636                                &pvDispClassInfoInt,
1637                                psEnumDispClassDimsIN->hDeviceKM,
1638                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1639
1640         if (psEnumDispClassDimsOUT->eError != PVRSRV_OK)
1641                 return 0;
1642
1643         psEnumDispClassDimsOUT->eError =
1644             PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
1645                                &psEnumDispClassDimsIN->sFormat,
1646                                &psEnumDispClassDimsOUT->ui32Count,
1647                                psEnumDispClassDimsOUT->asDim);
1648
1649         return 0;
1650 }
1651
1652 static int PVRSRVGetDCSystemBufferBW(u32 ui32BridgeID,
1653    struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,
1654    struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
1655    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1656 {
1657         void *hBufferInt;
1658         void *pvDispClassInfoInt;
1659
1660         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1661                                  PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
1662
1663         NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc,
1664                                   1);
1665
1666         psGetDispClassSysBufferOUT->eError =
1667             PVRSRVLookupHandle(psPerProc->psHandleBase,
1668                                &pvDispClassInfoInt,
1669                                psGetDispClassSysBufferIN->hDeviceKM,
1670                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1671         if (psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1672                 return 0;
1673
1674         psGetDispClassSysBufferOUT->eError =
1675             PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt, &hBufferInt);
1676
1677         if (psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1678                 return 0;
1679
1680         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1681                                &psGetDispClassSysBufferOUT->hBuffer,
1682                                hBufferInt,
1683                                PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1684                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
1685                                (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
1686                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
1687                                psGetDispClassSysBufferIN->hDeviceKM);
1688
1689         COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError,
1690                                      psPerProc);
1691
1692         return 0;
1693 }
1694
1695 static int PVRSRVGetDCInfoBW(u32 ui32BridgeID,
1696           struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
1697           struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
1698           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1699 {
1700         void *pvDispClassInfo;
1701
1702         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1703                                  PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
1704
1705         psGetDispClassInfoOUT->eError =
1706             PVRSRVLookupHandle(psPerProc->psHandleBase,
1707                                &pvDispClassInfo,
1708                                psGetDispClassInfoIN->hDeviceKM,
1709                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1710         if (psGetDispClassInfoOUT->eError != PVRSRV_OK)
1711                 return 0;
1712
1713         psGetDispClassInfoOUT->eError =
1714             PVRSRVGetDCInfoKM(pvDispClassInfo,
1715                               &psGetDispClassInfoOUT->sDisplayInfo);
1716
1717         return 0;
1718 }
1719
1720 static int PVRSRVCreateDCSwapChainBW(u32 ui32BridgeID,
1721                   struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN
1722                                 *psCreateDispClassSwapChainIN,
1723                   struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN
1724                                 *psCreateDispClassSwapChainOUT,
1725                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1726 {
1727         void *pvDispClassInfo;
1728         void *hSwapChainInt;
1729
1730         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1731                                  PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
1732
1733         NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError,
1734                                   psPerProc, 1);
1735
1736         psCreateDispClassSwapChainOUT->eError =
1737             PVRSRVLookupHandle(psPerProc->psHandleBase,
1738                                &pvDispClassInfo,
1739                                psCreateDispClassSwapChainIN->hDeviceKM,
1740                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1741
1742         if (psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1743                 return 0;
1744
1745         psCreateDispClassSwapChainOUT->eError =
1746             PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
1747                         psCreateDispClassSwapChainIN->ui32Flags,
1748                         &psCreateDispClassSwapChainIN->sDstSurfAttrib,
1749                         &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
1750                         psCreateDispClassSwapChainIN->ui32BufferCount,
1751                         psCreateDispClassSwapChainIN->ui32OEMFlags,
1752                         &hSwapChainInt,
1753                         &psCreateDispClassSwapChainOUT->ui32SwapChainID);
1754
1755         if (psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1756                 return 0;
1757
1758         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1759                                &psCreateDispClassSwapChainOUT->hSwapChain,
1760                                hSwapChainInt,
1761                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
1762                                PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1763                                psCreateDispClassSwapChainIN->hDeviceKM);
1764
1765         COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError,
1766                                      psPerProc);
1767
1768         return 0;
1769 }
1770
1771 static int PVRSRVDestroyDCSwapChainBW(u32 ui32BridgeID,
1772                            struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN
1773                                         *psDestroyDispClassSwapChainIN,
1774                            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1775                            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1776 {
1777         void *pvSwapChain;
1778
1779         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1780                                  PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
1781
1782         psRetOUT->eError =
1783             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
1784                                psDestroyDispClassSwapChainIN->hSwapChain,
1785                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1786         if (psRetOUT->eError != PVRSRV_OK)
1787                 return 0;
1788
1789         psRetOUT->eError = PVRSRVDestroyDCSwapChainKM(pvSwapChain);
1790
1791         if (psRetOUT->eError != PVRSRV_OK)
1792                 return 0;
1793
1794         psRetOUT->eError =
1795             PVRSRVReleaseHandle(psPerProc->psHandleBase,
1796                                 psDestroyDispClassSwapChainIN->hSwapChain,
1797                                 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1798
1799         return 0;
1800 }
1801
1802 static int PVRSRVSetDCDstRectBW(u32 ui32BridgeID,
1803          struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
1804          struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1805          struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1806 {
1807         void *pvDispClassInfo;
1808         void *pvSwapChain;
1809
1810         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1811                                  PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
1812
1813         psRetOUT->eError =
1814             PVRSRVLookupHandle(psPerProc->psHandleBase,
1815                                &pvDispClassInfo,
1816                                psSetDispClassDstRectIN->hDeviceKM,
1817                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1818         if (psRetOUT->eError != PVRSRV_OK)
1819                 return 0;
1820
1821         psRetOUT->eError =
1822             PVRSRVLookupHandle(psPerProc->psHandleBase,
1823                                &pvSwapChain,
1824                                psSetDispClassDstRectIN->hSwapChain,
1825                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1826
1827         if (psRetOUT->eError != PVRSRV_OK)
1828                 return 0;
1829
1830         psRetOUT->eError =
1831             PVRSRVSetDCDstRectKM(pvDispClassInfo,
1832                                  pvSwapChain, &psSetDispClassDstRectIN->sRect);
1833
1834         return 0;
1835 }
1836
1837 static int PVRSRVSetDCSrcRectBW(u32 ui32BridgeID,
1838      struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
1839      struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1840      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1841 {
1842         void *pvDispClassInfo;
1843         void *pvSwapChain;
1844
1845         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1846                                  PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
1847
1848         psRetOUT->eError =
1849             PVRSRVLookupHandle(psPerProc->psHandleBase,
1850                                &pvDispClassInfo,
1851                                psSetDispClassSrcRectIN->hDeviceKM,
1852                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1853         if (psRetOUT->eError != PVRSRV_OK)
1854                 return 0;
1855
1856         psRetOUT->eError =
1857             PVRSRVLookupHandle(psPerProc->psHandleBase,
1858                                &pvSwapChain,
1859                                psSetDispClassSrcRectIN->hSwapChain,
1860                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1861         if (psRetOUT->eError != PVRSRV_OK)
1862                 return 0;
1863
1864         psRetOUT->eError =
1865             PVRSRVSetDCSrcRectKM(pvDispClassInfo,
1866                                  pvSwapChain, &psSetDispClassSrcRectIN->sRect);
1867
1868         return 0;
1869 }
1870
1871 static int PVRSRVSetDCDstColourKeyBW(u32 ui32BridgeID,
1872        struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
1873        struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1874        struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1875 {
1876         void *pvDispClassInfo;
1877         void *pvSwapChain;
1878
1879         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1880                                  PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
1881
1882         psRetOUT->eError =
1883             PVRSRVLookupHandle(psPerProc->psHandleBase,
1884                                &pvDispClassInfo,
1885                                psSetDispClassColKeyIN->hDeviceKM,
1886                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1887         if (psRetOUT->eError != PVRSRV_OK)
1888                 return 0;
1889
1890         psRetOUT->eError =
1891             PVRSRVLookupHandle(psPerProc->psHandleBase,
1892                                &pvSwapChain,
1893                                psSetDispClassColKeyIN->hSwapChain,
1894                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1895         if (psRetOUT->eError != PVRSRV_OK)
1896                 return 0;
1897
1898         psRetOUT->eError =
1899             PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
1900                                       pvSwapChain,
1901                                       psSetDispClassColKeyIN->ui32CKColour);
1902
1903         return 0;
1904 }
1905
1906 static int PVRSRVSetDCSrcColourKeyBW(u32 ui32BridgeID,
1907         struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
1908         struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1909         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1910 {
1911         void *pvDispClassInfo;
1912         void *pvSwapChain;
1913
1914         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1915                                  PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
1916
1917         psRetOUT->eError =
1918             PVRSRVLookupHandle(psPerProc->psHandleBase,
1919                                &pvDispClassInfo,
1920                                psSetDispClassColKeyIN->hDeviceKM,
1921                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1922         if (psRetOUT->eError != PVRSRV_OK)
1923                 return 0;
1924
1925         psRetOUT->eError =
1926             PVRSRVLookupHandle(psPerProc->psHandleBase,
1927                                &pvSwapChain,
1928                                psSetDispClassColKeyIN->hSwapChain,
1929                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1930         if (psRetOUT->eError != PVRSRV_OK)
1931                 return 0;
1932
1933         psRetOUT->eError =
1934             PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
1935                                       pvSwapChain,
1936                                       psSetDispClassColKeyIN->ui32CKColour);
1937
1938         return 0;
1939 }
1940
1941 static int PVRSRVGetDCBuffersBW(u32 ui32BridgeID,
1942      struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
1943      struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
1944      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1945 {
1946         void *pvDispClassInfo;
1947         void *pvSwapChain;
1948         u32 i;
1949
1950         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1951                                  PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
1952
1953         NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc,
1954                                   PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1955
1956         psGetDispClassBuffersOUT->eError =
1957             PVRSRVLookupHandle(psPerProc->psHandleBase,
1958                                &pvDispClassInfo,
1959                                psGetDispClassBuffersIN->hDeviceKM,
1960                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1961         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1962                 return 0;
1963
1964         psGetDispClassBuffersOUT->eError =
1965             PVRSRVLookupHandle(psPerProc->psHandleBase,
1966                                &pvSwapChain,
1967                                psGetDispClassBuffersIN->hSwapChain,
1968                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1969         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1970                 return 0;
1971
1972         psGetDispClassBuffersOUT->eError =
1973             PVRSRVGetDCBuffersKM(pvDispClassInfo,
1974                                  pvSwapChain,
1975                                  &psGetDispClassBuffersOUT->ui32BufferCount,
1976                                  psGetDispClassBuffersOUT->ahBuffer);
1977         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1978                 return 0;
1979
1980         PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <=
1981                    PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1982
1983         for (i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++) {
1984                 void *hBufferExt;
1985
1986                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1987                                &hBufferExt,
1988                                psGetDispClassBuffersOUT->ahBuffer[i],
1989                                PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1990                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
1991                                        (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
1992                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
1993                                psGetDispClassBuffersIN->hSwapChain);
1994
1995                 psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
1996         }
1997
1998         COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError,
1999                                      psPerProc);
2000
2001         return 0;
2002 }
2003
2004 static int PVRSRVSwapToDCBufferBW(u32 ui32BridgeID,
2005       struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
2006       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2007       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2008 {
2009         void *pvDispClassInfo;
2010         void *pvSwapChainBuf;
2011
2012         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2013                                  PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
2014
2015         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2016                                         &pvDispClassInfo,
2017                                         psSwapDispClassBufferIN->hDeviceKM,
2018                                         PVRSRV_HANDLE_TYPE_DISP_INFO);
2019         if (psRetOUT->eError != PVRSRV_OK)
2020                 return 0;
2021
2022         psRetOUT->eError =
2023             PVRSRVLookupSubHandle(psPerProc->psHandleBase,
2024                                   &pvSwapChainBuf,
2025                                   psSwapDispClassBufferIN->hBuffer,
2026                                   PVRSRV_HANDLE_TYPE_DISP_BUFFER,
2027                                   psSwapDispClassBufferIN->hDeviceKM);
2028         if (psRetOUT->eError != PVRSRV_OK)
2029                 return 0;
2030
2031         psRetOUT->eError =
2032             PVRSRVSwapToDCBufferKM(pvDispClassInfo,
2033                                    pvSwapChainBuf,
2034                                    psSwapDispClassBufferIN->ui32SwapInterval,
2035                                    psSwapDispClassBufferIN->hPrivateTag,
2036                                    psSwapDispClassBufferIN->ui32ClipRectCount,
2037                                    psSwapDispClassBufferIN->sClipRect);
2038
2039         return 0;
2040 }
2041
2042 static int PVRSRVSwapToDCSystemBW(u32 ui32BridgeID,
2043       struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
2044       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2045       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2046 {
2047         void *pvDispClassInfo;
2048         void *pvSwapChain;
2049
2050         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2051                                  PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
2052
2053         psRetOUT->eError =
2054             PVRSRVLookupHandle(psPerProc->psHandleBase,
2055                                &pvDispClassInfo,
2056                                psSwapDispClassSystemIN->hDeviceKM,
2057                                PVRSRV_HANDLE_TYPE_DISP_INFO);
2058         if (psRetOUT->eError != PVRSRV_OK)
2059                 return 0;
2060
2061         psRetOUT->eError =
2062             PVRSRVLookupSubHandle(psPerProc->psHandleBase,
2063                                   &pvSwapChain,
2064                                   psSwapDispClassSystemIN->hSwapChain,
2065                                   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
2066                                   psSwapDispClassSystemIN->hDeviceKM);
2067         if (psRetOUT->eError != PVRSRV_OK)
2068                 return 0;
2069         psRetOUT->eError = PVRSRVSwapToDCSystemKM(pvDispClassInfo, pvSwapChain);
2070
2071         return 0;
2072 }
2073
2074 static int PVRSRVOpenBCDeviceBW(u32 ui32BridgeID,
2075    struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
2076    struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
2077    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2078 {
2079         void *hDevCookieInt;
2080         void *hBufClassInfo;
2081
2082         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2083                                  PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
2084
2085         NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc,
2086                                   1);
2087
2088         psOpenBufferClassDeviceOUT->eError =
2089             PVRSRVLookupHandle(psPerProc->psHandleBase,
2090                                &hDevCookieInt,
2091                                psOpenBufferClassDeviceIN->hDevCookie,
2092                                PVRSRV_HANDLE_TYPE_DEV_NODE);
2093         if (psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2094                 return 0;
2095
2096         psOpenBufferClassDeviceOUT->eError =
2097             PVRSRVOpenBCDeviceKM(psPerProc,
2098                                  psOpenBufferClassDeviceIN->ui32DeviceID,
2099                                  hDevCookieInt, &hBufClassInfo);
2100         if (psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2101                 return 0;
2102
2103         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2104                             &psOpenBufferClassDeviceOUT->hDeviceKM,
2105                             hBufClassInfo,
2106                             PVRSRV_HANDLE_TYPE_BUF_INFO,
2107                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2108
2109         COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError,
2110                                      psPerProc);
2111
2112         return 0;
2113 }
2114
2115 static int PVRSRVCloseBCDeviceBW(u32 ui32BridgeID,
2116    struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
2117    struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2118    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2119 {
2120         void *pvBufClassInfo;
2121
2122         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2123                                  PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
2124
2125         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2126                                &pvBufClassInfo,
2127                                psCloseBufferClassDeviceIN->hDeviceKM,
2128                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2129         if (psRetOUT->eError != PVRSRV_OK)
2130                 return 0;
2131
2132         psRetOUT->eError = PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
2133
2134         if (psRetOUT->eError != PVRSRV_OK)
2135                 return 0;
2136
2137         psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
2138                                                psCloseBufferClassDeviceIN->
2139                                                hDeviceKM,
2140                                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2141
2142         return 0;
2143 }
2144
2145 static int PVRSRVGetBCInfoBW(u32 ui32BridgeID,
2146    struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
2147    struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
2148    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2149 {
2150         void *pvBufClassInfo;
2151
2152         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2153                                  PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
2154
2155         psGetBufferClassInfoOUT->eError =
2156             PVRSRVLookupHandle(psPerProc->psHandleBase,
2157                                &pvBufClassInfo,
2158                                psGetBufferClassInfoIN->hDeviceKM,
2159                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2160         if (psGetBufferClassInfoOUT->eError != PVRSRV_OK)
2161                 return 0;
2162
2163         psGetBufferClassInfoOUT->eError =
2164             PVRSRVGetBCInfoKM(pvBufClassInfo,
2165                               &psGetBufferClassInfoOUT->sBufferInfo);
2166         return 0;
2167 }
2168
2169 static int PVRSRVGetBCBufferBW(u32 ui32BridgeID,
2170     struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
2171     struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
2172     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2173 {
2174         void *pvBufClassInfo;
2175         void *hBufferInt;
2176
2177         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2178                                  PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
2179
2180         NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc,
2181                                   1);
2182
2183         psGetBufferClassBufferOUT->eError =
2184             PVRSRVLookupHandle(psPerProc->psHandleBase,
2185                                &pvBufClassInfo,
2186                                psGetBufferClassBufferIN->hDeviceKM,
2187                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2188         if (psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2189                 return 0;
2190
2191         psGetBufferClassBufferOUT->eError =
2192             PVRSRVGetBCBufferKM(pvBufClassInfo,
2193                                 psGetBufferClassBufferIN->ui32BufferIndex,
2194                                 &hBufferInt);
2195
2196         if (psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2197                 return 0;
2198
2199         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2200                                &psGetBufferClassBufferOUT->hBuffer,
2201                                hBufferInt,
2202                                PVRSRV_HANDLE_TYPE_BUF_BUFFER,
2203                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
2204                                        (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
2205                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
2206                                psGetBufferClassBufferIN->hDeviceKM);
2207
2208         COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError,
2209                                      psPerProc);
2210
2211         return 0;
2212 }
2213
2214 static int PVRSRVAllocSharedSysMemoryBW(u32 ui32BridgeID,
2215           struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
2216           struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
2217           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2218 {
2219         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2220
2221         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2222                                  PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
2223
2224         NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1);
2225
2226         psAllocSharedSysMemOUT->eError =
2227             PVRSRVAllocSharedSysMemoryKM(psPerProc,
2228                                          psAllocSharedSysMemIN->ui32Flags,
2229                                          psAllocSharedSysMemIN->ui32Size,
2230                                          &psKernelMemInfo);
2231         if (psAllocSharedSysMemOUT->eError != PVRSRV_OK)
2232                 return 0;
2233
2234         OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
2235                  0, sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
2236
2237         psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
2238                     psKernelMemInfo->pvLinAddrKM;
2239
2240         psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = NULL;
2241         psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
2242                                         psKernelMemInfo->ui32Flags;
2243         psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize =
2244                                         psKernelMemInfo->ui32AllocSize;
2245         psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo =
2246                                         psKernelMemInfo->sMemBlk.hOSMemHandle;
2247
2248         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2249                          &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
2250                          psKernelMemInfo,
2251                          PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
2252                          PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2253
2254         COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc);
2255
2256         return 0;
2257 }
2258
2259 static int PVRSRVFreeSharedSysMemoryBW(u32 ui32BridgeID,
2260             struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
2261             struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
2262             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2263 {
2264         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2265
2266         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2267                                  PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
2268
2269         psFreeSharedSysMemOUT->eError =
2270             PVRSRVLookupHandle(psPerProc->psHandleBase,
2271                                (void **)&psKernelMemInfo,
2272                                psFreeSharedSysMemIN->psKernelMemInfo,
2273                                PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2274
2275         if (psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2276                 return 0;
2277
2278         psFreeSharedSysMemOUT->eError =
2279             PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
2280         if (psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2281                 return 0;
2282
2283         psFreeSharedSysMemOUT->eError =
2284             PVRSRVReleaseHandle(psPerProc->psHandleBase,
2285                                 psFreeSharedSysMemIN->psKernelMemInfo,
2286                                 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2287         return 0;
2288 }
2289
2290 static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID,
2291               struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
2292               struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
2293               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2294 {
2295         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2296         enum PVRSRV_HANDLE_TYPE eHandleType;
2297         void *hParent;
2298         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
2299
2300         NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2);
2301
2302         psMapMemInfoMemOUT->eError =
2303             PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
2304                                       (void **)&psKernelMemInfo, &eHandleType,
2305                                       psMapMemInfoMemIN->hKernelMemInfo);
2306         if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
2307                 return 0;
2308
2309         switch (eHandleType) {
2310         case PVRSRV_HANDLE_TYPE_MEM_INFO:
2311         case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
2312         case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
2313                 break;
2314         default:
2315                 psMapMemInfoMemOUT->eError = PVRSRV_ERROR_GENERIC;
2316                 return 0;
2317         }
2318
2319         psMapMemInfoMemOUT->eError =
2320             PVRSRVGetParentHandle(psPerProc->psHandleBase, &hParent,
2321                                   psMapMemInfoMemIN->hKernelMemInfo,
2322                                   eHandleType);
2323         if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
2324                 return 0;
2325         if (hParent == NULL)
2326                 hParent = psMapMemInfoMemIN->hKernelMemInfo;
2327
2328         OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
2329                  0, sizeof(psMapMemInfoMemOUT->sClientMemInfo));
2330
2331         psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
2332                                         psKernelMemInfo->pvLinAddrKM;
2333
2334         psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = NULL;
2335         psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
2336                                         psKernelMemInfo->sDevVAddr;
2337         psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
2338                                         psKernelMemInfo->ui32Flags;
2339         psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize =
2340                                         psKernelMemInfo->ui32AllocSize;
2341         psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo =
2342                                         psKernelMemInfo->sMemBlk.hOSMemHandle;
2343
2344         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2345                         &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
2346                         psKernelMemInfo,
2347                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
2348                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI, hParent);
2349
2350         if (psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) {
2351                 OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, 0,
2352                 sizeof(struct PVRSRV_CLIENT_SYNC_INFO));
2353                 psMapMemInfoMemOUT->psKernelSyncInfo = NULL;
2354         } else {
2355                 psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
2356                     psKernelMemInfo->psKernelSyncInfo->psSyncData;
2357                 psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
2358                     psKernelMemInfo->psKernelSyncInfo->
2359                                                     sWriteOpsCompleteDevVAddr;
2360                 psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
2361                     psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
2362
2363                 psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
2364                     psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->
2365                                                     sMemBlk.hOSMemHandle;
2366
2367                 psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo =
2368                     &psMapMemInfoMemOUT->sClientSyncInfo;
2369
2370                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2371                         &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
2372                         psKernelMemInfo->psKernelSyncInfo,
2373                         PVRSRV_HANDLE_TYPE_SYNC_INFO,
2374                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
2375                         psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
2376         }
2377
2378         COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc);
2379
2380         return 0;
2381 }
2382
2383 static int PVRSRVModifySyncOpsBW(u32 ui32BridgeID,
2384                  struct PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS *psModifySyncOpsIN,
2385                  struct PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS *psModifySyncOpsOUT,
2386                  struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2387 {
2388         void *hKernelSyncInfo;
2389         struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
2390
2391         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_SYNC_OPS);
2392
2393         psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2394                                         &hKernelSyncInfo,
2395                                         psModifySyncOpsIN->hKernelSyncInfo,
2396                                         PVRSRV_HANDLE_TYPE_SYNC_INFO);
2397         if (psModifySyncOpsOUT->eError != PVRSRV_OK)
2398                 return 0;
2399
2400         psKernelSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo;
2401
2402         /* We return PRE-INCREMENTED versions of all sync Op Values */
2403
2404         psModifySyncOpsOUT->ui32ReadOpsPending =
2405             psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
2406
2407         psModifySyncOpsOUT->ui32WriteOpsPending =
2408             psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
2409
2410         psModifySyncOpsOUT->ui32ReadOpsComplete =
2411             psKernelSyncInfo->psSyncData->ui32ReadOpsComplete;
2412
2413         psModifySyncOpsOUT->ui32WriteOpsComplete =
2414             psKernelSyncInfo->psSyncData->ui32WriteOpsComplete;
2415
2416         if (psModifySyncOpsIN->ui32ModifyFlags &
2417             PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC)
2418                 psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
2419
2420         if (psModifySyncOpsIN->ui32ModifyFlags &
2421             PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC)
2422                 psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
2423
2424         if (psModifySyncOpsIN->ui32ModifyFlags &
2425             PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC)
2426                 psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
2427
2428         if (psModifySyncOpsIN->ui32ModifyFlags &
2429             PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC)
2430                 psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
2431
2432         return 0;
2433 }
2434
2435 static int MMU_GetPDDevPAddrBW(u32 ui32BridgeID,
2436             struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN,
2437             struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT,
2438             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2439 {
2440         void *hDevMemContextInt;
2441
2442         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2443                                  PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR);
2444
2445         psGetMmuPDDevPAddrOUT->eError =
2446             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
2447                                psGetMmuPDDevPAddrIN->hDevMemContext,
2448                                PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
2449         if (psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK)
2450                 return 0;
2451
2452         psGetMmuPDDevPAddrOUT->sPDDevPAddr =
2453             BM_GetDeviceNode(hDevMemContextInt)->
2454             pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext
2455                               (hDevMemContextInt));
2456         if (psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr)
2457                 psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK;
2458         else
2459                 psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_GENERIC;
2460         return 0;
2461 }
2462
2463 int DummyBW(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut,
2464             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2465 {
2466 #if !defined(CONFIG_PVR_DEBUG_EXTRA)
2467         PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2468 #endif
2469         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2470         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
2471         PVR_UNREFERENCED_PARAMETER(psPerProc);
2472
2473 #if defined(DEBUG_BRIDGE_KM)
2474         PVR_DPF(PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu (%s) mapped to "
2475                  "Dummy Wrapper (probably not what you want!)",
2476                  __func__, ui32BridgeID,
2477                  g_BridgeDispatchTable[ui32BridgeID].pszIOCName);
2478 #else
2479         PVR_DPF(PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu mapped to "
2480                  "Dummy Wrapper (probably not what you want!)",
2481                  __func__, ui32BridgeID);
2482 #endif
2483         return -ENOTTY;
2484 }
2485
2486 void _SetDispatchTableEntry(u32 ui32Index, const char *pszIOCName,
2487                             int (*pfFunction)(u32 ui32BridgeID,
2488                                               void *psBridgeIn,
2489                                               void *psBridgeOut,
2490                                               struct PVRSRV_PER_PROCESS_DATA
2491                                                                    *psPerProc),
2492                             const char *pszFunctionName)
2493 {
2494         static u32 ui32PrevIndex = ~0UL;
2495 #if !defined(CONFIG_PVR_DEBUG_EXTRA)
2496         PVR_UNREFERENCED_PARAMETER(pszIOCName);
2497 #endif
2498 #if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
2499         PVR_UNREFERENCED_PARAMETER(pszFunctionName);
2500 #endif
2501
2502
2503         if (g_BridgeDispatchTable[ui32Index].pfFunction) {
2504 #if defined(DEBUG_BRIDGE_KM)
2505                 PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
2506                         "Adding dispatch table entry for %s "
2507                         "clobbers an existing entry for %s",
2508                          __func__, pszIOCName,
2509                          g_BridgeDispatchTable[ui32Index].pszIOCName);
2510 #else
2511                 PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
2512                         "Adding dispatch table entry for %s "
2513                         "clobbers an existing entry (index=%lu)",
2514                          __func__, pszIOCName, ui32Index);
2515 #endif
2516                 PVR_DPF(PVR_DBG_ERROR,
2517 "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.",
2518                          __func__);
2519         }
2520
2521         if ((ui32PrevIndex != ~0UL) &&
2522             ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
2523              (ui32Index <= ui32PrevIndex))) {
2524 #if defined(DEBUG_BRIDGE_KM)
2525                 PVR_DPF(PVR_DBG_WARNING,
2526                          "%s: There is a gap in the dispatch table "
2527                          "between indices %lu (%s) and %lu (%s)",
2528                          __func__, ui32PrevIndex,
2529                          g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
2530                          ui32Index, pszIOCName);
2531 #else
2532                 PVR_DPF(PVR_DBG_WARNING,
2533                          "%s: There is a gap in the dispatch table "
2534                         "between indices %u and %u (%s)",
2535                          __func__, (unsigned)ui32PrevIndex, (unsigned)ui32Index,
2536                          pszIOCName);
2537 #endif
2538                 PVR_DPF(PVR_DBG_ERROR,
2539                         "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE "
2540                         "may help debug this issue.",
2541                          __func__);
2542         }
2543
2544         g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
2545 #if defined(DEBUG_BRIDGE_KM)
2546         g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
2547         g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
2548         g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
2549         g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
2550 #endif
2551
2552         ui32PrevIndex = ui32Index;
2553 }
2554
2555 static int PVRSRVInitSrvConnectBW(u32 ui32BridgeID, void *psBridgeIn,
2556                                   struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2557                                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2558 {
2559         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2560
2561         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
2562         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2563
2564         if (!OSProcHasPrivSrvInit() ||
2565             PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) ||
2566             PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) {
2567                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
2568                 return 0;
2569         }
2570
2571         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
2572         psPerProc->bInitProcess = IMG_TRUE;
2573
2574         psRetOUT->eError = PVRSRV_OK;
2575
2576         return 0;
2577 }
2578
2579 static int PVRSRVInitSrvDisconnectBW(u32 ui32BridgeID,
2580              struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
2581              struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2582              struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2583 {
2584         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2585                                  PVRSRV_BRIDGE_INITSRV_DISCONNECT);
2586
2587         if (!psPerProc->bInitProcess) {
2588                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
2589                 return 0;
2590         }
2591
2592         psPerProc->bInitProcess = IMG_FALSE;
2593
2594         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
2595         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
2596
2597         psRetOUT->eError =
2598             PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
2599
2600         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL,
2601                                  (IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) &&
2602                                               (psInitSrvDisconnectIN->
2603                                                             bInitSuccesful))));
2604
2605         return 0;
2606 }
2607
2608 static int PVRSRVEventObjectWaitBW(u32 ui32BridgeID,
2609            struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
2610            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2611            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2612 {
2613         void *hOSEventKM;
2614
2615         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
2616
2617         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2618                                       &hOSEventKM,
2619                                       psEventObjectWaitIN->hOSEventKM,
2620                                       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2621
2622         if (psRetOUT->eError != PVRSRV_OK)
2623                 return 0;
2624
2625         psRetOUT->eError = OSEventObjectWait(hOSEventKM);
2626
2627         return 0;
2628 }
2629
2630 static int PVRSRVEventObjectOpenBW(u32 ui32BridgeID,
2631            struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
2632            struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
2633            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2634 {
2635
2636         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
2637
2638         NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1);
2639
2640         psEventObjectOpenOUT->eError =
2641             PVRSRVLookupHandle(psPerProc->psHandleBase,
2642                                &psEventObjectOpenIN->sEventObject.hOSEventKM,
2643                                psEventObjectOpenIN->sEventObject.hOSEventKM,
2644                                PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2645
2646         if (psEventObjectOpenOUT->eError != PVRSRV_OK)
2647                 return 0;
2648
2649         psEventObjectOpenOUT->eError =
2650             OSEventObjectOpen(&psEventObjectOpenIN->sEventObject,
2651                               &psEventObjectOpenOUT->hOSEvent);
2652
2653         if (psEventObjectOpenOUT->eError != PVRSRV_OK)
2654                 return 0;
2655
2656         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2657                             &psEventObjectOpenOUT->hOSEvent,
2658                             psEventObjectOpenOUT->hOSEvent,
2659                             PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
2660                             PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
2661
2662         COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc);
2663
2664         return 0;
2665 }
2666
2667 static int PVRSRVEventObjectCloseBW(u32 ui32BridgeID,
2668             struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
2669             struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2670             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2671 {
2672         void *hOSEventKM;
2673
2674         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2675                                  PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
2676
2677         psRetOUT->eError =
2678             PVRSRVLookupHandle(psPerProc->psHandleBase,
2679                                &psEventObjectCloseIN->sEventObject.hOSEventKM,
2680                                psEventObjectCloseIN->sEventObject.hOSEventKM,
2681                                PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2682         if (psRetOUT->eError != PVRSRV_OK)
2683                 return 0;
2684
2685         psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
2686                                 &hOSEventKM,
2687                                 psEventObjectCloseIN->hOSEventKM,
2688                                 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2689
2690         if (psRetOUT->eError != PVRSRV_OK)
2691                 return 0;
2692
2693         psRetOUT->eError =
2694             OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM);
2695
2696         return 0;
2697 }
2698
2699 enum PVRSRV_ERROR CommonBridgeInit(void)
2700 {
2701         u32 i;
2702
2703         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES,
2704                               PVRSRVEnumerateDevicesBW);
2705         SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO,
2706                               PVRSRVAcquireDeviceDataBW);
2707         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
2708         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT,
2709                               PVRSRVCreateDeviceMemContextBW);
2710         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT,
2711                               PVRSRVDestroyDeviceMemContextBW);
2712         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO,
2713                               PVRSRVGetDeviceMemHeapInfoBW);
2714         SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM,
2715                               PVRSRVAllocDeviceMemBW);
2716         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM,
2717                               PVRSRVFreeDeviceMemBW);
2718         SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM,
2719                               PVRSRVGetFreeDeviceMemBW);
2720         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
2721         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
2722         SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA,
2723                               PVRMMapOSMemHandleToMMapDataBW);
2724         SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
2725         SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES,
2726                               PVRSRVDisconnectBW);
2727         SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
2728         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
2729         SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM, DummyBW);
2730         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
2731         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
2732         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
2733         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY,
2734                               PVRSRVMapDeviceMemoryBW);
2735         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY,
2736                               PVRSRVUnmapDeviceMemoryBW);
2737         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY,
2738                               PVRSRVMapDeviceClassMemoryBW);
2739         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY,
2740                               PVRSRVUnmapDeviceClassMemoryBW);
2741         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
2742         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
2743         SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM,
2744                               PVRSRVExportDeviceMemBW);
2745         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA,
2746                               PVRMMapReleaseMMapDataBW);
2747         SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE_FLUSH_DRM,
2748                               PVRSRVCacheFlushDRIBW);
2749
2750         SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
2751         SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
2752         SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
2753
2754         SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
2755         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
2756         SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
2757
2758         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
2759
2760         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
2761         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
2762
2763
2764 #if defined(PDUMP)
2765         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
2766         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
2767         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
2768         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
2769         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
2770         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
2771         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
2772         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING,
2773                               PDumpIsCaptureFrameBW);
2774         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
2775         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, PDumpReadRegBW);
2776         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
2777         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
2778         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO,
2779                               PDumpDriverInfoBW);
2780         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_PDREG, PDumpPDRegBW);
2781         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR,
2782                               PDumpPDDevPAddrBW);
2783         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ,
2784                               PDumpCycleCountRegReadBW);
2785         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE,
2786                               PDumpStartInitPhaseBW);
2787         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE,
2788                               PDumpStopInitPhaseBW);
2789 #endif
2790
2791         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
2792
2793         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
2794
2795         SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE,
2796                               PVRSRVOpenDCDeviceBW);
2797         SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE,
2798                               PVRSRVCloseDCDeviceBW);
2799         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS,
2800                               PVRSRVEnumDCFormatsBW);
2801         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS,
2802                               PVRSRVEnumDCDimsBW);
2803         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER,
2804                               PVRSRVGetDCSystemBufferBW);
2805         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO,
2806                               PVRSRVGetDCInfoBW);
2807         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN,
2808                               PVRSRVCreateDCSwapChainBW);
2809         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN,
2810                               PVRSRVDestroyDCSwapChainBW);
2811         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT,
2812                               PVRSRVSetDCDstRectBW);
2813         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT,
2814                               PVRSRVSetDCSrcRectBW);
2815         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY,
2816                               PVRSRVSetDCDstColourKeyBW);
2817         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY,
2818                               PVRSRVSetDCSrcColourKeyBW);
2819         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS,
2820                               PVRSRVGetDCBuffersBW);
2821         SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER,
2822                               PVRSRVSwapToDCBufferBW);
2823         SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM,
2824                               PVRSRVSwapToDCSystemBW);
2825
2826         SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE,
2827                               PVRSRVOpenBCDeviceBW);
2828         SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE,
2829                               PVRSRVCloseBCDeviceBW);
2830         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO,
2831                               PVRSRVGetBCInfoBW);
2832         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER,
2833                               PVRSRVGetBCBufferBW);
2834
2835         SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY,
2836                               PVRSRVWrapExtMemoryBW);
2837         SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY,
2838                               PVRSRVUnwrapExtMemoryBW);
2839
2840         SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM,
2841                               PVRSRVAllocSharedSysMemoryBW);
2842         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM,
2843                               PVRSRVFreeSharedSysMemoryBW);
2844         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM,
2845                               PVRSRVMapMemInfoMemBW);
2846
2847         SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR,
2848                               MMU_GetPDDevPAddrBW);
2849
2850         SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT,
2851                               PVRSRVInitSrvConnectBW);
2852         SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT,
2853                               PVRSRVInitSrvDisconnectBW);
2854
2855         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT,
2856                               PVRSRVEventObjectWaitBW);
2857         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN,
2858                               PVRSRVEventObjectOpenBW);
2859         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE,
2860                               PVRSRVEventObjectCloseBW);
2861
2862         SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_SYNC_OPS,
2863                               PVRSRVModifySyncOpsBW);
2864
2865         SetSGXDispatchTableEntry();
2866
2867         for (i = 0; i < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT; i++)
2868                 if (!g_BridgeDispatchTable[i].pfFunction) {
2869                         g_BridgeDispatchTable[i].pfFunction = DummyBW;
2870 #if defined(DEBUG_BRIDGE_KM)
2871                         g_BridgeDispatchTable[i].pszIOCName =
2872                                                     "_PVRSRV_BRIDGE_DUMMY";
2873                         g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
2874                         g_BridgeDispatchTable[i].ui32CallCount = 0;
2875                         g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
2876                         g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
2877 #endif
2878                 }
2879
2880         return PVRSRV_OK;
2881 }
2882
2883 static int bridged_check_cmd(u32 cmd_id)
2884 {
2885         if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) {
2886                 if (!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) {
2887                         PVR_DPF(PVR_DBG_ERROR,
2888                         "%s: Initialisation failed.  Driver unusable.",
2889                                  __func__);
2890                         return 1;
2891                 }
2892         } else {
2893                 if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) {
2894                         PVR_DPF(PVR_DBG_ERROR,
2895                                  "%s: Initialisation is in progress",
2896                                  __func__);
2897                         return 1;
2898                 } else {
2899                         switch (cmd_id) {
2900                         case PVRSRV_GET_BRIDGE_ID(
2901                                 PVRSRV_BRIDGE_CONNECT_SERVICES):
2902                         case PVRSRV_GET_BRIDGE_ID(
2903                                 PVRSRV_BRIDGE_DISCONNECT_SERVICES):
2904                         case PVRSRV_GET_BRIDGE_ID(
2905                                 PVRSRV_BRIDGE_INITSRV_CONNECT):
2906                         case PVRSRV_GET_BRIDGE_ID(
2907                                 PVRSRV_BRIDGE_INITSRV_DISCONNECT):
2908                                 break;
2909                         default:
2910                                 PVR_DPF(PVR_DBG_ERROR,
2911                         "%s: Driver initialisation not completed yet.",
2912                                          __func__);
2913                                 return 1;
2914                         }
2915                 }
2916         }
2917
2918         return 0;
2919 }
2920
2921 static int bridged_ioctl(struct file *filp, u32 cmd, void *in, void *out,
2922                          size_t in_size,
2923                          struct PVRSRV_PER_PROCESS_DATA *per_proc)
2924 {
2925         int err = -EFAULT;
2926
2927         switch (PVRSRV_IOWR(cmd)) {
2928         case PVRSRV_BRIDGE_ENUM_DEVICES:
2929                 err = PVRSRVEnumerateDevicesBW(cmd, in, out, per_proc);
2930                 break;
2931         case PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO:
2932                 err = PVRSRVAcquireDeviceDataBW(cmd, in, out, per_proc);
2933                 break;
2934         case PVRSRV_BRIDGE_RELEASE_DEVICEINFO:
2935                 err = DummyBW(cmd, in, out, per_proc);
2936                 break;
2937         case PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT:
2938                 err = PVRSRVCreateDeviceMemContextBW(cmd, in, out, per_proc);
2939                 break;
2940         case PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT:
2941                 err = PVRSRVDestroyDeviceMemContextBW(cmd, in, out, per_proc);
2942                 break;
2943         case PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO:
2944                 err = PVRSRVGetDeviceMemHeapInfoBW(cmd, in, out, per_proc);
2945                 break;
2946         case PVRSRV_BRIDGE_ALLOC_DEVICEMEM:
2947                 err = PVRSRVAllocDeviceMemBW(cmd, in, out, per_proc);
2948                 break;
2949         case PVRSRV_BRIDGE_FREE_DEVICEMEM:
2950                 err = PVRSRVFreeDeviceMemBW(cmd, in, out, per_proc);
2951                 break;
2952         case PVRSRV_BRIDGE_GETFREE_DEVICEMEM:
2953                 err = PVRSRVGetFreeDeviceMemBW(cmd, in, out, per_proc);
2954                 break;
2955
2956         case PVRSRV_BRIDGE_CREATE_COMMANDQUEUE:
2957         case PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE:
2958                 err = DummyBW(cmd, in, out, per_proc);
2959                 break;
2960
2961         case PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA:
2962                 err = PVRMMapOSMemHandleToMMapDataBW(cmd, in, out, per_proc);
2963                 break;
2964         case PVRSRV_BRIDGE_CONNECT_SERVICES:
2965                 err = PVRSRVConnectBW(cmd, in, out, per_proc);
2966                 break;
2967         case PVRSRV_BRIDGE_DISCONNECT_SERVICES:
2968                 err = PVRSRVDisconnectBW(cmd, in, out, per_proc);
2969                 break;
2970
2971         case PVRSRV_BRIDGE_WRAP_DEVICE_MEM:
2972         case PVRSRV_BRIDGE_GET_DEVICEMEMINFO:
2973         case PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM:
2974         case PVRSRV_BRIDGE_FREE_DEV_VIRTMEM:
2975         case PVRSRV_BRIDGE_MAP_EXT_MEMORY:
2976         case PVRSRV_BRIDGE_UNMAP_EXT_MEMORY:
2977                 err = DummyBW(cmd, in, out, per_proc);
2978                 break;
2979
2980         case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
2981                 err = PVRSRVMapDeviceMemoryBW(cmd, in, out, per_proc);
2982                 break;
2983         case PVRSRV_BRIDGE_UNMAP_DEV_MEMORY:
2984                 err = PVRSRVUnmapDeviceMemoryBW(cmd, in, out, per_proc);
2985                 break;
2986         case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
2987                 err = PVRSRVMapDeviceClassMemoryBW(cmd, in, out, per_proc);
2988                 break;
2989         case PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY:
2990                 err = PVRSRVUnmapDeviceClassMemoryBW(cmd, in, out, per_proc);
2991                 break;
2992
2993         case PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER:
2994         case PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER:
2995                 err = DummyBW(cmd, in, out, per_proc);
2996                 break;
2997
2998         case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
2999                 err = PVRSRVExportDeviceMemBW(cmd, in, out, per_proc);
3000                 break;
3001         case PVRSRV_BRIDGE_RELEASE_MMAP_DATA:
3002                 err = PVRMMapReleaseMMapDataBW(cmd, in, out, per_proc);
3003                 break;
3004         case PVRSRV_BRIDGE_CACHE_FLUSH_DRM:
3005                 err = PVRSRVCacheFlushDRIBW(cmd, in, out, per_proc);
3006                 break;
3007
3008         case PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT:
3009         case PVRSRV_BRIDGE_REGISTER_SIM_PROCESS:
3010         case PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS:
3011         case PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE:
3012         case PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE:
3013         case PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP:
3014         case PVRSRV_BRIDGE_GET_FB_STATS:
3015                 err = DummyBW(cmd, in, out, per_proc);
3016                 break;
3017
3018         case PVRSRV_BRIDGE_GET_MISC_INFO:
3019                 err = PVRSRVGetMiscInfoBW(cmd, in, out, per_proc);
3020                 break;
3021         case PVRSRV_BRIDGE_RELEASE_MISC_INFO:
3022                 err = DummyBW(cmd, in, out, per_proc);
3023                 break;
3024
3025 #if defined(PDUMP)
3026         case PVRSRV_BRIDGE_PDUMP_INIT:
3027                 err = DummyBW(cmd, in, out, per_proc);
3028                 break;
3029         case PVRSRV_BRIDGE_PDUMP_MEMPOL:
3030                 err = PDumpMemPolBW(cmd, in, out, per_proc);
3031                 break;
3032         case PVRSRV_BRIDGE_PDUMP_DUMPMEM:
3033                 err = PDumpMemBW(cmd, in, out, per_proc);
3034                 break;
3035         case PVRSRV_BRIDGE_PDUMP_REG:
3036                 err = PDumpRegWithFlagsBW(cmd, in, out, per_proc);
3037                 break;
3038         case PVRSRV_BRIDGE_PDUMP_REGPOL:
3039                 err = PDumpRegPolBW(cmd, in, out, per_proc);
3040                 break;
3041         case PVRSRV_BRIDGE_PDUMP_COMMENT:
3042                 err = PDumpCommentBW(cmd, in, out, per_proc);
3043                 break;
3044         case PVRSRV_BRIDGE_PDUMP_SETFRAME:
3045                 err = PDumpSetFrameBW(cmd, in, out, per_proc);
3046                 break;
3047         case PVRSRV_BRIDGE_PDUMP_ISCAPTURING:
3048                 err = PDumpIsCaptureFrameBW(cmd, in, out, per_proc);
3049                 break;
3050         case PVRSRV_BRIDGE_PDUMP_DUMPBITMAP:
3051                 err = PDumpBitmapBW(cmd, in, out, per_proc);
3052                 break;
3053         case PVRSRV_BRIDGE_PDUMP_DUMPREADREG:
3054                 err = PDumpReadRegBW(cmd, in, out, per_proc);
3055                 break;
3056         case PVRSRV_BRIDGE_PDUMP_SYNCPOL:
3057                 err = PDumpSyncPolBW(cmd, in, out, per_proc);
3058                 break;
3059         case PVRSRV_BRIDGE_PDUMP_DUMPSYNC:
3060                 err = PDumpSyncDumpBW(cmd, in, out, per_proc);
3061                 break;
3062         case PVRSRV_BRIDGE_PDUMP_DRIVERINFO:
3063                 err = PDumpDriverInfoBW(cmd, in, out, per_proc);
3064                 break;
3065         case PVRSRV_BRIDGE_PDUMP_PDREG:
3066                 err = PDumpPDRegBW(cmd, in, out, per_proc);
3067                 break;
3068         case PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR:
3069                 err = PDumpPDDevPAddrBW(cmd, in, out, per_proc);
3070                 break;
3071         case PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ:
3072                 err = PDumpCycleCountRegReadBW(cmd, in, out, per_proc);
3073                 break;
3074         case PVRSRV_BRIDGE_PDUMP_STARTINITPHASE:
3075                 err = PDumpStartInitPhaseBW(cmd, in, out, per_proc);
3076                 break;
3077         case PVRSRV_BRIDGE_PDUMP_STOPINITPHASE:
3078                 err = PDumpStopInitPhaseBW(cmd, in, out, per_proc);
3079                 break;
3080 #endif
3081
3082         case PVRSRV_BRIDGE_GET_OEMJTABLE:
3083                 err = DummyBW(cmd, in, out, per_proc);
3084                 break;
3085
3086         case PVRSRV_BRIDGE_ENUM_CLASS:
3087                 err = PVRSRVEnumerateDCBW(cmd, in, out, per_proc);
3088                 break;
3089
3090         case PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE:
3091                 err = PVRSRVOpenDCDeviceBW(cmd, in, out, per_proc);
3092                 break;
3093         case PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE:
3094                 err = PVRSRVCloseDCDeviceBW(cmd, in, out, per_proc);
3095                 break;
3096         case PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS:
3097                 err = PVRSRVEnumDCFormatsBW(cmd, in, out, per_proc);
3098                 break;
3099         case PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS:
3100                 err = PVRSRVEnumDCDimsBW(cmd, in, out, per_proc);
3101                 break;
3102         case PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER:
3103                 err = PVRSRVGetDCSystemBufferBW(cmd, in, out, per_proc);
3104                 break;
3105         case PVRSRV_BRIDGE_GET_DISPCLASS_INFO:
3106                 err = PVRSRVGetDCInfoBW(cmd, in, out, per_proc);
3107                 break;
3108         case PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN:
3109                 err = PVRSRVCreateDCSwapChainBW(cmd, in, out, per_proc);
3110                 break;
3111         case PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN:
3112                 err = PVRSRVDestroyDCSwapChainBW(cmd, in, out, per_proc);
3113                 break;
3114         case PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT:
3115                 err = PVRSRVSetDCDstRectBW(cmd, in, out, per_proc);
3116                 break;
3117         case PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT:
3118                 err = PVRSRVSetDCSrcRectBW(cmd, in, out, per_proc);
3119                 break;
3120         case PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY:
3121                 err = PVRSRVSetDCDstColourKeyBW(cmd, in, out, per_proc);
3122                 break;
3123         case PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY:
3124                 err = PVRSRVSetDCSrcColourKeyBW(cmd, in, out, per_proc);
3125                 break;
3126         case PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS:
3127                 err = PVRSRVGetDCBuffersBW(cmd, in, out, per_proc);
3128                 break;
3129         case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER:
3130                 err = PVRSRVSwapToDCBufferBW(cmd, in, out, per_proc);
3131                 break;
3132         case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM:
3133                 err = PVRSRVSwapToDCSystemBW(cmd, in, out, per_proc);
3134                 break;
3135
3136         case PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE:
3137                 err = PVRSRVOpenBCDeviceBW(cmd, in, out, per_proc);
3138                 break;
3139         case PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE:
3140                 err = PVRSRVCloseBCDeviceBW(cmd, in, out, per_proc);
3141                 break;
3142         case PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO:
3143                 err = PVRSRVGetBCInfoBW(cmd, in, out, per_proc);
3144                 break;
3145         case PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER:
3146                 err = PVRSRVGetBCBufferBW(cmd, in, out, per_proc);
3147                 break;
3148
3149         case PVRSRV_BRIDGE_WRAP_EXT_MEMORY:
3150                 err = PVRSRVWrapExtMemoryBW(cmd, in, out, per_proc);
3151                 break;
3152         case PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY:
3153                 err = PVRSRVUnwrapExtMemoryBW(cmd, in, out, per_proc);
3154                 break;
3155
3156         case PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM:
3157                 err = PVRSRVAllocSharedSysMemoryBW(cmd, in, out, per_proc);
3158                 break;
3159         case PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM:
3160                 err = PVRSRVFreeSharedSysMemoryBW(cmd, in, out, per_proc);
3161                 break;
3162         case PVRSRV_BRIDGE_MAP_MEMINFO_MEM:
3163                 err = PVRSRVMapMemInfoMemBW(cmd, in, out, per_proc);
3164                 break;
3165
3166         case PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR:
3167                 err = MMU_GetPDDevPAddrBW(cmd, in, out, per_proc);
3168                 break;
3169
3170         case PVRSRV_BRIDGE_INITSRV_CONNECT:
3171                 err = PVRSRVInitSrvConnectBW(cmd, in, out, per_proc);
3172                 break;
3173         case PVRSRV_BRIDGE_INITSRV_DISCONNECT:
3174                 err = PVRSRVInitSrvDisconnectBW(cmd, in, out, per_proc);
3175                 break;
3176
3177         case PVRSRV_BRIDGE_EVENT_OBJECT_WAIT:
3178                 err = PVRSRVEventObjectWaitBW(cmd, in, out, per_proc);
3179                 break;
3180         case PVRSRV_BRIDGE_EVENT_OBJECT_OPEN:
3181                 err = PVRSRVEventObjectOpenBW(cmd, in, out, per_proc);
3182                 break;
3183         case PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE:
3184                 err = PVRSRVEventObjectCloseBW(cmd, in, out, per_proc);
3185                 break;
3186
3187         case PVRSRV_BRIDGE_MODIFY_SYNC_OPS:
3188                 err = PVRSRVModifySyncOpsBW(cmd, in, out, per_proc);
3189                 break;
3190
3191         case PVRSRV_BRIDGE_SGX_GETCLIENTINFO:
3192                 err = SGXGetClientInfoBW(cmd, in, out, per_proc);
3193                 break;
3194         case PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO:
3195                 err = SGXReleaseClientInfoBW(cmd, in, out, per_proc);
3196                 break;
3197         case PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO:
3198                 err = SGXGetInternalDevInfoBW(cmd, in, out, per_proc);
3199                 break;
3200         case PVRSRV_BRIDGE_SGX_DOKICK:
3201                 err = SGXDoKickBW(cmd, in, out, in_size, per_proc);
3202                 break;
3203
3204         case PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR:
3205         case PVRSRV_BRIDGE_SGX_READREGISTRYDWORD:
3206         case PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND:
3207                 err = DummyBW(cmd, in, out, per_proc);
3208                 break;
3209
3210         case PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE:
3211                 err = SGX2DQueryBlitsCompleteBW(filp, cmd, in, out, per_proc);
3212                 break;
3213
3214         case PVRSRV_BRIDGE_SGX_GETMMUPDADDR:
3215                 err = DummyBW(cmd, in, out, per_proc);
3216                 break;
3217
3218         case PVRSRV_BRIDGE_SGX_SUBMITTRANSFER:
3219                 err = SGXSubmitTransferBW(cmd, in, out, per_proc);
3220                 break;
3221         case PVRSRV_BRIDGE_SGX_GETMISCINFO:
3222                 err = SGXGetMiscInfoBW(cmd, in, out, per_proc);
3223                 break;
3224         case PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT:
3225                 err = SGXGetInfoForSrvinitBW(cmd, in, out, per_proc);
3226                 break;
3227         case PVRSRV_BRIDGE_SGX_DEVINITPART2:
3228                 err = SGXDevInitPart2BW(cmd, in, out, per_proc);
3229                 break;
3230
3231         case PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC:
3232                 err = SGXFindSharedPBDescBW(cmd, in, out, per_proc);
3233                 break;
3234         case PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC:
3235                 err = SGXUnrefSharedPBDescBW(cmd, in, out, per_proc);
3236                 break;
3237         case PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:
3238                 err = SGXAddSharedPBDescBW(cmd, in, out, per_proc);
3239                 break;
3240         case PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT:
3241                 err = SGXRegisterHWRenderContextBW(cmd, in, out, per_proc);
3242                 break;
3243         case PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET:
3244                 err = SGXFlushHWRenderTargetBW(cmd, in, out, per_proc);
3245                 break;
3246         case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT:
3247                 err = SGXUnregisterHWRenderContextBW(cmd, in, out, per_proc);
3248                 break;
3249         case PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT:
3250                 err = SGXRegisterHWTransferContextBW(cmd, in, out, per_proc);
3251                 break;
3252         case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT:
3253                 err = SGXUnregisterHWTransferContextBW(cmd, in, out, per_proc);
3254                 break;
3255
3256         case PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS:
3257                 err = SGXReadDiffCountersBW(cmd, in, out, per_proc);
3258                 break;
3259         case PVRSRV_BRIDGE_SGX_READ_HWPERF_CB:
3260                 err = SGXReadHWPerfCBBW(cmd, in, out, per_proc);
3261                 break;
3262
3263         case PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES:
3264                 err = SGXScheduleProcessQueuesBW(cmd, in, out, per_proc);
3265                 break;
3266
3267 #if defined(PDUMP)
3268         case PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY:
3269                 err = SGXPDumpBufferArrayBW(cmd, in, out, per_proc);
3270                 break;
3271         case PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS:
3272                 err = SGXPDump3DSignatureRegistersBW(cmd, in, out, per_proc);
3273                 break;
3274         case PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS:
3275                 err = SGXPDumpCounterRegistersBW(cmd, in, out, per_proc);
3276                 break;
3277         case PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS:
3278                 err = SGXPDumpTASignatureRegistersBW(cmd, in, out, per_proc);
3279                 break;
3280         case PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB:
3281                 err = SGXPDumpHWPerfCBBW(cmd, in, out, per_proc);
3282                 break;
3283 #endif
3284
3285         default:
3286                 PVR_DPF(PVR_DBG_ERROR, "%s: cmd = %d is out if range!",
3287                         __func__, cmd);
3288        }
3289
3290        return err;
3291 }
3292
3293 int BridgedDispatchKM(struct file *filp, struct PVRSRV_PER_PROCESS_DATA *pd,
3294                       struct PVRSRV_BRIDGE_PACKAGE *pkg)
3295 {
3296
3297         void *in;
3298         void *out;
3299         u32 bid = pkg->ui32BridgeID;
3300         int err = -EFAULT;
3301         struct SYS_DATA *psSysData;
3302
3303 #if defined(DEBUG_BRIDGE_KM)
3304         g_BridgeDispatchTable[bid].ui32CallCount++;
3305         g_BridgeGlobalStats.ui32IOCTLCount++;
3306 #endif
3307         if (!pd->bInitProcess && bridged_check_cmd(bid))
3308                 goto return_fault;
3309
3310         if (SysAcquireData(&psSysData) != PVRSRV_OK)
3311                 goto return_fault;
3312
3313         in = ((struct ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
3314         out = (void *)((u8 *)in + PVRSRV_MAX_BRIDGE_IN_SIZE);
3315
3316         if (pkg->ui32InBufferSize > 0 &&
3317             CopyFromUserWrapper(pd, bid, in, pkg->pvParamIn,
3318                                 pkg->ui32InBufferSize) != PVRSRV_OK)
3319                 goto return_fault;
3320
3321         if (bid >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) {
3322                 PVR_DPF(PVR_DBG_ERROR,
3323                          "%s: ui32BridgeID = %d is out if range!", __func__,
3324                          bid);
3325                 goto return_fault;
3326         }
3327
3328         err = bridged_ioctl(filp, bid, in, out, pkg->ui32InBufferSize, pd);
3329
3330         if (err < 0)
3331                 goto return_fault;
3332
3333         if (CopyToUserWrapper(pd, bid, pkg->pvParamOut, out,
3334                               pkg->ui32OutBufferSize) != PVRSRV_OK)
3335                 goto return_fault;
3336
3337         err = 0;
3338 return_fault:
3339         ReleaseHandleBatch(pd);
3340         return err;
3341 }