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