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