gpu: pvr: pdump: remove lastframe support
[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                           MAKEUNIQUETAG(pvMemInfo));
1136
1137         return 0;
1138 }
1139
1140 static int PDumpMemBW(u32 ui32BridgeID,
1141            struct PVRSRV_BRIDGE_IN_PDUMP_DUMPMEM *psPDumpMemDumpIN,
1142            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1143            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1144 {
1145         void *pvMemInfo;
1146
1147         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPMEM);
1148
1149         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1150                                         &pvMemInfo,
1151                                         psPDumpMemDumpIN->psKernelMemInfo,
1152                                         PVRSRV_HANDLE_TYPE_MEM_INFO);
1153         if (psRetOUT->eError != PVRSRV_OK)
1154                 return 0;
1155
1156         psRetOUT->eError = PDumpMemUM(psPerProc, psPDumpMemDumpIN->pvAltLinAddr,
1157                                        psPDumpMemDumpIN->pvLinAddr,
1158                                        pvMemInfo, psPDumpMemDumpIN->ui32Offset,
1159                                        psPDumpMemDumpIN->ui32Bytes,
1160                                        psPDumpMemDumpIN->ui32Flags,
1161                                                       MAKEUNIQUETAG(pvMemInfo));
1162
1163         return 0;
1164 }
1165
1166 static int PDumpBitmapBW(u32 ui32BridgeID,
1167               struct PVRSRV_BRIDGE_IN_PDUMP_BITMAP *psPDumpBitmapIN,
1168               struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1169               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1170 {
1171         PVR_UNREFERENCED_PARAMETER(psPerProc);
1172         PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
1173
1174         psRetOUT->eError = PDumpBitmapKM(&psPDumpBitmapIN->szFileName[0],
1175                           psPDumpBitmapIN->ui32FileOffset,
1176                           psPDumpBitmapIN->ui32Width,
1177                           psPDumpBitmapIN->ui32Height,
1178                           psPDumpBitmapIN->ui32StrideInBytes,
1179                           psPDumpBitmapIN->sDevBaseAddr,
1180                           psPDumpBitmapIN->ui32Size,
1181                           psPDumpBitmapIN->ePixelFormat,
1182                           psPDumpBitmapIN->eMemFormat,
1183                           psPDumpBitmapIN->ui32Flags);
1184
1185         return 0;
1186 }
1187
1188 static int PDumpSyncDumpBW(u32 ui32BridgeID,
1189                 struct PVRSRV_BRIDGE_IN_PDUMP_DUMPSYNC *psPDumpSyncDumpIN,
1190                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1191                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1192 {
1193         u32 ui32Bytes = psPDumpSyncDumpIN->ui32Bytes;
1194         void *pvSyncInfo;
1195
1196         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_DUMPSYNC);
1197
1198         psRetOUT->eError =
1199             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1200                                psPDumpSyncDumpIN->psKernelSyncInfo,
1201                                PVRSRV_HANDLE_TYPE_SYNC_INFO);
1202         if (psRetOUT->eError != PVRSRV_OK)
1203                 return 0;
1204
1205         psRetOUT->eError =
1206             PDumpMemUM(psPerProc, psPDumpSyncDumpIN->pvAltLinAddr, NULL,
1207                         ((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->
1208                                                         psSyncDataMemInfoKM,
1209                         psPDumpSyncDumpIN->ui32Offset, ui32Bytes, 0,
1210                         MAKEUNIQUETAG(((struct PVRSRV_KERNEL_SYNC_INFO *)
1211                                             pvSyncInfo)->psSyncDataMemInfoKM));
1212
1213         return 0;
1214 }
1215
1216 static int PDumpSyncPolBW(u32 ui32BridgeID,
1217                struct PVRSRV_BRIDGE_IN_PDUMP_SYNCPOL *psPDumpSyncPolIN,
1218                struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1219                struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1220 {
1221         u32 ui32Offset;
1222         void *pvSyncInfo;
1223
1224         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_SYNCPOL);
1225
1226         psRetOUT->eError =
1227             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSyncInfo,
1228                                psPDumpSyncPolIN->psKernelSyncInfo,
1229                                PVRSRV_HANDLE_TYPE_SYNC_INFO);
1230         if (psRetOUT->eError != PVRSRV_OK)
1231                 return 0;
1232
1233         if (psPDumpSyncPolIN->bIsRead)
1234                 ui32Offset = offsetof(struct PVRSRV_SYNC_DATA,
1235                                       ui32ReadOpsComplete);
1236         else
1237                 ui32Offset = offsetof(struct PVRSRV_SYNC_DATA,
1238                                       ui32WriteOpsComplete);
1239
1240         psRetOUT->eError =
1241             PDumpMemPolKM(((struct PVRSRV_KERNEL_SYNC_INFO *)pvSyncInfo)->
1242                           psSyncDataMemInfoKM, ui32Offset,
1243                           psPDumpSyncPolIN->ui32Value,
1244                           psPDumpSyncPolIN->ui32Mask, PDUMP_POLL_OPERATOR_EQUAL,
1245                           MAKEUNIQUETAG(((struct PVRSRV_KERNEL_SYNC_INFO *)
1246                                           pvSyncInfo)->psSyncDataMemInfoKM));
1247
1248         return 0;
1249 }
1250
1251 static int PDumpPDRegBW(u32 ui32BridgeID,
1252              struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDREG *psPDumpPDRegDumpIN,
1253              struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1254              struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1255 {
1256         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_PDUMP_PDREG);
1257         PVR_UNREFERENCED_PARAMETER(psPerProc);
1258
1259         PDumpPDReg(psPDumpPDRegDumpIN->sHWReg.ui32RegAddr,
1260                    psPDumpPDRegDumpIN->sHWReg.ui32RegVal, PDUMP_PD_UNIQUETAG);
1261
1262         psRetOUT->eError = PVRSRV_OK;
1263         return 0;
1264 }
1265
1266 static int PDumpCycleCountRegReadBW(u32 ui32BridgeID,
1267                 struct PVRSRV_BRIDGE_IN_PDUMP_CYCLE_COUNT_REG_READ
1268                                         *psPDumpCycleCountRegReadIN,
1269                 struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1270                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1271 {
1272         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1273                                  PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ);
1274         PVR_UNREFERENCED_PARAMETER(psPerProc);
1275
1276         PDumpCycleCountRegRead(psPDumpCycleCountRegReadIN->ui32RegOffset);
1277
1278         psRetOUT->eError = PVRSRV_OK;
1279
1280         return 0;
1281 }
1282
1283 static int PDumpPDDevPAddrBW(u32 ui32BridgeID,
1284           struct PVRSRV_BRIDGE_IN_PDUMP_DUMPPDDEVPADDR *psPDumpPDDevPAddrIN,
1285           struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1286           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1287 {
1288         void *pvMemInfo;
1289
1290         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1291                                  PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR);
1292
1293         psRetOUT->eError =
1294             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvMemInfo,
1295                                psPDumpPDDevPAddrIN->hKernelMemInfo,
1296                                PVRSRV_HANDLE_TYPE_MEM_INFO);
1297         if (psRetOUT->eError != PVRSRV_OK)
1298                 return 0;
1299
1300         psRetOUT->eError =
1301             PDumpPDDevPAddrKM((struct PVRSRV_KERNEL_MEM_INFO *)pvMemInfo,
1302                               psPDumpPDDevPAddrIN->ui32Offset,
1303                               psPDumpPDDevPAddrIN->sPDDevPAddr,
1304                               MAKEUNIQUETAG(pvMemInfo), PDUMP_PD_UNIQUETAG);
1305         return 0;
1306 }
1307
1308 #endif
1309
1310 static int PVRSRVGetMiscInfoBW(u32 ui32BridgeID,
1311                     struct PVRSRV_BRIDGE_IN_GET_MISC_INFO *psGetMiscInfoIN,
1312                     struct PVRSRV_BRIDGE_OUT_GET_MISC_INFO *psGetMiscInfoOUT,
1313                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1314 {
1315         enum PVRSRV_ERROR eError;
1316
1317         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_GET_MISC_INFO);
1318
1319         OSMemCopy(&psGetMiscInfoOUT->sMiscInfo, &psGetMiscInfoIN->sMiscInfo,
1320                   sizeof(struct PVRSRV_MISC_INFO));
1321
1322         if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1323                 PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) &&
1324             ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1325                 PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) {
1326
1327                 psGetMiscInfoOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1328                 return 0;
1329         }
1330
1331         if (((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1332                 PVRSRV_MISC_INFO_MEMSTATS_PRESENT) != 0) ||
1333             ((psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1334                 PVRSRV_MISC_INFO_DDKVERSION_PRESENT) != 0)) {
1335
1336                 ASSIGN_AND_EXIT_ON_ERROR(
1337                         psGetMiscInfoOUT->eError,
1338                         OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
1339                            psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1340                            (void **)&psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1341                            NULL));
1342
1343                 psGetMiscInfoOUT->eError =
1344                     PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1345
1346                 eError = CopyToUserWrapper(psPerProc, ui32BridgeID,
1347                                 (void __force __user *)
1348                                         psGetMiscInfoIN->sMiscInfo.pszMemoryStr,
1349                                 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1350                                 psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen);
1351
1352                 OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP,
1353                           psGetMiscInfoOUT->sMiscInfo.ui32MemoryStrLen,
1354                           (void *)psGetMiscInfoOUT->sMiscInfo.pszMemoryStr,
1355                           NULL);
1356
1357                 psGetMiscInfoOUT->sMiscInfo.pszMemoryStr =
1358                                         psGetMiscInfoIN->sMiscInfo.pszMemoryStr;
1359
1360                 if (eError != PVRSRV_OK) {
1361                         PVR_DPF(PVR_DBG_ERROR,
1362                                  "PVRSRVGetMiscInfoBW Error copy to user");
1363                         return -EFAULT;
1364                 }
1365         } else {
1366                 psGetMiscInfoOUT->eError =
1367                             PVRSRVGetMiscInfoKM(&psGetMiscInfoOUT->sMiscInfo);
1368         }
1369
1370         if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1371                 return 0;
1372
1373         if (psGetMiscInfoIN->sMiscInfo.ui32StateRequest &
1374             PVRSRV_MISC_INFO_GLOBALEVENTOBJECT_PRESENT) {
1375                 psGetMiscInfoOUT->eError =
1376                     PVRSRVAllocHandle(psPerProc->psHandleBase,
1377                                       &psGetMiscInfoOUT->sMiscInfo.
1378                                               sGlobalEventObject.hOSEventKM,
1379                                       psGetMiscInfoOUT->sMiscInfo.
1380                                               sGlobalEventObject.hOSEventKM,
1381                                       PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT,
1382                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1383
1384                 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1385                         return 0;
1386         }
1387
1388         if (psGetMiscInfoOUT->sMiscInfo.hSOCTimerRegisterOSMemHandle) {
1389                 psGetMiscInfoOUT->eError =
1390                     PVRSRVAllocHandle(psPerProc->psHandleBase,
1391                                       &psGetMiscInfoOUT->sMiscInfo.
1392                                               hSOCTimerRegisterOSMemHandle,
1393                                       psGetMiscInfoOUT->sMiscInfo.
1394                                               hSOCTimerRegisterOSMemHandle,
1395                                       PVRSRV_HANDLE_TYPE_SOC_TIMER,
1396                                       PVRSRV_HANDLE_ALLOC_FLAG_SHARED);
1397
1398                 if (psGetMiscInfoOUT->eError != PVRSRV_OK)
1399                         return 0;
1400         }
1401
1402         return 0;
1403 }
1404
1405 static int PVRSRVConnectBW(u32 ui32BridgeID, void *psBridgeIn,
1406                 struct PVRSRV_BRIDGE_OUT_CONNECT_SERVICES *psConnectServicesOUT,
1407                 struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1408 {
1409         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1410
1411         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_CONNECT_SERVICES);
1412
1413         psConnectServicesOUT->hKernelServices = psPerProc->hPerProcData;
1414         psConnectServicesOUT->eError = PVRSRV_OK;
1415
1416         return 0;
1417 }
1418
1419 static int PVRSRVDisconnectBW(u32 ui32BridgeID, void *psBridgeIn,
1420                    struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1421                    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1422 {
1423         PVR_UNREFERENCED_PARAMETER(psPerProc);
1424         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
1425
1426         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1427                                  PVRSRV_BRIDGE_DISCONNECT_SERVICES);
1428
1429         psRetOUT->eError = PVRSRV_OK;
1430
1431         return 0;
1432 }
1433
1434 static int PVRSRVEnumerateDCBW(u32 ui32BridgeID,
1435                     struct PVRSRV_BRIDGE_IN_ENUMCLASS *psEnumDispClassIN,
1436                     struct PVRSRV_BRIDGE_OUT_ENUMCLASS *psEnumDispClassOUT,
1437                     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1438 {
1439         PVR_UNREFERENCED_PARAMETER(psPerProc);
1440
1441         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_ENUM_CLASS);
1442
1443         psEnumDispClassOUT->eError =
1444             PVRSRVEnumerateDCKM(psEnumDispClassIN->sDeviceClass,
1445                                 &psEnumDispClassOUT->ui32NumDevices,
1446                                 &psEnumDispClassOUT->ui32DevID[0]);
1447
1448         return 0;
1449 }
1450
1451 static int PVRSRVOpenDCDeviceBW(u32 ui32BridgeID,
1452      struct PVRSRV_BRIDGE_IN_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceIN,
1453      struct PVRSRV_BRIDGE_OUT_OPEN_DISPCLASS_DEVICE *psOpenDispClassDeviceOUT,
1454      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1455 {
1456         void *hDevCookieInt;
1457         void *hDispClassInfoInt;
1458
1459         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1460                                  PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE);
1461
1462         NEW_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError, psPerProc,
1463                                   1);
1464
1465         psOpenDispClassDeviceOUT->eError =
1466             PVRSRVLookupHandle(psPerProc->psHandleBase,
1467                                &hDevCookieInt,
1468                                psOpenDispClassDeviceIN->hDevCookie,
1469                                PVRSRV_HANDLE_TYPE_DEV_NODE);
1470         if (psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1471                 return 0;
1472
1473         psOpenDispClassDeviceOUT->eError = PVRSRVOpenDCDeviceKM(psPerProc,
1474                                  psOpenDispClassDeviceIN->ui32DeviceID,
1475                                  hDevCookieInt, &hDispClassInfoInt);
1476
1477         if (psOpenDispClassDeviceOUT->eError != PVRSRV_OK)
1478                 return 0;
1479
1480         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
1481                             &psOpenDispClassDeviceOUT->hDeviceKM,
1482                             hDispClassInfoInt,
1483                             PVRSRV_HANDLE_TYPE_DISP_INFO,
1484                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
1485         COMMIT_HANDLE_BATCH_OR_ERROR(psOpenDispClassDeviceOUT->eError,
1486                                      psPerProc);
1487
1488         return 0;
1489 }
1490
1491 static int PVRSRVCloseDCDeviceBW(u32 ui32BridgeID,
1492      struct PVRSRV_BRIDGE_IN_CLOSE_DISPCLASS_DEVICE *psCloseDispClassDeviceIN,
1493      struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1494      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1495 {
1496         void *pvDispClassInfoInt;
1497
1498         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1499                                  PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE);
1500
1501         psRetOUT->eError =
1502             PVRSRVLookupHandle(psPerProc->psHandleBase,
1503                                &pvDispClassInfoInt,
1504                                psCloseDispClassDeviceIN->hDeviceKM,
1505                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1506
1507         if (psRetOUT->eError != PVRSRV_OK)
1508                 return 0;
1509
1510         psRetOUT->eError = PVRSRVCloseDCDeviceKM(pvDispClassInfoInt, IMG_FALSE);
1511         if (psRetOUT->eError != PVRSRV_OK)
1512                 return 0;
1513
1514         psRetOUT->eError =
1515             PVRSRVReleaseHandle(psPerProc->psHandleBase,
1516                                 psCloseDispClassDeviceIN->hDeviceKM,
1517                                 PVRSRV_HANDLE_TYPE_DISP_INFO);
1518         return 0;
1519 }
1520
1521 static int PVRSRVEnumDCFormatsBW(u32 ui32BridgeID,
1522      struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsIN,
1523      struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_FORMATS *psEnumDispClassFormatsOUT,
1524      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1525 {
1526         void *pvDispClassInfoInt;
1527
1528         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1529                                  PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS);
1530
1531         psEnumDispClassFormatsOUT->eError =
1532             PVRSRVLookupHandle(psPerProc->psHandleBase,
1533                                &pvDispClassInfoInt,
1534                                psEnumDispClassFormatsIN->hDeviceKM,
1535                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1536         if (psEnumDispClassFormatsOUT->eError != PVRSRV_OK)
1537                 return 0;
1538
1539         psEnumDispClassFormatsOUT->eError =
1540             PVRSRVEnumDCFormatsKM(pvDispClassInfoInt,
1541                                   &psEnumDispClassFormatsOUT->ui32Count,
1542                                   psEnumDispClassFormatsOUT->asFormat);
1543
1544         return 0;
1545 }
1546
1547 static int PVRSRVEnumDCDimsBW(u32 ui32BridgeID,
1548            struct PVRSRV_BRIDGE_IN_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsIN,
1549            struct PVRSRV_BRIDGE_OUT_ENUM_DISPCLASS_DIMS *psEnumDispClassDimsOUT,
1550            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1551 {
1552         void *pvDispClassInfoInt;
1553
1554         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1555                                  PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS);
1556
1557         psEnumDispClassDimsOUT->eError =
1558             PVRSRVLookupHandle(psPerProc->psHandleBase,
1559                                &pvDispClassInfoInt,
1560                                psEnumDispClassDimsIN->hDeviceKM,
1561                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1562
1563         if (psEnumDispClassDimsOUT->eError != PVRSRV_OK)
1564                 return 0;
1565
1566         psEnumDispClassDimsOUT->eError =
1567             PVRSRVEnumDCDimsKM(pvDispClassInfoInt,
1568                                &psEnumDispClassDimsIN->sFormat,
1569                                &psEnumDispClassDimsOUT->ui32Count,
1570                                psEnumDispClassDimsOUT->asDim);
1571
1572         return 0;
1573 }
1574
1575 static int PVRSRVGetDCSystemBufferBW(u32 ui32BridgeID,
1576    struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferIN,
1577    struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_SYSBUFFER *psGetDispClassSysBufferOUT,
1578    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1579 {
1580         void *hBufferInt;
1581         void *pvDispClassInfoInt;
1582
1583         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1584                                  PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER);
1585
1586         NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError, psPerProc,
1587                                   1);
1588
1589         psGetDispClassSysBufferOUT->eError =
1590             PVRSRVLookupHandle(psPerProc->psHandleBase,
1591                                &pvDispClassInfoInt,
1592                                psGetDispClassSysBufferIN->hDeviceKM,
1593                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1594         if (psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1595                 return 0;
1596
1597         psGetDispClassSysBufferOUT->eError =
1598             PVRSRVGetDCSystemBufferKM(pvDispClassInfoInt, &hBufferInt);
1599
1600         if (psGetDispClassSysBufferOUT->eError != PVRSRV_OK)
1601                 return 0;
1602
1603         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1604                                &psGetDispClassSysBufferOUT->hBuffer,
1605                                hBufferInt,
1606                                PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1607                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
1608                                (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
1609                                 PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
1610                                psGetDispClassSysBufferIN->hDeviceKM);
1611
1612         COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassSysBufferOUT->eError,
1613                                      psPerProc);
1614
1615         return 0;
1616 }
1617
1618 static int PVRSRVGetDCInfoBW(u32 ui32BridgeID,
1619           struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_INFO *psGetDispClassInfoIN,
1620           struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_INFO *psGetDispClassInfoOUT,
1621           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1622 {
1623         void *pvDispClassInfo;
1624
1625         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1626                                  PVRSRV_BRIDGE_GET_DISPCLASS_INFO);
1627
1628         psGetDispClassInfoOUT->eError =
1629             PVRSRVLookupHandle(psPerProc->psHandleBase,
1630                                &pvDispClassInfo,
1631                                psGetDispClassInfoIN->hDeviceKM,
1632                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1633         if (psGetDispClassInfoOUT->eError != PVRSRV_OK)
1634                 return 0;
1635
1636         psGetDispClassInfoOUT->eError =
1637             PVRSRVGetDCInfoKM(pvDispClassInfo,
1638                               &psGetDispClassInfoOUT->sDisplayInfo);
1639
1640         return 0;
1641 }
1642
1643 static int PVRSRVCreateDCSwapChainBW(u32 ui32BridgeID,
1644                   struct PVRSRV_BRIDGE_IN_CREATE_DISPCLASS_SWAPCHAIN
1645                                 *psCreateDispClassSwapChainIN,
1646                   struct PVRSRV_BRIDGE_OUT_CREATE_DISPCLASS_SWAPCHAIN
1647                                 *psCreateDispClassSwapChainOUT,
1648                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1649 {
1650         void *pvDispClassInfo;
1651         void *hSwapChainInt;
1652
1653         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1654                                  PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN);
1655
1656         NEW_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError,
1657                                   psPerProc, 1);
1658
1659         psCreateDispClassSwapChainOUT->eError =
1660             PVRSRVLookupHandle(psPerProc->psHandleBase,
1661                                &pvDispClassInfo,
1662                                psCreateDispClassSwapChainIN->hDeviceKM,
1663                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1664
1665         if (psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1666                 return 0;
1667
1668         psCreateDispClassSwapChainOUT->eError =
1669             PVRSRVCreateDCSwapChainKM(psPerProc, pvDispClassInfo,
1670                         psCreateDispClassSwapChainIN->ui32Flags,
1671                         &psCreateDispClassSwapChainIN->sDstSurfAttrib,
1672                         &psCreateDispClassSwapChainIN->sSrcSurfAttrib,
1673                         psCreateDispClassSwapChainIN->ui32BufferCount,
1674                         psCreateDispClassSwapChainIN->ui32OEMFlags,
1675                         &hSwapChainInt,
1676                         &psCreateDispClassSwapChainOUT->ui32SwapChainID);
1677
1678         if (psCreateDispClassSwapChainOUT->eError != PVRSRV_OK)
1679                 return 0;
1680
1681         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1682                                &psCreateDispClassSwapChainOUT->hSwapChain,
1683                                hSwapChainInt,
1684                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
1685                                PVRSRV_HANDLE_ALLOC_FLAG_NONE,
1686                                psCreateDispClassSwapChainIN->hDeviceKM);
1687
1688         COMMIT_HANDLE_BATCH_OR_ERROR(psCreateDispClassSwapChainOUT->eError,
1689                                      psPerProc);
1690
1691         return 0;
1692 }
1693
1694 static int PVRSRVDestroyDCSwapChainBW(u32 ui32BridgeID,
1695                            struct PVRSRV_BRIDGE_IN_DESTROY_DISPCLASS_SWAPCHAIN
1696                                         *psDestroyDispClassSwapChainIN,
1697                            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1698                            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1699 {
1700         void *pvSwapChain;
1701
1702         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1703                                  PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN);
1704
1705         psRetOUT->eError =
1706             PVRSRVLookupHandle(psPerProc->psHandleBase, &pvSwapChain,
1707                                psDestroyDispClassSwapChainIN->hSwapChain,
1708                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1709         if (psRetOUT->eError != PVRSRV_OK)
1710                 return 0;
1711
1712         psRetOUT->eError = PVRSRVDestroyDCSwapChainKM(pvSwapChain);
1713
1714         if (psRetOUT->eError != PVRSRV_OK)
1715                 return 0;
1716
1717         psRetOUT->eError =
1718             PVRSRVReleaseHandle(psPerProc->psHandleBase,
1719                                 psDestroyDispClassSwapChainIN->hSwapChain,
1720                                 PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1721
1722         return 0;
1723 }
1724
1725 static int PVRSRVSetDCDstRectBW(u32 ui32BridgeID,
1726          struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassDstRectIN,
1727          struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1728          struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1729 {
1730         void *pvDispClassInfo;
1731         void *pvSwapChain;
1732
1733         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1734                                  PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT);
1735
1736         psRetOUT->eError =
1737             PVRSRVLookupHandle(psPerProc->psHandleBase,
1738                                &pvDispClassInfo,
1739                                psSetDispClassDstRectIN->hDeviceKM,
1740                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1741         if (psRetOUT->eError != PVRSRV_OK)
1742                 return 0;
1743
1744         psRetOUT->eError =
1745             PVRSRVLookupHandle(psPerProc->psHandleBase,
1746                                &pvSwapChain,
1747                                psSetDispClassDstRectIN->hSwapChain,
1748                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1749
1750         if (psRetOUT->eError != PVRSRV_OK)
1751                 return 0;
1752
1753         psRetOUT->eError =
1754             PVRSRVSetDCDstRectKM(pvDispClassInfo,
1755                                  pvSwapChain, &psSetDispClassDstRectIN->sRect);
1756
1757         return 0;
1758 }
1759
1760 static int PVRSRVSetDCSrcRectBW(u32 ui32BridgeID,
1761      struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_RECT *psSetDispClassSrcRectIN,
1762      struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1763      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1764 {
1765         void *pvDispClassInfo;
1766         void *pvSwapChain;
1767
1768         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1769                                  PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT);
1770
1771         psRetOUT->eError =
1772             PVRSRVLookupHandle(psPerProc->psHandleBase,
1773                                &pvDispClassInfo,
1774                                psSetDispClassSrcRectIN->hDeviceKM,
1775                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1776         if (psRetOUT->eError != PVRSRV_OK)
1777                 return 0;
1778
1779         psRetOUT->eError =
1780             PVRSRVLookupHandle(psPerProc->psHandleBase,
1781                                &pvSwapChain,
1782                                psSetDispClassSrcRectIN->hSwapChain,
1783                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1784         if (psRetOUT->eError != PVRSRV_OK)
1785                 return 0;
1786
1787         psRetOUT->eError =
1788             PVRSRVSetDCSrcRectKM(pvDispClassInfo,
1789                                  pvSwapChain, &psSetDispClassSrcRectIN->sRect);
1790
1791         return 0;
1792 }
1793
1794 static int PVRSRVSetDCDstColourKeyBW(u32 ui32BridgeID,
1795        struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
1796        struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1797        struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1798 {
1799         void *pvDispClassInfo;
1800         void *pvSwapChain;
1801
1802         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1803                                  PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY);
1804
1805         psRetOUT->eError =
1806             PVRSRVLookupHandle(psPerProc->psHandleBase,
1807                                &pvDispClassInfo,
1808                                psSetDispClassColKeyIN->hDeviceKM,
1809                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1810         if (psRetOUT->eError != PVRSRV_OK)
1811                 return 0;
1812
1813         psRetOUT->eError =
1814             PVRSRVLookupHandle(psPerProc->psHandleBase,
1815                                &pvSwapChain,
1816                                psSetDispClassColKeyIN->hSwapChain,
1817                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1818         if (psRetOUT->eError != PVRSRV_OK)
1819                 return 0;
1820
1821         psRetOUT->eError =
1822             PVRSRVSetDCDstColourKeyKM(pvDispClassInfo,
1823                                       pvSwapChain,
1824                                       psSetDispClassColKeyIN->ui32CKColour);
1825
1826         return 0;
1827 }
1828
1829 static int PVRSRVSetDCSrcColourKeyBW(u32 ui32BridgeID,
1830         struct PVRSRV_BRIDGE_IN_SET_DISPCLASS_COLOURKEY *psSetDispClassColKeyIN,
1831         struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1832         struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1833 {
1834         void *pvDispClassInfo;
1835         void *pvSwapChain;
1836
1837         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1838                                  PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY);
1839
1840         psRetOUT->eError =
1841             PVRSRVLookupHandle(psPerProc->psHandleBase,
1842                                &pvDispClassInfo,
1843                                psSetDispClassColKeyIN->hDeviceKM,
1844                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1845         if (psRetOUT->eError != PVRSRV_OK)
1846                 return 0;
1847
1848         psRetOUT->eError =
1849             PVRSRVLookupHandle(psPerProc->psHandleBase,
1850                                &pvSwapChain,
1851                                psSetDispClassColKeyIN->hSwapChain,
1852                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1853         if (psRetOUT->eError != PVRSRV_OK)
1854                 return 0;
1855
1856         psRetOUT->eError =
1857             PVRSRVSetDCSrcColourKeyKM(pvDispClassInfo,
1858                                       pvSwapChain,
1859                                       psSetDispClassColKeyIN->ui32CKColour);
1860
1861         return 0;
1862 }
1863
1864 static int PVRSRVGetDCBuffersBW(u32 ui32BridgeID,
1865      struct PVRSRV_BRIDGE_IN_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersIN,
1866      struct PVRSRV_BRIDGE_OUT_GET_DISPCLASS_BUFFERS *psGetDispClassBuffersOUT,
1867      struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1868 {
1869         void *pvDispClassInfo;
1870         void *pvSwapChain;
1871         u32 i;
1872
1873         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1874                                  PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS);
1875
1876         NEW_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError, psPerProc,
1877                                   PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1878
1879         psGetDispClassBuffersOUT->eError =
1880             PVRSRVLookupHandle(psPerProc->psHandleBase,
1881                                &pvDispClassInfo,
1882                                psGetDispClassBuffersIN->hDeviceKM,
1883                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1884         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1885                 return 0;
1886
1887         psGetDispClassBuffersOUT->eError =
1888             PVRSRVLookupHandle(psPerProc->psHandleBase,
1889                                &pvSwapChain,
1890                                psGetDispClassBuffersIN->hSwapChain,
1891                                PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN);
1892         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1893                 return 0;
1894
1895         psGetDispClassBuffersOUT->eError =
1896             PVRSRVGetDCBuffersKM(pvDispClassInfo,
1897                                  pvSwapChain,
1898                                  &psGetDispClassBuffersOUT->ui32BufferCount,
1899                                  psGetDispClassBuffersOUT->ahBuffer);
1900         if (psGetDispClassBuffersOUT->eError != PVRSRV_OK)
1901                 return 0;
1902
1903         PVR_ASSERT(psGetDispClassBuffersOUT->ui32BufferCount <=
1904                    PVRSRV_MAX_DC_SWAPCHAIN_BUFFERS);
1905
1906         for (i = 0; i < psGetDispClassBuffersOUT->ui32BufferCount; i++) {
1907                 void *hBufferExt;
1908
1909                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
1910                                &hBufferExt,
1911                                psGetDispClassBuffersOUT->ahBuffer[i],
1912                                PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1913                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
1914                                        (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
1915                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
1916                                psGetDispClassBuffersIN->hSwapChain);
1917
1918                 psGetDispClassBuffersOUT->ahBuffer[i] = hBufferExt;
1919         }
1920
1921         COMMIT_HANDLE_BATCH_OR_ERROR(psGetDispClassBuffersOUT->eError,
1922                                      psPerProc);
1923
1924         return 0;
1925 }
1926
1927 static int PVRSRVSwapToDCBufferBW(u32 ui32BridgeID,
1928       struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_BUFFER *psSwapDispClassBufferIN,
1929       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1930       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1931 {
1932         void *pvDispClassInfo;
1933         void *pvSwapChainBuf;
1934
1935         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1936                                  PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER);
1937
1938         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
1939                                         &pvDispClassInfo,
1940                                         psSwapDispClassBufferIN->hDeviceKM,
1941                                         PVRSRV_HANDLE_TYPE_DISP_INFO);
1942         if (psRetOUT->eError != PVRSRV_OK)
1943                 return 0;
1944
1945         psRetOUT->eError =
1946             PVRSRVLookupSubHandle(psPerProc->psHandleBase,
1947                                   &pvSwapChainBuf,
1948                                   psSwapDispClassBufferIN->hBuffer,
1949                                   PVRSRV_HANDLE_TYPE_DISP_BUFFER,
1950                                   psSwapDispClassBufferIN->hDeviceKM);
1951         if (psRetOUT->eError != PVRSRV_OK)
1952                 return 0;
1953
1954         psRetOUT->eError =
1955             PVRSRVSwapToDCBufferKM(pvDispClassInfo,
1956                                    pvSwapChainBuf,
1957                                    psSwapDispClassBufferIN->ui32SwapInterval,
1958                                    psSwapDispClassBufferIN->hPrivateTag,
1959                                    psSwapDispClassBufferIN->ui32ClipRectCount,
1960                                    psSwapDispClassBufferIN->sClipRect);
1961
1962         return 0;
1963 }
1964
1965 static int PVRSRVSwapToDCSystemBW(u32 ui32BridgeID,
1966       struct PVRSRV_BRIDGE_IN_SWAP_DISPCLASS_TO_SYSTEM *psSwapDispClassSystemIN,
1967       struct PVRSRV_BRIDGE_RETURN *psRetOUT,
1968       struct PVRSRV_PER_PROCESS_DATA *psPerProc)
1969 {
1970         void *pvDispClassInfo;
1971         void *pvSwapChain;
1972
1973         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
1974                                  PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM);
1975
1976         psRetOUT->eError =
1977             PVRSRVLookupHandle(psPerProc->psHandleBase,
1978                                &pvDispClassInfo,
1979                                psSwapDispClassSystemIN->hDeviceKM,
1980                                PVRSRV_HANDLE_TYPE_DISP_INFO);
1981         if (psRetOUT->eError != PVRSRV_OK)
1982                 return 0;
1983
1984         psRetOUT->eError =
1985             PVRSRVLookupSubHandle(psPerProc->psHandleBase,
1986                                   &pvSwapChain,
1987                                   psSwapDispClassSystemIN->hSwapChain,
1988                                   PVRSRV_HANDLE_TYPE_DISP_SWAP_CHAIN,
1989                                   psSwapDispClassSystemIN->hDeviceKM);
1990         if (psRetOUT->eError != PVRSRV_OK)
1991                 return 0;
1992         psRetOUT->eError = PVRSRVSwapToDCSystemKM(pvDispClassInfo, pvSwapChain);
1993
1994         return 0;
1995 }
1996
1997 static int PVRSRVOpenBCDeviceBW(u32 ui32BridgeID,
1998    struct PVRSRV_BRIDGE_IN_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceIN,
1999    struct PVRSRV_BRIDGE_OUT_OPEN_BUFFERCLASS_DEVICE *psOpenBufferClassDeviceOUT,
2000    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2001 {
2002         void *hDevCookieInt;
2003         void *hBufClassInfo;
2004
2005         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2006                                  PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE);
2007
2008         NEW_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError, psPerProc,
2009                                   1);
2010
2011         psOpenBufferClassDeviceOUT->eError =
2012             PVRSRVLookupHandle(psPerProc->psHandleBase,
2013                                &hDevCookieInt,
2014                                psOpenBufferClassDeviceIN->hDevCookie,
2015                                PVRSRV_HANDLE_TYPE_DEV_NODE);
2016         if (psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2017                 return 0;
2018
2019         psOpenBufferClassDeviceOUT->eError =
2020             PVRSRVOpenBCDeviceKM(psPerProc,
2021                                  psOpenBufferClassDeviceIN->ui32DeviceID,
2022                                  hDevCookieInt, &hBufClassInfo);
2023         if (psOpenBufferClassDeviceOUT->eError != PVRSRV_OK)
2024                 return 0;
2025
2026         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2027                             &psOpenBufferClassDeviceOUT->hDeviceKM,
2028                             hBufClassInfo,
2029                             PVRSRV_HANDLE_TYPE_BUF_INFO,
2030                             PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2031
2032         COMMIT_HANDLE_BATCH_OR_ERROR(psOpenBufferClassDeviceOUT->eError,
2033                                      psPerProc);
2034
2035         return 0;
2036 }
2037
2038 static int PVRSRVCloseBCDeviceBW(u32 ui32BridgeID,
2039    struct PVRSRV_BRIDGE_IN_CLOSE_BUFFERCLASS_DEVICE *psCloseBufferClassDeviceIN,
2040    struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2041    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2042 {
2043         void *pvBufClassInfo;
2044
2045         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2046                                  PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE);
2047
2048         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2049                                &pvBufClassInfo,
2050                                psCloseBufferClassDeviceIN->hDeviceKM,
2051                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2052         if (psRetOUT->eError != PVRSRV_OK)
2053                 return 0;
2054
2055         psRetOUT->eError = PVRSRVCloseBCDeviceKM(pvBufClassInfo, IMG_FALSE);
2056
2057         if (psRetOUT->eError != PVRSRV_OK)
2058                 return 0;
2059
2060         psRetOUT->eError = PVRSRVReleaseHandle(psPerProc->psHandleBase,
2061                                                psCloseBufferClassDeviceIN->
2062                                                hDeviceKM,
2063                                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2064
2065         return 0;
2066 }
2067
2068 static int PVRSRVGetBCInfoBW(u32 ui32BridgeID,
2069    struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_INFO *psGetBufferClassInfoIN,
2070    struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_INFO *psGetBufferClassInfoOUT,
2071    struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2072 {
2073         void *pvBufClassInfo;
2074
2075         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2076                                  PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO);
2077
2078         psGetBufferClassInfoOUT->eError =
2079             PVRSRVLookupHandle(psPerProc->psHandleBase,
2080                                &pvBufClassInfo,
2081                                psGetBufferClassInfoIN->hDeviceKM,
2082                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2083         if (psGetBufferClassInfoOUT->eError != PVRSRV_OK)
2084                 return 0;
2085
2086         psGetBufferClassInfoOUT->eError =
2087             PVRSRVGetBCInfoKM(pvBufClassInfo,
2088                               &psGetBufferClassInfoOUT->sBufferInfo);
2089         return 0;
2090 }
2091
2092 static int PVRSRVGetBCBufferBW(u32 ui32BridgeID,
2093     struct PVRSRV_BRIDGE_IN_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferIN,
2094     struct PVRSRV_BRIDGE_OUT_GET_BUFFERCLASS_BUFFER *psGetBufferClassBufferOUT,
2095     struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2096 {
2097         void *pvBufClassInfo;
2098         void *hBufferInt;
2099
2100         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2101                                  PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER);
2102
2103         NEW_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError, psPerProc,
2104                                   1);
2105
2106         psGetBufferClassBufferOUT->eError =
2107             PVRSRVLookupHandle(psPerProc->psHandleBase,
2108                                &pvBufClassInfo,
2109                                psGetBufferClassBufferIN->hDeviceKM,
2110                                PVRSRV_HANDLE_TYPE_BUF_INFO);
2111         if (psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2112                 return 0;
2113
2114         psGetBufferClassBufferOUT->eError =
2115             PVRSRVGetBCBufferKM(pvBufClassInfo,
2116                                 psGetBufferClassBufferIN->ui32BufferIndex,
2117                                 &hBufferInt);
2118
2119         if (psGetBufferClassBufferOUT->eError != PVRSRV_OK)
2120                 return 0;
2121
2122         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2123                                &psGetBufferClassBufferOUT->hBuffer,
2124                                hBufferInt,
2125                                PVRSRV_HANDLE_TYPE_BUF_BUFFER,
2126                                (enum PVRSRV_HANDLE_ALLOC_FLAG)
2127                                        (PVRSRV_HANDLE_ALLOC_FLAG_PRIVATE |
2128                                         PVRSRV_HANDLE_ALLOC_FLAG_SHARED),
2129                                psGetBufferClassBufferIN->hDeviceKM);
2130
2131         COMMIT_HANDLE_BATCH_OR_ERROR(psGetBufferClassBufferOUT->eError,
2132                                      psPerProc);
2133
2134         return 0;
2135 }
2136
2137 static int PVRSRVAllocSharedSysMemoryBW(u32 ui32BridgeID,
2138           struct PVRSRV_BRIDGE_IN_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemIN,
2139           struct PVRSRV_BRIDGE_OUT_ALLOC_SHARED_SYS_MEM *psAllocSharedSysMemOUT,
2140           struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2141 {
2142         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2143
2144         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2145                                  PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM);
2146
2147         NEW_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc, 1);
2148
2149         psAllocSharedSysMemOUT->eError =
2150             PVRSRVAllocSharedSysMemoryKM(psPerProc,
2151                                          psAllocSharedSysMemIN->ui32Flags,
2152                                          psAllocSharedSysMemIN->ui32Size,
2153                                          &psKernelMemInfo);
2154         if (psAllocSharedSysMemOUT->eError != PVRSRV_OK)
2155                 return 0;
2156
2157         OSMemSet(&psAllocSharedSysMemOUT->sClientMemInfo,
2158                  0, sizeof(psAllocSharedSysMemOUT->sClientMemInfo));
2159
2160         psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddrKM =
2161                     psKernelMemInfo->pvLinAddrKM;
2162
2163         psAllocSharedSysMemOUT->sClientMemInfo.pvLinAddr = NULL;
2164         psAllocSharedSysMemOUT->sClientMemInfo.ui32Flags =
2165                                         psKernelMemInfo->ui32Flags;
2166         psAllocSharedSysMemOUT->sClientMemInfo.ui32AllocSize =
2167                                         psKernelMemInfo->ui32AllocSize;
2168         psAllocSharedSysMemOUT->sClientMemInfo.hMappingInfo =
2169                                         psKernelMemInfo->sMemBlk.hOSMemHandle;
2170
2171         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2172                          &psAllocSharedSysMemOUT->sClientMemInfo.hKernelMemInfo,
2173                          psKernelMemInfo,
2174                          PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO,
2175                          PVRSRV_HANDLE_ALLOC_FLAG_NONE);
2176
2177         COMMIT_HANDLE_BATCH_OR_ERROR(psAllocSharedSysMemOUT->eError, psPerProc);
2178
2179         return 0;
2180 }
2181
2182 static int PVRSRVFreeSharedSysMemoryBW(u32 ui32BridgeID,
2183             struct PVRSRV_BRIDGE_IN_FREE_SHARED_SYS_MEM *psFreeSharedSysMemIN,
2184             struct PVRSRV_BRIDGE_OUT_FREE_SHARED_SYS_MEM *psFreeSharedSysMemOUT,
2185             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2186 {
2187         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2188
2189         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2190                                  PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM);
2191
2192         psFreeSharedSysMemOUT->eError =
2193             PVRSRVLookupHandle(psPerProc->psHandleBase,
2194                                (void **)&psKernelMemInfo,
2195                                psFreeSharedSysMemIN->psKernelMemInfo,
2196                                PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2197
2198         if (psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2199                 return 0;
2200
2201         psFreeSharedSysMemOUT->eError =
2202             PVRSRVFreeSharedSysMemoryKM(psKernelMemInfo);
2203         if (psFreeSharedSysMemOUT->eError != PVRSRV_OK)
2204                 return 0;
2205
2206         psFreeSharedSysMemOUT->eError =
2207             PVRSRVReleaseHandle(psPerProc->psHandleBase,
2208                                 psFreeSharedSysMemIN->psKernelMemInfo,
2209                                 PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO);
2210         return 0;
2211 }
2212
2213 static int PVRSRVMapMemInfoMemBW(u32 ui32BridgeID,
2214               struct PVRSRV_BRIDGE_IN_MAP_MEMINFO_MEM *psMapMemInfoMemIN,
2215               struct PVRSRV_BRIDGE_OUT_MAP_MEMINFO_MEM *psMapMemInfoMemOUT,
2216               struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2217 {
2218         struct PVRSRV_KERNEL_MEM_INFO *psKernelMemInfo;
2219         enum PVRSRV_HANDLE_TYPE eHandleType;
2220         void *hParent;
2221         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MAP_MEMINFO_MEM);
2222
2223         NEW_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc, 2);
2224
2225         psMapMemInfoMemOUT->eError =
2226             PVRSRVLookupHandleAnyType(psPerProc->psHandleBase,
2227                                       (void **)&psKernelMemInfo, &eHandleType,
2228                                       psMapMemInfoMemIN->hKernelMemInfo);
2229         if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
2230                 return 0;
2231
2232         switch (eHandleType) {
2233         case PVRSRV_HANDLE_TYPE_MEM_INFO:
2234         case PVRSRV_HANDLE_TYPE_MEM_INFO_REF:
2235         case PVRSRV_HANDLE_TYPE_SHARED_SYS_MEM_INFO:
2236                 break;
2237         default:
2238                 psMapMemInfoMemOUT->eError = PVRSRV_ERROR_GENERIC;
2239                 return 0;
2240         }
2241
2242         psMapMemInfoMemOUT->eError =
2243             PVRSRVGetParentHandle(psPerProc->psHandleBase, &hParent,
2244                                   psMapMemInfoMemIN->hKernelMemInfo,
2245                                   eHandleType);
2246         if (psMapMemInfoMemOUT->eError != PVRSRV_OK)
2247                 return 0;
2248         if (hParent == NULL)
2249                 hParent = psMapMemInfoMemIN->hKernelMemInfo;
2250
2251         OSMemSet(&psMapMemInfoMemOUT->sClientMemInfo,
2252                  0, sizeof(psMapMemInfoMemOUT->sClientMemInfo));
2253
2254         psMapMemInfoMemOUT->sClientMemInfo.pvLinAddrKM =
2255                                         psKernelMemInfo->pvLinAddrKM;
2256
2257         psMapMemInfoMemOUT->sClientMemInfo.pvLinAddr = NULL;
2258         psMapMemInfoMemOUT->sClientMemInfo.sDevVAddr =
2259                                         psKernelMemInfo->sDevVAddr;
2260         psMapMemInfoMemOUT->sClientMemInfo.ui32Flags =
2261                                         psKernelMemInfo->ui32Flags;
2262         psMapMemInfoMemOUT->sClientMemInfo.ui32AllocSize =
2263                                         psKernelMemInfo->ui32AllocSize;
2264         psMapMemInfoMemOUT->sClientMemInfo.hMappingInfo =
2265                                         psKernelMemInfo->sMemBlk.hOSMemHandle;
2266
2267         PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2268                         &psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo,
2269                         psKernelMemInfo,
2270                         PVRSRV_HANDLE_TYPE_MEM_INFO_REF,
2271                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI, hParent);
2272
2273         if (psKernelMemInfo->ui32Flags & PVRSRV_MEM_NO_SYNCOBJ) {
2274                 OSMemSet(&psMapMemInfoMemOUT->sClientSyncInfo, 0,
2275                 sizeof(struct PVRSRV_CLIENT_SYNC_INFO));
2276                 psMapMemInfoMemOUT->psKernelSyncInfo = NULL;
2277         } else {
2278                 psMapMemInfoMemOUT->sClientSyncInfo.psSyncData =
2279                     psKernelMemInfo->psKernelSyncInfo->psSyncData;
2280                 psMapMemInfoMemOUT->sClientSyncInfo.sWriteOpsCompleteDevVAddr =
2281                     psKernelMemInfo->psKernelSyncInfo->
2282                                                     sWriteOpsCompleteDevVAddr;
2283                 psMapMemInfoMemOUT->sClientSyncInfo.sReadOpsCompleteDevVAddr =
2284                     psKernelMemInfo->psKernelSyncInfo->sReadOpsCompleteDevVAddr;
2285
2286                 psMapMemInfoMemOUT->sClientSyncInfo.hMappingInfo =
2287                     psKernelMemInfo->psKernelSyncInfo->psSyncDataMemInfoKM->
2288                                                     sMemBlk.hOSMemHandle;
2289
2290                 psMapMemInfoMemOUT->sClientMemInfo.psClientSyncInfo =
2291                     &psMapMemInfoMemOUT->sClientSyncInfo;
2292
2293                 PVRSRVAllocSubHandleNR(psPerProc->psHandleBase,
2294                         &psMapMemInfoMemOUT->sClientSyncInfo.hKernelSyncInfo,
2295                         psKernelMemInfo->psKernelSyncInfo,
2296                         PVRSRV_HANDLE_TYPE_SYNC_INFO,
2297                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI,
2298                         psMapMemInfoMemOUT->sClientMemInfo.hKernelMemInfo);
2299         }
2300
2301         COMMIT_HANDLE_BATCH_OR_ERROR(psMapMemInfoMemOUT->eError, psPerProc);
2302
2303         return 0;
2304 }
2305
2306 static int PVRSRVModifySyncOpsBW(u32 ui32BridgeID,
2307                  struct PVRSRV_BRIDGE_IN_MODIFY_SYNC_OPS *psModifySyncOpsIN,
2308                  struct PVRSRV_BRIDGE_OUT_MODIFY_SYNC_OPS *psModifySyncOpsOUT,
2309                  struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2310 {
2311         void *hKernelSyncInfo;
2312         struct PVRSRV_KERNEL_SYNC_INFO *psKernelSyncInfo;
2313
2314         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_MODIFY_SYNC_OPS);
2315
2316         psModifySyncOpsOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2317                                         &hKernelSyncInfo,
2318                                         psModifySyncOpsIN->hKernelSyncInfo,
2319                                         PVRSRV_HANDLE_TYPE_SYNC_INFO);
2320         if (psModifySyncOpsOUT->eError != PVRSRV_OK)
2321                 return 0;
2322
2323         psKernelSyncInfo = (struct PVRSRV_KERNEL_SYNC_INFO *)hKernelSyncInfo;
2324
2325         /* We return PRE-INCREMENTED versions of all sync Op Values */
2326
2327         psModifySyncOpsOUT->ui32ReadOpsPending =
2328             psKernelSyncInfo->psSyncData->ui32ReadOpsPending;
2329
2330         psModifySyncOpsOUT->ui32WriteOpsPending =
2331             psKernelSyncInfo->psSyncData->ui32WriteOpsPending;
2332
2333         psModifySyncOpsOUT->ui32ReadOpsComplete =
2334             psKernelSyncInfo->psSyncData->ui32ReadOpsComplete;
2335
2336         psModifySyncOpsOUT->ui32WriteOpsComplete =
2337             psKernelSyncInfo->psSyncData->ui32WriteOpsComplete;
2338
2339         if (psModifySyncOpsIN->ui32ModifyFlags &
2340             PVRSRV_MODIFYSYNCOPS_FLAGS_WOP_INC)
2341                 psKernelSyncInfo->psSyncData->ui32WriteOpsPending++;
2342
2343         if (psModifySyncOpsIN->ui32ModifyFlags &
2344             PVRSRV_MODIFYSYNCOPS_FLAGS_ROP_INC)
2345                 psKernelSyncInfo->psSyncData->ui32ReadOpsPending++;
2346
2347         if (psModifySyncOpsIN->ui32ModifyFlags &
2348             PVRSRV_MODIFYSYNCOPS_FLAGS_WOC_INC)
2349                 psKernelSyncInfo->psSyncData->ui32WriteOpsComplete++;
2350
2351         if (psModifySyncOpsIN->ui32ModifyFlags &
2352             PVRSRV_MODIFYSYNCOPS_FLAGS_ROC_INC)
2353                 psKernelSyncInfo->psSyncData->ui32ReadOpsComplete++;
2354
2355         return 0;
2356 }
2357
2358 static int MMU_GetPDDevPAddrBW(u32 ui32BridgeID,
2359             struct PVRSRV_BRIDGE_IN_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrIN,
2360             struct PVRSRV_BRIDGE_OUT_GETMMU_PD_DEVPADDR *psGetMmuPDDevPAddrOUT,
2361             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2362 {
2363         void *hDevMemContextInt;
2364
2365         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2366                                  PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR);
2367
2368         psGetMmuPDDevPAddrOUT->eError =
2369             PVRSRVLookupHandle(psPerProc->psHandleBase, &hDevMemContextInt,
2370                                psGetMmuPDDevPAddrIN->hDevMemContext,
2371                                PVRSRV_HANDLE_TYPE_DEV_MEM_CONTEXT);
2372         if (psGetMmuPDDevPAddrOUT->eError != PVRSRV_OK)
2373                 return 0;
2374
2375         psGetMmuPDDevPAddrOUT->sPDDevPAddr =
2376             BM_GetDeviceNode(hDevMemContextInt)->
2377             pfnMMUGetPDDevPAddr(BM_GetMMUContextFromMemContext
2378                               (hDevMemContextInt));
2379         if (psGetMmuPDDevPAddrOUT->sPDDevPAddr.uiAddr)
2380                 psGetMmuPDDevPAddrOUT->eError = PVRSRV_OK;
2381         else
2382                 psGetMmuPDDevPAddrOUT->eError = PVRSRV_ERROR_GENERIC;
2383         return 0;
2384 }
2385
2386 int DummyBW(u32 ui32BridgeID, void *psBridgeIn, void *psBridgeOut,
2387             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2388 {
2389 #if !defined(CONFIG_PVR_DEBUG_EXTRA)
2390         PVR_UNREFERENCED_PARAMETER(ui32BridgeID);
2391 #endif
2392         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2393         PVR_UNREFERENCED_PARAMETER(psBridgeOut);
2394         PVR_UNREFERENCED_PARAMETER(psPerProc);
2395
2396 #if defined(DEBUG_BRIDGE_KM)
2397         PVR_DPF(PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu (%s) mapped to "
2398                  "Dummy Wrapper (probably not what you want!)",
2399                  __func__, ui32BridgeID,
2400                  g_BridgeDispatchTable[ui32BridgeID].pszIOCName);
2401 #else
2402         PVR_DPF(PVR_DBG_ERROR, "%s: BRIDGE ERROR: BridgeID %lu mapped to "
2403                  "Dummy Wrapper (probably not what you want!)",
2404                  __func__, ui32BridgeID);
2405 #endif
2406         return -ENOTTY;
2407 }
2408
2409 void _SetDispatchTableEntry(u32 ui32Index, const char *pszIOCName,
2410                             int (*pfFunction)(u32 ui32BridgeID,
2411                                               void *psBridgeIn,
2412                                               void *psBridgeOut,
2413                                               struct PVRSRV_PER_PROCESS_DATA
2414                                                                    *psPerProc),
2415                             const char *pszFunctionName)
2416 {
2417         static u32 ui32PrevIndex = ~0UL;
2418 #if !defined(CONFIG_PVR_DEBUG_EXTRA)
2419         PVR_UNREFERENCED_PARAMETER(pszIOCName);
2420 #endif
2421 #if !defined(DEBUG_BRIDGE_KM_DISPATCH_TABLE) && !defined(DEBUG_BRIDGE_KM)
2422         PVR_UNREFERENCED_PARAMETER(pszFunctionName);
2423 #endif
2424
2425
2426         if (g_BridgeDispatchTable[ui32Index].pfFunction) {
2427 #if defined(DEBUG_BRIDGE_KM)
2428                 PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
2429                         "Adding dispatch table entry for %s "
2430                         "clobbers an existing entry for %s",
2431                          __func__, pszIOCName,
2432                          g_BridgeDispatchTable[ui32Index].pszIOCName);
2433 #else
2434                 PVR_DPF(PVR_DBG_ERROR, "%s: BUG!: "
2435                         "Adding dispatch table entry for %s "
2436                         "clobbers an existing entry (index=%lu)",
2437                          __func__, pszIOCName, ui32Index);
2438 #endif
2439                 PVR_DPF(PVR_DBG_ERROR,
2440 "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE may help debug this issue.",
2441                          __func__);
2442         }
2443
2444         if ((ui32PrevIndex != ~0UL) &&
2445             ((ui32Index >= ui32PrevIndex + DISPATCH_TABLE_GAP_THRESHOLD) ||
2446              (ui32Index <= ui32PrevIndex))) {
2447 #if defined(DEBUG_BRIDGE_KM)
2448                 PVR_DPF(PVR_DBG_WARNING,
2449                          "%s: There is a gap in the dispatch table "
2450                          "between indices %lu (%s) and %lu (%s)",
2451                          __func__, ui32PrevIndex,
2452                          g_BridgeDispatchTable[ui32PrevIndex].pszIOCName,
2453                          ui32Index, pszIOCName);
2454 #else
2455                 PVR_DPF(PVR_DBG_WARNING,
2456                          "%s: There is a gap in the dispatch table "
2457                         "between indices %u and %u (%s)",
2458                          __func__, (unsigned)ui32PrevIndex, (unsigned)ui32Index,
2459                          pszIOCName);
2460 #endif
2461                 PVR_DPF(PVR_DBG_ERROR,
2462                         "NOTE: Enabling DEBUG_BRIDGE_KM_DISPATCH_TABLE "
2463                         "may help debug this issue.",
2464                          __func__);
2465         }
2466
2467         g_BridgeDispatchTable[ui32Index].pfFunction = pfFunction;
2468 #if defined(DEBUG_BRIDGE_KM)
2469         g_BridgeDispatchTable[ui32Index].pszIOCName = pszIOCName;
2470         g_BridgeDispatchTable[ui32Index].pszFunctionName = pszFunctionName;
2471         g_BridgeDispatchTable[ui32Index].ui32CallCount = 0;
2472         g_BridgeDispatchTable[ui32Index].ui32CopyFromUserTotalBytes = 0;
2473 #endif
2474
2475         ui32PrevIndex = ui32Index;
2476 }
2477
2478 static int PVRSRVInitSrvConnectBW(u32 ui32BridgeID, void *psBridgeIn,
2479                                   struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2480                                   struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2481 {
2482         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2483
2484         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_INITSRV_CONNECT);
2485         PVR_UNREFERENCED_PARAMETER(psBridgeIn);
2486
2487         if (!OSProcHasPrivSrvInit() ||
2488             PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING) ||
2489             PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) {
2490                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
2491                 return 0;
2492         }
2493
2494         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_TRUE);
2495         psPerProc->bInitProcess = IMG_TRUE;
2496
2497         psRetOUT->eError = PVRSRV_OK;
2498
2499         return 0;
2500 }
2501
2502 static int PVRSRVInitSrvDisconnectBW(u32 ui32BridgeID,
2503              struct PVRSRV_BRIDGE_IN_INITSRV_DISCONNECT *psInitSrvDisconnectIN,
2504              struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2505              struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2506 {
2507         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2508                                  PVRSRV_BRIDGE_INITSRV_DISCONNECT);
2509
2510         if (!psPerProc->bInitProcess) {
2511                 psRetOUT->eError = PVRSRV_ERROR_GENERIC;
2512                 return 0;
2513         }
2514
2515         psPerProc->bInitProcess = IMG_FALSE;
2516
2517         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RUNNING, IMG_FALSE);
2518         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_RAN, IMG_TRUE);
2519
2520         psRetOUT->eError =
2521             PVRSRVFinaliseSystem(psInitSrvDisconnectIN->bInitSuccesful);
2522
2523         PVRSRVSetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL,
2524                                  (IMG_BOOL)(((psRetOUT->eError == PVRSRV_OK) &&
2525                                               (psInitSrvDisconnectIN->
2526                                                             bInitSuccesful))));
2527
2528         return 0;
2529 }
2530
2531 static int PVRSRVEventObjectWaitBW(u32 ui32BridgeID,
2532            struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_WAIT *psEventObjectWaitIN,
2533            struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2534            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2535 {
2536         void *hOSEventKM;
2537
2538         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_WAIT);
2539
2540         psRetOUT->eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
2541                                       &hOSEventKM,
2542                                       psEventObjectWaitIN->hOSEventKM,
2543                                       PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2544
2545         if (psRetOUT->eError != PVRSRV_OK)
2546                 return 0;
2547
2548         psRetOUT->eError = OSEventObjectWait(hOSEventKM);
2549
2550         return 0;
2551 }
2552
2553 static int PVRSRVEventObjectOpenBW(u32 ui32BridgeID,
2554            struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_OPEN *psEventObjectOpenIN,
2555            struct PVRSRV_BRIDGE_OUT_EVENT_OBJECT_OPEN *psEventObjectOpenOUT,
2556            struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2557 {
2558
2559         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID, PVRSRV_BRIDGE_EVENT_OBJECT_OPEN);
2560
2561         NEW_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc, 1);
2562
2563         psEventObjectOpenOUT->eError =
2564             PVRSRVLookupHandle(psPerProc->psHandleBase,
2565                                &psEventObjectOpenIN->sEventObject.hOSEventKM,
2566                                psEventObjectOpenIN->sEventObject.hOSEventKM,
2567                                PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2568
2569         if (psEventObjectOpenOUT->eError != PVRSRV_OK)
2570                 return 0;
2571
2572         psEventObjectOpenOUT->eError =
2573             OSEventObjectOpen(&psEventObjectOpenIN->sEventObject,
2574                               &psEventObjectOpenOUT->hOSEvent);
2575
2576         if (psEventObjectOpenOUT->eError != PVRSRV_OK)
2577                 return 0;
2578
2579         PVRSRVAllocHandleNR(psPerProc->psHandleBase,
2580                             &psEventObjectOpenOUT->hOSEvent,
2581                             psEventObjectOpenOUT->hOSEvent,
2582                             PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT,
2583                             PVRSRV_HANDLE_ALLOC_FLAG_MULTI);
2584
2585         COMMIT_HANDLE_BATCH_OR_ERROR(psEventObjectOpenOUT->eError, psPerProc);
2586
2587         return 0;
2588 }
2589
2590 static int PVRSRVEventObjectCloseBW(u32 ui32BridgeID,
2591             struct PVRSRV_BRIDGE_IN_EVENT_OBJECT_CLOSE *psEventObjectCloseIN,
2592             struct PVRSRV_BRIDGE_RETURN *psRetOUT,
2593             struct PVRSRV_PER_PROCESS_DATA *psPerProc)
2594 {
2595         void *hOSEventKM;
2596
2597         PVRSRV_BRIDGE_ASSERT_CMD(ui32BridgeID,
2598                                  PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE);
2599
2600         psRetOUT->eError =
2601             PVRSRVLookupHandle(psPerProc->psHandleBase,
2602                                &psEventObjectCloseIN->sEventObject.hOSEventKM,
2603                                psEventObjectCloseIN->sEventObject.hOSEventKM,
2604                                PVRSRV_HANDLE_TYPE_SHARED_EVENT_OBJECT);
2605         if (psRetOUT->eError != PVRSRV_OK)
2606                 return 0;
2607
2608         psRetOUT->eError = PVRSRVLookupAndReleaseHandle(psPerProc->psHandleBase,
2609                                 &hOSEventKM,
2610                                 psEventObjectCloseIN->hOSEventKM,
2611                                 PVRSRV_HANDLE_TYPE_EVENT_OBJECT_CONNECT);
2612
2613         if (psRetOUT->eError != PVRSRV_OK)
2614                 return 0;
2615
2616         psRetOUT->eError =
2617             OSEventObjectClose(&psEventObjectCloseIN->sEventObject, hOSEventKM);
2618
2619         return 0;
2620 }
2621
2622 enum PVRSRV_ERROR CommonBridgeInit(void)
2623 {
2624         u32 i;
2625
2626         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DEVICES,
2627                               PVRSRVEnumerateDevicesBW);
2628         SetDispatchTableEntry(PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO,
2629                               PVRSRVAcquireDeviceDataBW);
2630         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_DEVICEINFO, DummyBW);
2631         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT,
2632                               PVRSRVCreateDeviceMemContextBW);
2633         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT,
2634                               PVRSRVDestroyDeviceMemContextBW);
2635         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO,
2636                               PVRSRVGetDeviceMemHeapInfoBW);
2637         SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_DEVICEMEM,
2638                               PVRSRVAllocDeviceMemBW);
2639         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEVICEMEM,
2640                               PVRSRVFreeDeviceMemBW);
2641         SetDispatchTableEntry(PVRSRV_BRIDGE_GETFREE_DEVICEMEM,
2642                               PVRSRVGetFreeDeviceMemBW);
2643         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_COMMANDQUEUE, DummyBW);
2644         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE, DummyBW);
2645         SetDispatchTableEntry(PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA,
2646                               PVRMMapOSMemHandleToMMapDataBW);
2647         SetDispatchTableEntry(PVRSRV_BRIDGE_CONNECT_SERVICES, PVRSRVConnectBW);
2648         SetDispatchTableEntry(PVRSRV_BRIDGE_DISCONNECT_SERVICES,
2649                               PVRSRVDisconnectBW);
2650         SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_DEVICE_MEM, DummyBW);
2651         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DEVICEMEMINFO, DummyBW);
2652         SetDispatchTableEntry(PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM, DummyBW);
2653         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_DEV_VIRTMEM, DummyBW);
2654         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_EXT_MEMORY, DummyBW);
2655         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_EXT_MEMORY, DummyBW);
2656         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEV_MEMORY,
2657                               PVRSRVMapDeviceMemoryBW);
2658         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEV_MEMORY,
2659                               PVRSRVUnmapDeviceMemoryBW);
2660         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY,
2661                               PVRSRVMapDeviceClassMemoryBW);
2662         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY,
2663                               PVRSRVUnmapDeviceClassMemoryBW);
2664         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER, DummyBW);
2665         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER, DummyBW);
2666         SetDispatchTableEntry(PVRSRV_BRIDGE_EXPORT_DEVICEMEM,
2667                               PVRSRVExportDeviceMemBW);
2668         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MMAP_DATA,
2669                               PVRMMapReleaseMMapDataBW);
2670         SetDispatchTableEntry(PVRSRV_BRIDGE_CACHE_FLUSH_DRM,
2671                               PVRSRVCacheFlushDRIBW);
2672
2673         SetDispatchTableEntry(PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT, DummyBW);
2674         SetDispatchTableEntry(PVRSRV_BRIDGE_REGISTER_SIM_PROCESS, DummyBW);
2675         SetDispatchTableEntry(PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS, DummyBW);
2676
2677         SetDispatchTableEntry(PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE, DummyBW);
2678         SetDispatchTableEntry(PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE, DummyBW);
2679         SetDispatchTableEntry(PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP, DummyBW);
2680
2681         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_FB_STATS, DummyBW);
2682
2683         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_MISC_INFO, PVRSRVGetMiscInfoBW);
2684         SetDispatchTableEntry(PVRSRV_BRIDGE_RELEASE_MISC_INFO, DummyBW);
2685
2686
2687 #if defined(PDUMP)
2688         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_INIT, DummyBW);
2689         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_MEMPOL, PDumpMemPolBW);
2690         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPMEM, PDumpMemBW);
2691         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REG, PDumpRegWithFlagsBW);
2692         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_REGPOL, PDumpRegPolBW);
2693         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_COMMENT, PDumpCommentBW);
2694         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SETFRAME, PDumpSetFrameBW);
2695         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_ISCAPTURING,
2696                               PDumpIsCaptureFrameBW);
2697         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPBITMAP, PDumpBitmapBW);
2698         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPREADREG, DummyBW);
2699         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_SYNCPOL, PDumpSyncPolBW);
2700         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPSYNC, PDumpSyncDumpBW);
2701         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DRIVERINFO, DummyBW);
2702         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_PDREG, PDumpPDRegBW);
2703         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR,
2704                               PDumpPDDevPAddrBW);
2705         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ,
2706                               PDumpCycleCountRegReadBW);
2707         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STARTINITPHASE, DummyBW);
2708         SetDispatchTableEntry(PVRSRV_BRIDGE_PDUMP_STOPINITPHASE, DummyBW);
2709 #endif
2710
2711         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_OEMJTABLE, DummyBW);
2712
2713         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_CLASS, PVRSRVEnumerateDCBW);
2714
2715         SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE,
2716                               PVRSRVOpenDCDeviceBW);
2717         SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE,
2718                               PVRSRVCloseDCDeviceBW);
2719         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS,
2720                               PVRSRVEnumDCFormatsBW);
2721         SetDispatchTableEntry(PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS,
2722                               PVRSRVEnumDCDimsBW);
2723         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER,
2724                               PVRSRVGetDCSystemBufferBW);
2725         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_INFO,
2726                               PVRSRVGetDCInfoBW);
2727         SetDispatchTableEntry(PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN,
2728                               PVRSRVCreateDCSwapChainBW);
2729         SetDispatchTableEntry(PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN,
2730                               PVRSRVDestroyDCSwapChainBW);
2731         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT,
2732                               PVRSRVSetDCDstRectBW);
2733         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT,
2734                               PVRSRVSetDCSrcRectBW);
2735         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY,
2736                               PVRSRVSetDCDstColourKeyBW);
2737         SetDispatchTableEntry(PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY,
2738                               PVRSRVSetDCSrcColourKeyBW);
2739         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS,
2740                               PVRSRVGetDCBuffersBW);
2741         SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER,
2742                               PVRSRVSwapToDCBufferBW);
2743         SetDispatchTableEntry(PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM,
2744                               PVRSRVSwapToDCSystemBW);
2745
2746         SetDispatchTableEntry(PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE,
2747                               PVRSRVOpenBCDeviceBW);
2748         SetDispatchTableEntry(PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE,
2749                               PVRSRVCloseBCDeviceBW);
2750         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO,
2751                               PVRSRVGetBCInfoBW);
2752         SetDispatchTableEntry(PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER,
2753                               PVRSRVGetBCBufferBW);
2754
2755         SetDispatchTableEntry(PVRSRV_BRIDGE_WRAP_EXT_MEMORY,
2756                               PVRSRVWrapExtMemoryBW);
2757         SetDispatchTableEntry(PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY,
2758                               PVRSRVUnwrapExtMemoryBW);
2759
2760         SetDispatchTableEntry(PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM,
2761                               PVRSRVAllocSharedSysMemoryBW);
2762         SetDispatchTableEntry(PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM,
2763                               PVRSRVFreeSharedSysMemoryBW);
2764         SetDispatchTableEntry(PVRSRV_BRIDGE_MAP_MEMINFO_MEM,
2765                               PVRSRVMapMemInfoMemBW);
2766
2767         SetDispatchTableEntry(PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR,
2768                               MMU_GetPDDevPAddrBW);
2769
2770         SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_CONNECT,
2771                               PVRSRVInitSrvConnectBW);
2772         SetDispatchTableEntry(PVRSRV_BRIDGE_INITSRV_DISCONNECT,
2773                               PVRSRVInitSrvDisconnectBW);
2774
2775         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_WAIT,
2776                               PVRSRVEventObjectWaitBW);
2777         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_OPEN,
2778                               PVRSRVEventObjectOpenBW);
2779         SetDispatchTableEntry(PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE,
2780                               PVRSRVEventObjectCloseBW);
2781
2782         SetDispatchTableEntry(PVRSRV_BRIDGE_MODIFY_SYNC_OPS,
2783                               PVRSRVModifySyncOpsBW);
2784
2785         SetSGXDispatchTableEntry();
2786
2787         for (i = 0; i < BRIDGE_DISPATCH_TABLE_ENTRY_COUNT; i++)
2788                 if (!g_BridgeDispatchTable[i].pfFunction) {
2789                         g_BridgeDispatchTable[i].pfFunction = DummyBW;
2790 #if defined(DEBUG_BRIDGE_KM)
2791                         g_BridgeDispatchTable[i].pszIOCName =
2792                                                     "_PVRSRV_BRIDGE_DUMMY";
2793                         g_BridgeDispatchTable[i].pszFunctionName = "DummyBW";
2794                         g_BridgeDispatchTable[i].ui32CallCount = 0;
2795                         g_BridgeDispatchTable[i].ui32CopyFromUserTotalBytes = 0;
2796                         g_BridgeDispatchTable[i].ui32CopyToUserTotalBytes = 0;
2797 #endif
2798                 }
2799
2800         return PVRSRV_OK;
2801 }
2802
2803 static int bridged_check_cmd(u32 cmd_id)
2804 {
2805         if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RAN)) {
2806                 if (!PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL)) {
2807                         PVR_DPF(PVR_DBG_ERROR,
2808                         "%s: Initialisation failed.  Driver unusable.",
2809                                  __func__);
2810                         return 1;
2811                 }
2812         } else {
2813                 if (PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_RUNNING)) {
2814                         PVR_DPF(PVR_DBG_ERROR,
2815                                  "%s: Initialisation is in progress",
2816                                  __func__);
2817                         return 1;
2818                 } else {
2819                         switch (cmd_id) {
2820                         case PVRSRV_GET_BRIDGE_ID(
2821                                 PVRSRV_BRIDGE_CONNECT_SERVICES):
2822                         case PVRSRV_GET_BRIDGE_ID(
2823                                 PVRSRV_BRIDGE_DISCONNECT_SERVICES):
2824                         case PVRSRV_GET_BRIDGE_ID(
2825                                 PVRSRV_BRIDGE_INITSRV_CONNECT):
2826                         case PVRSRV_GET_BRIDGE_ID(
2827                                 PVRSRV_BRIDGE_INITSRV_DISCONNECT):
2828                                 break;
2829                         default:
2830                                 PVR_DPF(PVR_DBG_ERROR,
2831                         "%s: Driver initialisation not completed yet.",
2832                                          __func__);
2833                                 return 1;
2834                         }
2835                 }
2836         }
2837
2838         return 0;
2839 }
2840
2841 static int bridged_ioctl(struct file *filp, u32 cmd, void *in, void *out,
2842                          size_t in_size,
2843                          struct PVRSRV_PER_PROCESS_DATA *per_proc)
2844 {
2845         int err = -EFAULT;
2846
2847         switch (PVRSRV_IOWR(cmd)) {
2848         case PVRSRV_BRIDGE_ENUM_DEVICES:
2849                 err = PVRSRVEnumerateDevicesBW(cmd, in, out, per_proc);
2850                 break;
2851         case PVRSRV_BRIDGE_ACQUIRE_DEVICEINFO:
2852                 err = PVRSRVAcquireDeviceDataBW(cmd, in, out, per_proc);
2853                 break;
2854         case PVRSRV_BRIDGE_RELEASE_DEVICEINFO:
2855                 err = DummyBW(cmd, in, out, per_proc);
2856                 break;
2857         case PVRSRV_BRIDGE_CREATE_DEVMEMCONTEXT:
2858                 err = PVRSRVCreateDeviceMemContextBW(cmd, in, out, per_proc);
2859                 break;
2860         case PVRSRV_BRIDGE_DESTROY_DEVMEMCONTEXT:
2861                 err = PVRSRVDestroyDeviceMemContextBW(cmd, in, out, per_proc);
2862                 break;
2863         case PVRSRV_BRIDGE_GET_DEVMEM_HEAPINFO:
2864                 err = PVRSRVGetDeviceMemHeapInfoBW(cmd, in, out, per_proc);
2865                 break;
2866         case PVRSRV_BRIDGE_ALLOC_DEVICEMEM:
2867                 err = PVRSRVAllocDeviceMemBW(cmd, in, out, per_proc);
2868                 break;
2869         case PVRSRV_BRIDGE_FREE_DEVICEMEM:
2870                 err = PVRSRVFreeDeviceMemBW(cmd, in, out, per_proc);
2871                 break;
2872         case PVRSRV_BRIDGE_GETFREE_DEVICEMEM:
2873                 err = PVRSRVGetFreeDeviceMemBW(cmd, in, out, per_proc);
2874                 break;
2875
2876         case PVRSRV_BRIDGE_CREATE_COMMANDQUEUE:
2877         case PVRSRV_BRIDGE_DESTROY_COMMANDQUEUE:
2878                 err = DummyBW(cmd, in, out, per_proc);
2879                 break;
2880
2881         case PVRSRV_BRIDGE_MHANDLE_TO_MMAP_DATA:
2882                 err = PVRMMapOSMemHandleToMMapDataBW(cmd, in, out, per_proc);
2883                 break;
2884         case PVRSRV_BRIDGE_CONNECT_SERVICES:
2885                 err = PVRSRVConnectBW(cmd, in, out, per_proc);
2886                 break;
2887         case PVRSRV_BRIDGE_DISCONNECT_SERVICES:
2888                 err = PVRSRVDisconnectBW(cmd, in, out, per_proc);
2889                 break;
2890
2891         case PVRSRV_BRIDGE_WRAP_DEVICE_MEM:
2892         case PVRSRV_BRIDGE_GET_DEVICEMEMINFO:
2893         case PVRSRV_BRIDGE_RESERVE_DEV_VIRTMEM:
2894         case PVRSRV_BRIDGE_FREE_DEV_VIRTMEM:
2895         case PVRSRV_BRIDGE_MAP_EXT_MEMORY:
2896         case PVRSRV_BRIDGE_UNMAP_EXT_MEMORY:
2897                 err = DummyBW(cmd, in, out, per_proc);
2898                 break;
2899
2900         case PVRSRV_BRIDGE_MAP_DEV_MEMORY:
2901                 err = PVRSRVMapDeviceMemoryBW(cmd, in, out, per_proc);
2902                 break;
2903         case PVRSRV_BRIDGE_UNMAP_DEV_MEMORY:
2904                 err = PVRSRVUnmapDeviceMemoryBW(cmd, in, out, per_proc);
2905                 break;
2906         case PVRSRV_BRIDGE_MAP_DEVICECLASS_MEMORY:
2907                 err = PVRSRVMapDeviceClassMemoryBW(cmd, in, out, per_proc);
2908                 break;
2909         case PVRSRV_BRIDGE_UNMAP_DEVICECLASS_MEMORY:
2910                 err = PVRSRVUnmapDeviceClassMemoryBW(cmd, in, out, per_proc);
2911                 break;
2912
2913         case PVRSRV_BRIDGE_MAP_MEM_INFO_TO_USER:
2914         case PVRSRV_BRIDGE_UNMAP_MEM_INFO_FROM_USER:
2915                 err = DummyBW(cmd, in, out, per_proc);
2916                 break;
2917
2918         case PVRSRV_BRIDGE_EXPORT_DEVICEMEM:
2919                 err = PVRSRVExportDeviceMemBW(cmd, in, out, per_proc);
2920                 break;
2921         case PVRSRV_BRIDGE_RELEASE_MMAP_DATA:
2922                 err = PVRMMapReleaseMMapDataBW(cmd, in, out, per_proc);
2923                 break;
2924         case PVRSRV_BRIDGE_CACHE_FLUSH_DRM:
2925                 err = PVRSRVCacheFlushDRIBW(cmd, in, out, per_proc);
2926                 break;
2927
2928         case PVRSRV_BRIDGE_PROCESS_SIMISR_EVENT:
2929         case PVRSRV_BRIDGE_REGISTER_SIM_PROCESS:
2930         case PVRSRV_BRIDGE_UNREGISTER_SIM_PROCESS:
2931         case PVRSRV_BRIDGE_MAPPHYSTOUSERSPACE:
2932         case PVRSRV_BRIDGE_UNMAPPHYSTOUSERSPACE:
2933         case PVRSRV_BRIDGE_GETPHYSTOUSERSPACEMAP:
2934         case PVRSRV_BRIDGE_GET_FB_STATS:
2935                 err = DummyBW(cmd, in, out, per_proc);
2936                 break;
2937
2938         case PVRSRV_BRIDGE_GET_MISC_INFO:
2939                 err = PVRSRVGetMiscInfoBW(cmd, in, out, per_proc);
2940                 break;
2941         case PVRSRV_BRIDGE_RELEASE_MISC_INFO:
2942                 err = DummyBW(cmd, in, out, per_proc);
2943                 break;
2944
2945 #if defined(PDUMP)
2946         case PVRSRV_BRIDGE_PDUMP_INIT:
2947                 err = DummyBW(cmd, in, out, per_proc);
2948                 break;
2949         case PVRSRV_BRIDGE_PDUMP_MEMPOL:
2950                 err = PDumpMemPolBW(cmd, in, out, per_proc);
2951                 break;
2952         case PVRSRV_BRIDGE_PDUMP_DUMPMEM:
2953                 err = PDumpMemBW(cmd, in, out, per_proc);
2954                 break;
2955         case PVRSRV_BRIDGE_PDUMP_REG:
2956                 err = PDumpRegWithFlagsBW(cmd, in, out, per_proc);
2957                 break;
2958         case PVRSRV_BRIDGE_PDUMP_REGPOL:
2959                 err = PDumpRegPolBW(cmd, in, out, per_proc);
2960                 break;
2961         case PVRSRV_BRIDGE_PDUMP_COMMENT:
2962                 err = PDumpCommentBW(cmd, in, out, per_proc);
2963                 break;
2964         case PVRSRV_BRIDGE_PDUMP_SETFRAME:
2965                 err = PDumpSetFrameBW(cmd, in, out, per_proc);
2966                 break;
2967         case PVRSRV_BRIDGE_PDUMP_ISCAPTURING:
2968                 err = PDumpIsCaptureFrameBW(cmd, in, out, per_proc);
2969                 break;
2970         case PVRSRV_BRIDGE_PDUMP_DUMPBITMAP:
2971                 err = PDumpBitmapBW(cmd, in, out, per_proc);
2972                 break;
2973         case PVRSRV_BRIDGE_PDUMP_DUMPREADREG:
2974                 err = DummyBW(cmd, in, out, per_proc);
2975                 break;
2976         case PVRSRV_BRIDGE_PDUMP_SYNCPOL:
2977                 err = PDumpSyncPolBW(cmd, in, out, per_proc);
2978                 break;
2979         case PVRSRV_BRIDGE_PDUMP_DUMPSYNC:
2980                 err = PDumpSyncDumpBW(cmd, in, out, per_proc);
2981                 break;
2982         case PVRSRV_BRIDGE_PDUMP_DRIVERINFO:
2983                 err = DummyBW(cmd, in, out, per_proc);
2984                 break;
2985         case PVRSRV_BRIDGE_PDUMP_PDREG:
2986                 err = PDumpPDRegBW(cmd, in, out, per_proc);
2987                 break;
2988         case PVRSRV_BRIDGE_PDUMP_DUMPPDDEVPADDR:
2989                 err = PDumpPDDevPAddrBW(cmd, in, out, per_proc);
2990                 break;
2991         case PVRSRV_BRIDGE_PDUMP_CYCLE_COUNT_REG_READ:
2992                 err = PDumpCycleCountRegReadBW(cmd, in, out, per_proc);
2993                 break;
2994         case PVRSRV_BRIDGE_PDUMP_STARTINITPHASE:
2995         case PVRSRV_BRIDGE_PDUMP_STOPINITPHASE:
2996                 err = DummyBW(cmd, in, out, per_proc);
2997                 break;
2998 #endif
2999
3000         case PVRSRV_BRIDGE_GET_OEMJTABLE:
3001                 err = DummyBW(cmd, in, out, per_proc);
3002                 break;
3003
3004         case PVRSRV_BRIDGE_ENUM_CLASS:
3005                 err = PVRSRVEnumerateDCBW(cmd, in, out, per_proc);
3006                 break;
3007
3008         case PVRSRV_BRIDGE_OPEN_DISPCLASS_DEVICE:
3009                 err = PVRSRVOpenDCDeviceBW(cmd, in, out, per_proc);
3010                 break;
3011         case PVRSRV_BRIDGE_CLOSE_DISPCLASS_DEVICE:
3012                 err = PVRSRVCloseDCDeviceBW(cmd, in, out, per_proc);
3013                 break;
3014         case PVRSRV_BRIDGE_ENUM_DISPCLASS_FORMATS:
3015                 err = PVRSRVEnumDCFormatsBW(cmd, in, out, per_proc);
3016                 break;
3017         case PVRSRV_BRIDGE_ENUM_DISPCLASS_DIMS:
3018                 err = PVRSRVEnumDCDimsBW(cmd, in, out, per_proc);
3019                 break;
3020         case PVRSRV_BRIDGE_GET_DISPCLASS_SYSBUFFER:
3021                 err = PVRSRVGetDCSystemBufferBW(cmd, in, out, per_proc);
3022                 break;
3023         case PVRSRV_BRIDGE_GET_DISPCLASS_INFO:
3024                 err = PVRSRVGetDCInfoBW(cmd, in, out, per_proc);
3025                 break;
3026         case PVRSRV_BRIDGE_CREATE_DISPCLASS_SWAPCHAIN:
3027                 err = PVRSRVCreateDCSwapChainBW(cmd, in, out, per_proc);
3028                 break;
3029         case PVRSRV_BRIDGE_DESTROY_DISPCLASS_SWAPCHAIN:
3030                 err = PVRSRVDestroyDCSwapChainBW(cmd, in, out, per_proc);
3031                 break;
3032         case PVRSRV_BRIDGE_SET_DISPCLASS_DSTRECT:
3033                 err = PVRSRVSetDCDstRectBW(cmd, in, out, per_proc);
3034                 break;
3035         case PVRSRV_BRIDGE_SET_DISPCLASS_SRCRECT:
3036                 err = PVRSRVSetDCSrcRectBW(cmd, in, out, per_proc);
3037                 break;
3038         case PVRSRV_BRIDGE_SET_DISPCLASS_DSTCOLOURKEY:
3039                 err = PVRSRVSetDCDstColourKeyBW(cmd, in, out, per_proc);
3040                 break;
3041         case PVRSRV_BRIDGE_SET_DISPCLASS_SRCCOLOURKEY:
3042                 err = PVRSRVSetDCSrcColourKeyBW(cmd, in, out, per_proc);
3043                 break;
3044         case PVRSRV_BRIDGE_GET_DISPCLASS_BUFFERS:
3045                 err = PVRSRVGetDCBuffersBW(cmd, in, out, per_proc);
3046                 break;
3047         case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_BUFFER:
3048                 err = PVRSRVSwapToDCBufferBW(cmd, in, out, per_proc);
3049                 break;
3050         case PVRSRV_BRIDGE_SWAP_DISPCLASS_TO_SYSTEM:
3051                 err = PVRSRVSwapToDCSystemBW(cmd, in, out, per_proc);
3052                 break;
3053
3054         case PVRSRV_BRIDGE_OPEN_BUFFERCLASS_DEVICE:
3055                 err = PVRSRVOpenBCDeviceBW(cmd, in, out, per_proc);
3056                 break;
3057         case PVRSRV_BRIDGE_CLOSE_BUFFERCLASS_DEVICE:
3058                 err = PVRSRVCloseBCDeviceBW(cmd, in, out, per_proc);
3059                 break;
3060         case PVRSRV_BRIDGE_GET_BUFFERCLASS_INFO:
3061                 err = PVRSRVGetBCInfoBW(cmd, in, out, per_proc);
3062                 break;
3063         case PVRSRV_BRIDGE_GET_BUFFERCLASS_BUFFER:
3064                 err = PVRSRVGetBCBufferBW(cmd, in, out, per_proc);
3065                 break;
3066
3067         case PVRSRV_BRIDGE_WRAP_EXT_MEMORY:
3068                 err = PVRSRVWrapExtMemoryBW(cmd, in, out, per_proc);
3069                 break;
3070         case PVRSRV_BRIDGE_UNWRAP_EXT_MEMORY:
3071                 err = PVRSRVUnwrapExtMemoryBW(cmd, in, out, per_proc);
3072                 break;
3073
3074         case PVRSRV_BRIDGE_ALLOC_SHARED_SYS_MEM:
3075                 err = PVRSRVAllocSharedSysMemoryBW(cmd, in, out, per_proc);
3076                 break;
3077         case PVRSRV_BRIDGE_FREE_SHARED_SYS_MEM:
3078                 err = PVRSRVFreeSharedSysMemoryBW(cmd, in, out, per_proc);
3079                 break;
3080         case PVRSRV_BRIDGE_MAP_MEMINFO_MEM:
3081                 err = PVRSRVMapMemInfoMemBW(cmd, in, out, per_proc);
3082                 break;
3083
3084         case PVRSRV_BRIDGE_GETMMU_PD_DEVPADDR:
3085                 err = MMU_GetPDDevPAddrBW(cmd, in, out, per_proc);
3086                 break;
3087
3088         case PVRSRV_BRIDGE_INITSRV_CONNECT:
3089                 err = PVRSRVInitSrvConnectBW(cmd, in, out, per_proc);
3090                 break;
3091         case PVRSRV_BRIDGE_INITSRV_DISCONNECT:
3092                 err = PVRSRVInitSrvDisconnectBW(cmd, in, out, per_proc);
3093                 break;
3094
3095         case PVRSRV_BRIDGE_EVENT_OBJECT_WAIT:
3096                 err = PVRSRVEventObjectWaitBW(cmd, in, out, per_proc);
3097                 break;
3098         case PVRSRV_BRIDGE_EVENT_OBJECT_OPEN:
3099                 err = PVRSRVEventObjectOpenBW(cmd, in, out, per_proc);
3100                 break;
3101         case PVRSRV_BRIDGE_EVENT_OBJECT_CLOSE:
3102                 err = PVRSRVEventObjectCloseBW(cmd, in, out, per_proc);
3103                 break;
3104
3105         case PVRSRV_BRIDGE_MODIFY_SYNC_OPS:
3106                 err = PVRSRVModifySyncOpsBW(cmd, in, out, per_proc);
3107                 break;
3108
3109         case PVRSRV_BRIDGE_SGX_GETCLIENTINFO:
3110                 err = SGXGetClientInfoBW(cmd, in, out, per_proc);
3111                 break;
3112         case PVRSRV_BRIDGE_SGX_RELEASECLIENTINFO:
3113                 err = SGXReleaseClientInfoBW(cmd, in, out, per_proc);
3114                 break;
3115         case PVRSRV_BRIDGE_SGX_GETINTERNALDEVINFO:
3116                 err = SGXGetInternalDevInfoBW(cmd, in, out, per_proc);
3117                 break;
3118         case PVRSRV_BRIDGE_SGX_DOKICK:
3119                 err = SGXDoKickBW(cmd, in, out, in_size, per_proc);
3120                 break;
3121
3122         case PVRSRV_BRIDGE_SGX_GETPHYSPAGEADDR:
3123         case PVRSRV_BRIDGE_SGX_READREGISTRYDWORD:
3124         case PVRSRV_BRIDGE_SGX_SCHEDULECOMMAND:
3125                 err = DummyBW(cmd, in, out, per_proc);
3126                 break;
3127
3128         case PVRSRV_BRIDGE_SGX_2DQUERYBLTSCOMPLETE:
3129                 err = SGX2DQueryBlitsCompleteBW(filp, cmd, in, out, per_proc);
3130                 break;
3131
3132         case PVRSRV_BRIDGE_SGX_GETMMUPDADDR:
3133                 err = DummyBW(cmd, in, out, per_proc);
3134                 break;
3135
3136         case PVRSRV_BRIDGE_SGX_SUBMITTRANSFER:
3137                 err = SGXSubmitTransferBW(cmd, in, out, per_proc);
3138                 break;
3139         case PVRSRV_BRIDGE_SGX_GETMISCINFO:
3140                 err = SGXGetMiscInfoBW(cmd, in, out, per_proc);
3141                 break;
3142         case PVRSRV_BRIDGE_SGXINFO_FOR_SRVINIT:
3143                 err = SGXGetInfoForSrvinitBW(cmd, in, out, per_proc);
3144                 break;
3145         case PVRSRV_BRIDGE_SGX_DEVINITPART2:
3146                 err = SGXDevInitPart2BW(cmd, in, out, per_proc);
3147                 break;
3148
3149         case PVRSRV_BRIDGE_SGX_FINDSHAREDPBDESC:
3150                 err = SGXFindSharedPBDescBW(cmd, in, out, per_proc);
3151                 break;
3152         case PVRSRV_BRIDGE_SGX_UNREFSHAREDPBDESC:
3153                 err = SGXUnrefSharedPBDescBW(cmd, in, out, per_proc);
3154                 break;
3155         case PVRSRV_BRIDGE_SGX_ADDSHAREDPBDESC:
3156                 err = SGXAddSharedPBDescBW(cmd, in, out, per_proc);
3157                 break;
3158         case PVRSRV_BRIDGE_SGX_REGISTER_HW_RENDER_CONTEXT:
3159                 err = SGXRegisterHWRenderContextBW(cmd, in, out, per_proc);
3160                 break;
3161         case PVRSRV_BRIDGE_SGX_FLUSH_HW_RENDER_TARGET:
3162                 err = SGXFlushHWRenderTargetBW(cmd, in, out, per_proc);
3163                 break;
3164         case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_RENDER_CONTEXT:
3165                 err = SGXUnregisterHWRenderContextBW(cmd, in, out, per_proc);
3166                 break;
3167         case PVRSRV_BRIDGE_SGX_REGISTER_HW_TRANSFER_CONTEXT:
3168                 err = SGXRegisterHWTransferContextBW(cmd, in, out, per_proc);
3169                 break;
3170         case PVRSRV_BRIDGE_SGX_UNREGISTER_HW_TRANSFER_CONTEXT:
3171                 err = SGXUnregisterHWTransferContextBW(cmd, in, out, per_proc);
3172                 break;
3173
3174         case PVRSRV_BRIDGE_SGX_READ_DIFF_COUNTERS:
3175                 err = SGXReadDiffCountersBW(cmd, in, out, per_proc);
3176                 break;
3177         case PVRSRV_BRIDGE_SGX_READ_HWPERF_CB:
3178                 err = SGXReadHWPerfCBBW(cmd, in, out, per_proc);
3179                 break;
3180
3181         case PVRSRV_BRIDGE_SGX_SCHEDULE_PROCESS_QUEUES:
3182                 err = SGXScheduleProcessQueuesBW(cmd, in, out, per_proc);
3183                 break;
3184
3185 #if defined(PDUMP)
3186         case PVRSRV_BRIDGE_SGX_PDUMP_BUFFER_ARRAY:
3187                 err = SGXPDumpBufferArrayBW(cmd, in, out, per_proc);
3188                 break;
3189         case PVRSRV_BRIDGE_SGX_PDUMP_3D_SIGNATURE_REGISTERS:
3190                 err = SGXPDump3DSignatureRegistersBW(cmd, in, out, per_proc);
3191                 break;
3192         case PVRSRV_BRIDGE_SGX_PDUMP_COUNTER_REGISTERS:
3193                 err = SGXPDumpCounterRegistersBW(cmd, in, out, per_proc);
3194                 break;
3195         case PVRSRV_BRIDGE_SGX_PDUMP_TA_SIGNATURE_REGISTERS:
3196                 err = SGXPDumpTASignatureRegistersBW(cmd, in, out, per_proc);
3197                 break;
3198         case PVRSRV_BRIDGE_SGX_PDUMP_HWPERFCB:
3199                 err = SGXPDumpHWPerfCBBW(cmd, in, out, per_proc);
3200                 break;
3201 #endif
3202
3203         default:
3204                 PVR_DPF(PVR_DBG_ERROR, "%s: cmd = %d is out if range!",
3205                         __func__, cmd);
3206        }
3207
3208        return err;
3209 }
3210
3211 int BridgedDispatchKM(struct file *filp, struct PVRSRV_PER_PROCESS_DATA *pd,
3212                       struct PVRSRV_BRIDGE_PACKAGE *pkg)
3213 {
3214
3215         void *in;
3216         void *out;
3217         u32 bid = pkg->ui32BridgeID;
3218         int err = -EFAULT;
3219         struct SYS_DATA *psSysData;
3220
3221 #if defined(DEBUG_BRIDGE_KM)
3222         g_BridgeDispatchTable[bid].ui32CallCount++;
3223         g_BridgeGlobalStats.ui32IOCTLCount++;
3224 #endif
3225         if (!pd->bInitProcess && bridged_check_cmd(bid))
3226                 goto return_fault;
3227
3228         if (SysAcquireData(&psSysData) != PVRSRV_OK)
3229                 goto return_fault;
3230
3231         in = ((struct ENV_DATA *)psSysData->pvEnvSpecificData)->pvBridgeData;
3232         out = (void *)((u8 *)in + PVRSRV_MAX_BRIDGE_IN_SIZE);
3233
3234         if (pkg->ui32InBufferSize > 0 &&
3235             CopyFromUserWrapper(pd, bid, in, pkg->pvParamIn,
3236                                 pkg->ui32InBufferSize) != PVRSRV_OK)
3237                 goto return_fault;
3238
3239         if (bid >= (BRIDGE_DISPATCH_TABLE_ENTRY_COUNT)) {
3240                 PVR_DPF(PVR_DBG_ERROR,
3241                          "%s: ui32BridgeID = %d is out if range!", __func__,
3242                          bid);
3243                 goto return_fault;
3244         }
3245
3246         err = bridged_ioctl(filp, bid, in, out, pkg->ui32InBufferSize, pd);
3247
3248         if (err < 0)
3249                 goto return_fault;
3250
3251         if (CopyToUserWrapper(pd, bid, pkg->pvParamOut, out,
3252                               pkg->ui32OutBufferSize) != PVRSRV_OK)
3253                 goto return_fault;
3254
3255         err = 0;
3256 return_fault:
3257         ReleaseHandleBatch(pd);
3258         return err;
3259 }