RK3368 GPU: Rogue N Init.
[firefly-linux-kernel-4.4.55.git] / drivers / staging / imgtec / rogue / generated / rgxtq_bridge / server_rgxtq_bridge.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Server bridge for rgxtq
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Implements the server side of the bridge for rgxtq
6 @License        Dual MIT/GPLv2
7
8 The contents of this file are subject to the MIT license as set out below.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
23
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
31
32 This License is also included in this distribution in the file called
33 "MIT-COPYING".
34
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
43
44 #include <stddef.h>
45 #include <asm/uaccess.h>
46
47 #include "img_defs.h"
48
49 #include "rgxtransfer.h"
50
51
52 #include "common_rgxtq_bridge.h"
53
54 #include "allocmem.h"
55 #include "pvr_debug.h"
56 #include "connection_server.h"
57 #include "pvr_bridge.h"
58 #include "rgx_bridge.h"
59 #include "srvcore.h"
60 #include "handle.h"
61
62 #include <linux/slab.h>
63
64
65
66
67
68
69 /* ***************************************************************************
70  * Server-side bridge entry points
71  */
72  
73 static IMG_INT
74 PVRSRVBridgeRGXCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry,
75                                           PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextIN,
76                                           PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextOUT,
77                                          CONNECTION_DATA *psConnection)
78 {
79         IMG_BYTE *psFrameworkCmdInt = NULL;
80         IMG_HANDLE hPrivData = psRGXCreateTransferContextIN->hPrivData;
81         IMG_HANDLE hPrivDataInt = NULL;
82         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
83
84         IMG_UINT32 ui32NextOffset = 0;
85         IMG_BYTE   *pArrayArgsBuffer = NULL;
86 #if !defined(INTEGRITY_OS)
87         IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
88 #endif
89
90         IMG_UINT32 ui32BufferSize = 
91                         (psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) +
92                         0;
93
94
95
96
97
98         if (ui32BufferSize != 0)
99         {
100 #if !defined(INTEGRITY_OS)
101                 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
102                 IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXCreateTransferContextIN), sizeof(unsigned long));
103                 IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
104                         PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
105
106                 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
107                 if (bHaveEnoughSpace)
108                 {
109                         IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXCreateTransferContextIN;
110
111                         pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];           }
112                 else
113 #endif
114                 {
115                         pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
116
117                         if(!pArrayArgsBuffer)
118                         {
119                                 psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
120                                 goto RGXCreateTransferContext_exit;
121                         }
122                 }
123         }
124
125         if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0)
126         {
127                 psFrameworkCmdInt = (IMG_BYTE*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
128                 ui32NextOffset += psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE);
129         }
130
131                         /* Copy the data over */
132                         if (psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE) > 0)
133                         {
134                                 if ( OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateTransferContextIN->psFrameworkCmd, psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK )
135                                 {
136                                         psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
137
138                                         goto RGXCreateTransferContext_exit;
139                                 }
140                         }
141
142         /* Lock over handle lookup. */
143         LockHandle();
144
145
146
147
148
149                                 {
150                                         /* Look up the address from the handle */
151                                         psRGXCreateTransferContextOUT->eError =
152                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
153                                                                                         (void **) &hPrivDataInt,
154                                                                                         hPrivData,
155                                                                                         PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA,
156                                                                                         IMG_TRUE);
157                                         if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
158                                         {
159                                                 UnlockHandle();
160                                                 goto RGXCreateTransferContext_exit;
161                                         }
162                                 }
163         /* Release now we have looked up handles. */
164         UnlockHandle();
165
166         psRGXCreateTransferContextOUT->eError =
167                 PVRSRVRGXCreateTransferContextKM(psConnection, OSGetDevData(psConnection),
168                                         psRGXCreateTransferContextIN->ui32Priority,
169                                         psRGXCreateTransferContextIN->sMCUFenceAddr,
170                                         psRGXCreateTransferContextIN->ui32FrameworkCmdize,
171                                         psFrameworkCmdInt,
172                                         hPrivDataInt,
173                                         &psTransferContextInt);
174         /* Exit early if bridged call fails */
175         if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
176         {
177                 goto RGXCreateTransferContext_exit;
178         }
179
180         /* Lock over handle creation. */
181         LockHandle();
182
183
184
185
186
187         psRGXCreateTransferContextOUT->eError = PVRSRVAllocHandleUnlocked(psConnection->psHandleBase,
188
189                                                         &psRGXCreateTransferContextOUT->hTransferContext,
190                                                         (void *) psTransferContextInt,
191                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
192                                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI
193                                                         ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyTransferContextKM);
194         if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
195         {
196                 UnlockHandle();
197                 goto RGXCreateTransferContext_exit;
198         }
199
200         /* Release now we have created handles. */
201         UnlockHandle();
202
203
204
205 RGXCreateTransferContext_exit:
206
207         /* Lock over handle lookup cleanup. */
208         LockHandle();
209
210
211
212
213
214
215                                 {
216                                         /* Unreference the previously looked up handle */
217                                                 if(hPrivDataInt)
218                                                 {
219                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
220                                                                                         hPrivData,
221                                                                                         PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
222                                                 }
223                                 }
224         /* Release now we have cleaned up look up handles. */
225         UnlockHandle();
226
227         if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
228         {
229                 if (psTransferContextInt)
230                 {
231                         PVRSRVRGXDestroyTransferContextKM(psTransferContextInt);
232                 }
233         }
234
235         /* Allocated space should be equal to the last updated offset */
236         PVR_ASSERT(ui32BufferSize == ui32NextOffset);
237
238 #if defined(INTEGRITY_OS)
239         if(pArrayArgsBuffer)
240 #else
241         if(!bHaveEnoughSpace && pArrayArgsBuffer)
242 #endif
243                 OSFreeMemNoStats(pArrayArgsBuffer);
244
245
246         return 0;
247 }
248
249
250 static IMG_INT
251 PVRSRVBridgeRGXDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry,
252                                           PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextIN,
253                                           PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextOUT,
254                                          CONNECTION_DATA *psConnection)
255 {
256
257
258
259
260
261
262
263
264
265         /* Lock over handle destruction. */
266         LockHandle();
267
268
269
270
271
272         psRGXDestroyTransferContextOUT->eError =
273                 PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
274                                         (IMG_HANDLE) psRGXDestroyTransferContextIN->hTransferContext,
275                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
276         if ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) &&
277             (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
278         {
279                 PVR_DPF((PVR_DBG_ERROR,
280                         "PVRSRVBridgeRGXDestroyTransferContext: %s",
281                         PVRSRVGetErrorStringKM(psRGXDestroyTransferContextOUT->eError)));
282                 PVR_ASSERT(0);
283                 UnlockHandle();
284                 goto RGXDestroyTransferContext_exit;
285         }
286
287         /* Release now we have destroyed handles. */
288         UnlockHandle();
289
290
291
292 RGXDestroyTransferContext_exit:
293
294
295
296
297         return 0;
298 }
299
300
301 static IMG_INT
302 PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32DispatchTableEntry,
303                                           PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER *psRGXSubmitTransferIN,
304                                           PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER *psRGXSubmitTransferOUT,
305                                          CONNECTION_DATA *psConnection)
306 {
307         IMG_HANDLE hTransferContext = psRGXSubmitTransferIN->hTransferContext;
308         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
309         IMG_UINT32 *ui32ClientFenceCountInt = NULL;
310         SYNC_PRIMITIVE_BLOCK * **psFenceUFOSyncPrimBlockInt = NULL;
311         IMG_HANDLE **hFenceUFOSyncPrimBlockInt2 = NULL;
312         IMG_UINT32 **ui32FenceSyncOffsetInt = NULL;
313         IMG_UINT32 **ui32FenceValueInt = NULL;
314         IMG_UINT32 *ui32ClientUpdateCountInt = NULL;
315         SYNC_PRIMITIVE_BLOCK * **psUpdateUFOSyncPrimBlockInt = NULL;
316         IMG_HANDLE **hUpdateUFOSyncPrimBlockInt2 = NULL;
317         IMG_UINT32 **ui32UpdateSyncOffsetInt = NULL;
318         IMG_UINT32 **ui32UpdateValueInt = NULL;
319         IMG_UINT32 *ui32ServerSyncCountInt = NULL;
320         IMG_UINT32 **ui32ServerSyncFlagsInt = NULL;
321         SERVER_SYNC_PRIMITIVE * **psServerSyncInt = NULL;
322         IMG_HANDLE **hServerSyncInt2 = NULL;
323         IMG_CHAR *uiUpdateFenceNameInt = NULL;
324         IMG_UINT32 *ui32CommandSizeInt = NULL;
325         IMG_UINT8 **ui8FWCommandInt = NULL;
326         IMG_UINT32 *ui32TQPrepareFlagsInt = NULL;
327         IMG_UINT32 *ui32SyncPMRFlagsInt = NULL;
328         PMR * *psSyncPMRsInt = NULL;
329         IMG_HANDLE *hSyncPMRsInt2 = NULL;
330
331         IMG_UINT32 ui32NextOffset = 0;
332         IMG_BYTE   *pArrayArgsBuffer = NULL;
333         IMG_BYTE   *pArrayArgsBuffer2 = NULL;
334 #if !defined(INTEGRITY_OS)
335         IMG_BOOL bHaveEnoughSpace = IMG_FALSE;
336 #endif
337
338         IMG_UINT32 ui32BufferSize = 
339                         (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
340                         (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
341                         (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
342                         (32 * sizeof(IMG_CHAR)) +
343                         (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
344                         (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) +
345                         (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) +
346                         (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *)) +
347                         (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) +
348                         0;
349         IMG_UINT32 ui32BufferSize2 = 0;
350         IMG_UINT32 ui32NextOffset2 = 0;
351
352         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
353         {
354
355                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
356                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
357                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
358                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
359                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
360                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
361                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
362                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
363                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
364                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE **);
365                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE **);
366                 ui32BufferSize += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8*);
367         }
368
369
370
371
372
373
374         if (ui32BufferSize != 0)
375         {
376 #if !defined(INTEGRITY_OS)
377                 /* Try to use remainder of input buffer for copies if possible, word-aligned for safety. */
378                 IMG_UINT32 ui32InBufferOffset = PVR_ALIGN(sizeof(*psRGXSubmitTransferIN), sizeof(unsigned long));
379                 IMG_UINT32 ui32InBufferExcessSize = ui32InBufferOffset >= PVRSRV_MAX_BRIDGE_IN_SIZE ? 0 :
380                         PVRSRV_MAX_BRIDGE_IN_SIZE - ui32InBufferOffset;
381
382                 bHaveEnoughSpace = ui32BufferSize <= ui32InBufferExcessSize;
383                 if (bHaveEnoughSpace)
384                 {
385                         IMG_BYTE *pInputBuffer = (IMG_BYTE *)psRGXSubmitTransferIN;
386
387                         pArrayArgsBuffer = &pInputBuffer[ui32InBufferOffset];           }
388                 else
389 #endif
390                 {
391                         pArrayArgsBuffer = OSAllocMemNoStats(ui32BufferSize);
392
393                         if(!pArrayArgsBuffer)
394                         {
395                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
396                                 goto RGXSubmitTransfer_exit;
397                         }
398                 }
399         }
400
401         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
402         {
403                 ui32ClientFenceCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
404                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
405         }
406
407                         /* Copy the data over */
408                         if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
409                         {
410                                 if ( OSCopyFromUser(NULL, ui32ClientFenceCountInt, psRGXSubmitTransferIN->pui32ClientFenceCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
411                                 {
412                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
413
414                                         goto RGXSubmitTransfer_exit;
415                                 }
416                         }
417         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
418         {
419                 /* Assigning psFenceUFOSyncPrimBlockInt to the right offset in the pool buffer for first dimension */
420                 psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
421                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
422                 /* Assigning hFenceUFOSyncPrimBlockInt2 to the right offset in the pool buffer for first dimension */
423                 hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
424                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
425         }
426
427         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
428         {
429                 /* Assigning ui32FenceSyncOffsetInt to the right offset in the pool buffer for first dimension */
430                 ui32FenceSyncOffsetInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
431                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
432         }
433
434         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
435         {
436                 /* Assigning ui32FenceValueInt to the right offset in the pool buffer for first dimension */
437                 ui32FenceValueInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
438                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
439         }
440
441         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
442         {
443                 ui32ClientUpdateCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
444                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
445         }
446
447                         /* Copy the data over */
448                         if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
449                         {
450                                 if ( OSCopyFromUser(NULL, ui32ClientUpdateCountInt, psRGXSubmitTransferIN->pui32ClientUpdateCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
451                                 {
452                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
453
454                                         goto RGXSubmitTransfer_exit;
455                                 }
456                         }
457         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
458         {
459                 /* Assigning psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer for first dimension */
460                 psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
461                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK **);
462                 /* Assigning hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer for first dimension */
463                 hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
464                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
465         }
466
467         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
468         {
469                 /* Assigning ui32UpdateSyncOffsetInt to the right offset in the pool buffer for first dimension */
470                 ui32UpdateSyncOffsetInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
471                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
472         }
473
474         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
475         {
476                 /* Assigning ui32UpdateValueInt to the right offset in the pool buffer for first dimension */
477                 ui32UpdateValueInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
478                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
479         }
480
481         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
482         {
483                 ui32ServerSyncCountInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
484                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
485         }
486
487                         /* Copy the data over */
488                         if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
489                         {
490                                 if ( OSCopyFromUser(NULL, ui32ServerSyncCountInt, psRGXSubmitTransferIN->pui32ServerSyncCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
491                                 {
492                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
493
494                                         goto RGXSubmitTransfer_exit;
495                                 }
496                         }
497         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
498         {
499                 /* Assigning ui32ServerSyncFlagsInt to the right offset in the pool buffer for first dimension */
500                 ui32ServerSyncFlagsInt = (IMG_UINT32**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
501                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32*);
502         }
503
504         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
505         {
506                 /* Assigning psServerSyncInt to the right offset in the pool buffer for first dimension */
507                 psServerSyncInt = (SERVER_SYNC_PRIMITIVE ***)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
508                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE **);
509                 /* Assigning hServerSyncInt2 to the right offset in the pool buffer for first dimension */
510                 hServerSyncInt2 = (IMG_HANDLE **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
511                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE);
512         }
513
514         
515         {
516                 uiUpdateFenceNameInt = (IMG_CHAR*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
517                 ui32NextOffset += 32 * sizeof(IMG_CHAR);
518         }
519
520                         /* Copy the data over */
521                         if (32 * sizeof(IMG_CHAR) > 0)
522                         {
523                                 if ( OSCopyFromUser(NULL, uiUpdateFenceNameInt, psRGXSubmitTransferIN->puiUpdateFenceName, 32 * sizeof(IMG_CHAR)) != PVRSRV_OK )
524                                 {
525                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
526
527                                         goto RGXSubmitTransfer_exit;
528                                 }
529                         }
530         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
531         {
532                 ui32CommandSizeInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
533                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
534         }
535
536                         /* Copy the data over */
537                         if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
538                         {
539                                 if ( OSCopyFromUser(NULL, ui32CommandSizeInt, psRGXSubmitTransferIN->pui32CommandSize, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
540                                 {
541                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
542
543                                         goto RGXSubmitTransfer_exit;
544                                 }
545                         }
546         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
547         {
548                 /* Assigning ui8FWCommandInt to the right offset in the pool buffer for first dimension */
549                 ui8FWCommandInt = (IMG_UINT8**)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
550                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8*);
551         }
552
553         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
554         {
555                 ui32TQPrepareFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
556                 ui32NextOffset += psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32);
557         }
558
559                         /* Copy the data over */
560                         if (psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32) > 0)
561                         {
562                                 if ( OSCopyFromUser(NULL, ui32TQPrepareFlagsInt, psRGXSubmitTransferIN->pui32TQPrepareFlags, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
563                                 {
564                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
565
566                                         goto RGXSubmitTransfer_exit;
567                                 }
568                         }
569         if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
570         {
571                 ui32SyncPMRFlagsInt = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
572                 ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32);
573         }
574
575                         /* Copy the data over */
576                         if (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32) > 0)
577                         {
578                                 if ( OSCopyFromUser(NULL, ui32SyncPMRFlagsInt, psRGXSubmitTransferIN->pui32SyncPMRFlags, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_UINT32)) != PVRSRV_OK )
579                                 {
580                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
581
582                                         goto RGXSubmitTransfer_exit;
583                                 }
584                         }
585         if (psRGXSubmitTransferIN->ui32SyncPMRCount != 0)
586         {
587                 psSyncPMRsInt = (PMR **)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset);
588                 ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(PMR *);
589                 hSyncPMRsInt2 = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer) + ui32NextOffset); 
590                 ui32NextOffset += psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE);
591         }
592
593                         /* Copy the data over */
594                         if (psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE) > 0)
595                         {
596                                 if ( OSCopyFromUser(NULL, hSyncPMRsInt2, psRGXSubmitTransferIN->phSyncPMRs, psRGXSubmitTransferIN->ui32SyncPMRCount * sizeof(IMG_HANDLE)) != PVRSRV_OK )
597                                 {
598                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
599
600                                         goto RGXSubmitTransfer_exit;
601                                 }
602                         }
603
604         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
605         {
606                 IMG_UINT32 i;
607                 for (i = 0; i < psRGXSubmitTransferIN->ui32PrepareCount; i++)
608                 {
609                         ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
610                         ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE *);
611                         ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
612                         ui32BufferSize2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
613                         ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
614                         ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE *);
615                         ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
616                         ui32BufferSize2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
617                         ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);
618                         ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);
619                         ui32BufferSize2 += ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE *);
620                         ui32BufferSize2 += ui32CommandSizeInt[i] * sizeof(IMG_UINT8);
621                 }
622         }
623
624         if (ui32BufferSize2 != 0)
625         {
626                 pArrayArgsBuffer2 = OSAllocMemNoStats(ui32BufferSize2);
627
628                 if(!pArrayArgsBuffer2)
629                 {
630                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
631                         goto RGXSubmitTransfer_exit;
632                 }
633         }
634
635         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
636         {
637                 IMG_UINT32 i;
638                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
639                 {
640                         /* Assigning each psFenceUFOSyncPrimBlockInt to the right offset in the pool buffer (this is the second dimension) */
641                         psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
642                         ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
643                         /* Assigning each hFenceUFOSyncPrimBlockInt2 to the right offset in the pool buffer (this is the second dimension) */
644                         hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
645                         ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE);
646                 }
647         }
648         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
649         {
650                 IMG_UINT32 i;
651                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
652                 {
653                         /* Assigning each ui32FenceSyncOffsetInt to the right offset in the pool buffer (this is the second dimension) */
654                         ui32FenceSyncOffsetInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
655                         ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
656                 }
657         }
658         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
659         {
660                 IMG_UINT32 i;
661                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
662                 {
663                         /* Assigning each ui32FenceValueInt to the right offset in the pool buffer (this is the second dimension) */
664                         ui32FenceValueInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
665                         ui32NextOffset2 += ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);
666                 }
667         }
668         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
669         {
670                 IMG_UINT32 i;
671                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
672                 {
673                         /* Assigning each psUpdateUFOSyncPrimBlockInt to the right offset in the pool buffer (this is the second dimension) */
674                         psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
675                         ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);
676                         /* Assigning each hUpdateUFOSyncPrimBlockInt2 to the right offset in the pool buffer (this is the second dimension) */
677                         hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
678                         ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE);
679                 }
680         }
681         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
682         {
683                 IMG_UINT32 i;
684                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
685                 {
686                         /* Assigning each ui32UpdateSyncOffsetInt to the right offset in the pool buffer (this is the second dimension) */
687                         ui32UpdateSyncOffsetInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
688                         ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
689                 }
690         }
691         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
692         {
693                 IMG_UINT32 i;
694                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
695                 {
696                         /* Assigning each ui32UpdateValueInt to the right offset in the pool buffer (this is the second dimension) */
697                         ui32UpdateValueInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
698                         ui32NextOffset2 += ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);
699                 }
700         }
701         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
702         {
703                 IMG_UINT32 i;
704                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
705                 {
706                         /* Assigning each ui32ServerSyncFlagsInt to the right offset in the pool buffer (this is the second dimension) */
707                         ui32ServerSyncFlagsInt[i] = (IMG_UINT32*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
708                         ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);
709                 }
710         }
711         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
712         {
713                 IMG_UINT32 i;
714                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
715                 {
716                         /* Assigning each psServerSyncInt to the right offset in the pool buffer (this is the second dimension) */
717                         psServerSyncInt[i] = (SERVER_SYNC_PRIMITIVE **)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
718                         ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);
719                         /* Assigning each hServerSyncInt2 to the right offset in the pool buffer (this is the second dimension) */
720                         hServerSyncInt2[i] = (IMG_HANDLE *)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2); 
721                         ui32NextOffset2 += ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE);
722                 }
723         }
724         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
725         {
726                 IMG_UINT32 i;
727                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
728                 {
729                         /* Assigning each ui8FWCommandInt to the right offset in the pool buffer (this is the second dimension) */
730                         ui8FWCommandInt[i] = (IMG_UINT8*)(((IMG_UINT8 *)pArrayArgsBuffer2) + ui32NextOffset2);
731                         ui32NextOffset2 += ui32CommandSizeInt[i] * sizeof(IMG_UINT8);
732                 }
733         }
734
735         {
736                 IMG_UINT32 i;
737                 IMG_HANDLE **psPtr;
738
739                 /* Loop over all the pointers in the array copying the data into the kernel */
740                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
741                 {
742                         /* Copy the pointer over from the client side */
743                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i],
744                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK )
745                         {
746                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
747
748                                 goto RGXSubmitTransfer_exit;
749                         }
750
751                         /* Copy the data over */
752                         if ((ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE)) > 0)
753                         {
754                                 if ( OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
755                                 {
756                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
757
758                                         goto RGXSubmitTransfer_exit;
759                                 }
760                         }
761                 }
762         }
763
764         {
765                 IMG_UINT32 i;
766                 IMG_UINT32 **psPtr;
767
768                 /* Loop over all the pointers in the array copying the data into the kernel */
769                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
770                 {
771                         /* Copy the pointer over from the client side */
772                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i],
773                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK )
774                         {
775                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
776
777                                 goto RGXSubmitTransfer_exit;
778                         }
779
780                         /* Copy the data over */
781                         if ((ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)) > 0)
782                         {
783                                 if ( OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
784                                 {
785                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
786
787                                         goto RGXSubmitTransfer_exit;
788                                 }
789                         }
790                 }
791         }
792
793         {
794                 IMG_UINT32 i;
795                 IMG_UINT32 **psPtr;
796
797                 /* Loop over all the pointers in the array copying the data into the kernel */
798                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
799                 {
800                         /* Copy the pointer over from the client side */
801                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceValue[i],
802                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK )
803                         {
804                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
805
806                                 goto RGXSubmitTransfer_exit;
807                         }
808
809                         /* Copy the data over */
810                         if ((ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)) > 0)
811                         {
812                                 if ( OSCopyFromUser(NULL, (ui32FenceValueInt[i]), psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
813                                 {
814                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
815
816                                         goto RGXSubmitTransfer_exit;
817                                 }
818                         }
819                 }
820         }
821
822         {
823                 IMG_UINT32 i;
824                 IMG_HANDLE **psPtr;
825
826                 /* Loop over all the pointers in the array copying the data into the kernel */
827                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
828                 {
829                         /* Copy the pointer over from the client side */
830                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i],
831                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK )
832                         {
833                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
834
835                                 goto RGXSubmitTransfer_exit;
836                         }
837
838                         /* Copy the data over */
839                         if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)) > 0)
840                         {
841                                 if ( OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
842                                 {
843                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
844
845                                         goto RGXSubmitTransfer_exit;
846                                 }
847                         }
848                 }
849         }
850
851         {
852                 IMG_UINT32 i;
853                 IMG_UINT32 **psPtr;
854
855                 /* Loop over all the pointers in the array copying the data into the kernel */
856                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
857                 {
858                         /* Copy the pointer over from the client side */
859                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i],
860                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK )
861                         {
862                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
863
864                                 goto RGXSubmitTransfer_exit;
865                         }
866
867                         /* Copy the data over */
868                         if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0)
869                         {
870                                 if ( OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
871                                 {
872                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
873
874                                         goto RGXSubmitTransfer_exit;
875                                 }
876                         }
877                 }
878         }
879
880         {
881                 IMG_UINT32 i;
882                 IMG_UINT32 **psPtr;
883
884                 /* Loop over all the pointers in the array copying the data into the kernel */
885                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
886                 {
887                         /* Copy the pointer over from the client side */
888                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateValue[i],
889                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK )
890                         {
891                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
892
893                                 goto RGXSubmitTransfer_exit;
894                         }
895
896                         /* Copy the data over */
897                         if ((ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)) > 0)
898                         {
899                                 if ( OSCopyFromUser(NULL, (ui32UpdateValueInt[i]), psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
900                                 {
901                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
902
903                                         goto RGXSubmitTransfer_exit;
904                                 }
905                         }
906                 }
907         }
908
909         {
910                 IMG_UINT32 i;
911                 IMG_UINT32 **psPtr;
912
913                 /* Loop over all the pointers in the array copying the data into the kernel */
914                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
915                 {
916                         /* Copy the pointer over from the client side */
917                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32ServerSyncFlags[i],
918                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK )
919                         {
920                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
921
922                                 goto RGXSubmitTransfer_exit;
923                         }
924
925                         /* Copy the data over */
926                         if ((ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32)) > 0)
927                         {
928                                 if ( OSCopyFromUser(NULL, (ui32ServerSyncFlagsInt[i]), psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK )
929                                 {
930                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
931
932                                         goto RGXSubmitTransfer_exit;
933                                 }
934                         }
935                 }
936         }
937
938         {
939                 IMG_UINT32 i;
940                 IMG_HANDLE **psPtr;
941
942                 /* Loop over all the pointers in the array copying the data into the kernel */
943                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
944                 {
945                         /* Copy the pointer over from the client side */
946                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phServerSync[i],
947                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK )
948                         {
949                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
950
951                                 goto RGXSubmitTransfer_exit;
952                         }
953
954                         /* Copy the data over */
955                         if ((ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE)) > 0)
956                         {
957                                 if ( OSCopyFromUser(NULL, (hServerSyncInt2[i]), psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK )
958                                 {
959                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
960
961                                         goto RGXSubmitTransfer_exit;
962                                 }
963                         }
964                 }
965         }
966
967         {
968                 IMG_UINT32 i;
969                 IMG_UINT8 **psPtr;
970
971                 /* Loop over all the pointers in the array copying the data into the kernel */
972                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
973                 {
974                         /* Copy the pointer over from the client side */
975                         if ( OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui8FWCommand[i],
976                                 sizeof(IMG_UINT8 **)) != PVRSRV_OK )
977                         {
978                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
979
980                                 goto RGXSubmitTransfer_exit;
981                         }
982
983                         /* Copy the data over */
984                         if ((ui32CommandSizeInt[i] * sizeof(IMG_UINT8)) > 0)
985                         {
986                                 if ( OSCopyFromUser(NULL, (ui8FWCommandInt[i]), psPtr, (ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK )
987                                 {
988                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
989
990                                         goto RGXSubmitTransfer_exit;
991                                 }
992                         }
993                 }
994         }
995         /* Lock over handle lookup. */
996         LockHandle();
997
998
999
1000
1001
1002                                 {
1003                                         /* Look up the address from the handle */
1004                                         psRGXSubmitTransferOUT->eError =
1005                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1006                                                                                         (void **) &psTransferContextInt,
1007                                                                                         hTransferContext,
1008                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
1009                                                                                         IMG_TRUE);
1010                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1011                                         {
1012                                                 UnlockHandle();
1013                                                 goto RGXSubmitTransfer_exit;
1014                                         }
1015                                 }
1016
1017
1018
1019
1020
1021         {
1022                 IMG_UINT32 i;
1023
1024                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1025                 {
1026                         IMG_UINT32 j;
1027                         for (j=0;j<ui32ClientFenceCountInt[i];j++)
1028                         {
1029                                 {
1030                                         /* Look up the address from the handle */
1031                                         psRGXSubmitTransferOUT->eError =
1032                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1033                                                                                         (void **) &psFenceUFOSyncPrimBlockInt[i][j],
1034                                                                                         hFenceUFOSyncPrimBlockInt2[i][j],
1035                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
1036                                                                                         IMG_TRUE);
1037                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1038                                         {
1039                                                 UnlockHandle();
1040                                                 goto RGXSubmitTransfer_exit;
1041                                         }
1042                                 }
1043                         }
1044                 }
1045         }
1046
1047
1048
1049
1050
1051         {
1052                 IMG_UINT32 i;
1053
1054                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1055                 {
1056                         IMG_UINT32 j;
1057                         for (j=0;j<ui32ClientUpdateCountInt[i];j++)
1058                         {
1059                                 {
1060                                         /* Look up the address from the handle */
1061                                         psRGXSubmitTransferOUT->eError =
1062                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1063                                                                                         (void **) &psUpdateUFOSyncPrimBlockInt[i][j],
1064                                                                                         hUpdateUFOSyncPrimBlockInt2[i][j],
1065                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK,
1066                                                                                         IMG_TRUE);
1067                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1068                                         {
1069                                                 UnlockHandle();
1070                                                 goto RGXSubmitTransfer_exit;
1071                                         }
1072                                 }
1073                         }
1074                 }
1075         }
1076
1077
1078
1079
1080
1081         {
1082                 IMG_UINT32 i;
1083
1084                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1085                 {
1086                         IMG_UINT32 j;
1087                         for (j=0;j<ui32ServerSyncCountInt[i];j++)
1088                         {
1089                                 {
1090                                         /* Look up the address from the handle */
1091                                         psRGXSubmitTransferOUT->eError =
1092                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1093                                                                                         (void **) &psServerSyncInt[i][j],
1094                                                                                         hServerSyncInt2[i][j],
1095                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE,
1096                                                                                         IMG_TRUE);
1097                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1098                                         {
1099                                                 UnlockHandle();
1100                                                 goto RGXSubmitTransfer_exit;
1101                                         }
1102                                 }
1103                         }
1104                 }
1105         }
1106
1107
1108
1109
1110
1111         {
1112                 IMG_UINT32 i;
1113
1114                 for (i=0;i<psRGXSubmitTransferIN->ui32SyncPMRCount;i++)
1115                 {
1116                                 {
1117                                         /* Look up the address from the handle */
1118                                         psRGXSubmitTransferOUT->eError =
1119                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1120                                                                                         (void **) &psSyncPMRsInt[i],
1121                                                                                         hSyncPMRsInt2[i],
1122                                                                                         PVRSRV_HANDLE_TYPE_PHYSMEM_PMR,
1123                                                                                         IMG_TRUE);
1124                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1125                                         {
1126                                                 UnlockHandle();
1127                                                 goto RGXSubmitTransfer_exit;
1128                                         }
1129                                 }
1130                 }
1131         }
1132         /* Release now we have looked up handles. */
1133         UnlockHandle();
1134
1135         psRGXSubmitTransferOUT->eError =
1136                 PVRSRVRGXSubmitTransferKM(
1137                                         psTransferContextInt,
1138                                         psRGXSubmitTransferIN->ui32ClientCacheOpSeqNum,
1139                                         psRGXSubmitTransferIN->ui32PrepareCount,
1140                                         ui32ClientFenceCountInt,
1141                                         psFenceUFOSyncPrimBlockInt,
1142                                         ui32FenceSyncOffsetInt,
1143                                         ui32FenceValueInt,
1144                                         ui32ClientUpdateCountInt,
1145                                         psUpdateUFOSyncPrimBlockInt,
1146                                         ui32UpdateSyncOffsetInt,
1147                                         ui32UpdateValueInt,
1148                                         ui32ServerSyncCountInt,
1149                                         ui32ServerSyncFlagsInt,
1150                                         psServerSyncInt,
1151                                         psRGXSubmitTransferIN->i32CheckFenceFD,
1152                                         psRGXSubmitTransferIN->i32UpdateTimelineFD,
1153                                         &psRGXSubmitTransferOUT->i32UpdateFenceFD,
1154                                         uiUpdateFenceNameInt,
1155                                         ui32CommandSizeInt,
1156                                         ui8FWCommandInt,
1157                                         ui32TQPrepareFlagsInt,
1158                                         psRGXSubmitTransferIN->ui32ExtJobRef,
1159                                         psRGXSubmitTransferIN->ui32SyncPMRCount,
1160                                         ui32SyncPMRFlagsInt,
1161                                         psSyncPMRsInt);
1162
1163
1164
1165
1166 RGXSubmitTransfer_exit:
1167
1168         /* Lock over handle lookup cleanup. */
1169         LockHandle();
1170
1171
1172
1173
1174
1175
1176                                 {
1177                                         /* Unreference the previously looked up handle */
1178                                                 if(psTransferContextInt)
1179                                                 {
1180                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1181                                                                                         hTransferContext,
1182                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
1183                                                 }
1184                                 }
1185
1186
1187
1188
1189
1190         {
1191                 IMG_UINT32 i;
1192
1193                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1194                 {
1195                         IMG_UINT32 j;
1196                         for (j=0;j<ui32ClientFenceCountInt[i];j++)
1197                         {
1198                                 {
1199                                         /* Unreference the previously looked up handle */
1200                                                 if(psFenceUFOSyncPrimBlockInt[i][j])
1201                                                 {
1202                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1203                                                                                         hFenceUFOSyncPrimBlockInt2[i][j],
1204                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1205                                                 }
1206                                 }
1207                         }
1208                 }
1209         }
1210
1211
1212
1213
1214
1215         {
1216                 IMG_UINT32 i;
1217
1218                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1219                 {
1220                         IMG_UINT32 j;
1221                         for (j=0;j<ui32ClientUpdateCountInt[i];j++)
1222                         {
1223                                 {
1224                                         /* Unreference the previously looked up handle */
1225                                                 if(psUpdateUFOSyncPrimBlockInt[i][j])
1226                                                 {
1227                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1228                                                                                         hUpdateUFOSyncPrimBlockInt2[i][j],
1229                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1230                                                 }
1231                                 }
1232                         }
1233                 }
1234         }
1235
1236
1237
1238
1239
1240         {
1241                 IMG_UINT32 i;
1242
1243                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1244                 {
1245                         IMG_UINT32 j;
1246                         for (j=0;j<ui32ServerSyncCountInt[i];j++)
1247                         {
1248                                 {
1249                                         /* Unreference the previously looked up handle */
1250                                                 if(psServerSyncInt[i][j])
1251                                                 {
1252                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1253                                                                                         hServerSyncInt2[i][j],
1254                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
1255                                                 }
1256                                 }
1257                         }
1258                 }
1259         }
1260
1261
1262
1263
1264
1265         {
1266                 IMG_UINT32 i;
1267
1268                 for (i=0;i<psRGXSubmitTransferIN->ui32SyncPMRCount;i++)
1269                 {
1270                                 {
1271                                         /* Unreference the previously looked up handle */
1272                                                 if(psSyncPMRsInt[i])
1273                                                 {
1274                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1275                                                                                         hSyncPMRsInt2[i],
1276                                                                                         PVRSRV_HANDLE_TYPE_PHYSMEM_PMR);
1277                                                 }
1278                                 }
1279                 }
1280         }
1281         /* Release now we have cleaned up look up handles. */
1282         UnlockHandle();
1283
1284         /* Allocated space should be equal to the last updated offset */
1285         PVR_ASSERT(ui32BufferSize == ui32NextOffset);
1286
1287 #if defined(INTEGRITY_OS)
1288         if(pArrayArgsBuffer)
1289 #else
1290         if(!bHaveEnoughSpace && pArrayArgsBuffer)
1291 #endif
1292                 OSFreeMemNoStats(pArrayArgsBuffer);
1293
1294         /* Allocated space should be equal to the last updated offset */
1295         PVR_ASSERT(ui32BufferSize2 == ui32NextOffset2);
1296
1297         if(pArrayArgsBuffer2)
1298                 OSFreeMemNoStats(pArrayArgsBuffer2);
1299
1300         return 0;
1301 }
1302
1303
1304 static IMG_INT
1305 PVRSRVBridgeRGXSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry,
1306                                           PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityIN,
1307                                           PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityOUT,
1308                                          CONNECTION_DATA *psConnection)
1309 {
1310         IMG_HANDLE hTransferContext = psRGXSetTransferContextPriorityIN->hTransferContext;
1311         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = NULL;
1312
1313
1314
1315
1316
1317
1318
1319         /* Lock over handle lookup. */
1320         LockHandle();
1321
1322
1323
1324
1325
1326                                 {
1327                                         /* Look up the address from the handle */
1328                                         psRGXSetTransferContextPriorityOUT->eError =
1329                                                 PVRSRVLookupHandleUnlocked(psConnection->psHandleBase,
1330                                                                                         (void **) &psTransferContextInt,
1331                                                                                         hTransferContext,
1332                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
1333                                                                                         IMG_TRUE);
1334                                         if(psRGXSetTransferContextPriorityOUT->eError != PVRSRV_OK)
1335                                         {
1336                                                 UnlockHandle();
1337                                                 goto RGXSetTransferContextPriority_exit;
1338                                         }
1339                                 }
1340         /* Release now we have looked up handles. */
1341         UnlockHandle();
1342
1343         psRGXSetTransferContextPriorityOUT->eError =
1344                 PVRSRVRGXSetTransferContextPriorityKM(psConnection, OSGetDevData(psConnection),
1345                                         psTransferContextInt,
1346                                         psRGXSetTransferContextPriorityIN->ui32Priority);
1347
1348
1349
1350
1351 RGXSetTransferContextPriority_exit:
1352
1353         /* Lock over handle lookup cleanup. */
1354         LockHandle();
1355
1356
1357
1358
1359
1360
1361                                 {
1362                                         /* Unreference the previously looked up handle */
1363                                                 if(psTransferContextInt)
1364                                                 {
1365                                                         PVRSRVReleaseHandleUnlocked(psConnection->psHandleBase,
1366                                                                                         hTransferContext,
1367                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
1368                                                 }
1369                                 }
1370         /* Release now we have cleaned up look up handles. */
1371         UnlockHandle();
1372
1373
1374         return 0;
1375 }
1376
1377
1378
1379
1380 /* *************************************************************************** 
1381  * Server bridge dispatch related glue 
1382  */
1383
1384 static IMG_BOOL bUseLock = IMG_TRUE;
1385
1386 PVRSRV_ERROR InitRGXTQBridge(void);
1387 PVRSRV_ERROR DeinitRGXTQBridge(void);
1388
1389 /*
1390  * Register all RGXTQ functions with services
1391  */
1392 PVRSRV_ERROR InitRGXTQBridge(void)
1393 {
1394
1395         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT, PVRSRVBridgeRGXCreateTransferContext,
1396                                         NULL, bUseLock);
1397
1398         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT, PVRSRVBridgeRGXDestroyTransferContext,
1399                                         NULL, bUseLock);
1400
1401         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER, PVRSRVBridgeRGXSubmitTransfer,
1402                                         NULL, bUseLock);
1403
1404         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY, PVRSRVBridgeRGXSetTransferContextPriority,
1405                                         NULL, bUseLock);
1406
1407
1408         return PVRSRV_OK;
1409 }
1410
1411 /*
1412  * Unregister all rgxtq functions with services
1413  */
1414 PVRSRV_ERROR DeinitRGXTQBridge(void)
1415 {
1416         return PVRSRV_OK;
1417 }