RK3368 GPU version Rogue M 1.28
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue_m / 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 #if defined (SUPPORT_AUTH)
63 #include "osauth.h"
64 #endif
65
66 #include <linux/slab.h>
67
68
69
70
71 /* ***************************************************************************
72  * Server-side bridge entry points
73  */
74  
75 static IMG_INT
76 PVRSRVBridgeRGXCreateTransferContext(IMG_UINT32 ui32DispatchTableEntry,
77                                           PVRSRV_BRIDGE_IN_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextIN,
78                                           PVRSRV_BRIDGE_OUT_RGXCREATETRANSFERCONTEXT *psRGXCreateTransferContextOUT,
79                                          CONNECTION_DATA *psConnection)
80 {
81         IMG_HANDLE hDevNodeInt = IMG_NULL;
82         IMG_BYTE *psFrameworkCmdInt = IMG_NULL;
83         IMG_HANDLE hPrivDataInt = IMG_NULL;
84         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
85
86
87
88
89         if (psRGXCreateTransferContextIN->ui32FrameworkCmdize != 0)
90         {
91                 psFrameworkCmdInt = OSAllocMem(psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE));
92                 if (!psFrameworkCmdInt)
93                 {
94                         psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
95         
96                         goto RGXCreateTransferContext_exit;
97                 }
98         }
99
100                         /* Copy the data over */
101                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXCreateTransferContextIN->psFrameworkCmd, psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE))
102                                 || (OSCopyFromUser(NULL, psFrameworkCmdInt, psRGXCreateTransferContextIN->psFrameworkCmd,
103                                 psRGXCreateTransferContextIN->ui32FrameworkCmdize * sizeof(IMG_BYTE)) != PVRSRV_OK) )
104                         {
105                                 psRGXCreateTransferContextOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
106
107                                 goto RGXCreateTransferContext_exit;
108                         }
109
110
111
112                                 {
113                                         /* Look up the address from the handle */
114                                         psRGXCreateTransferContextOUT->eError =
115                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
116                                                                                         (IMG_VOID **) &hDevNodeInt,
117                                                                                         psRGXCreateTransferContextIN->hDevNode,
118                                                                                         PVRSRV_HANDLE_TYPE_DEV_NODE);
119                                         if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
120                                         {
121                                                 goto RGXCreateTransferContext_exit;
122                                         }
123                                 }
124
125
126                                 {
127                                         /* Look up the address from the handle */
128                                         psRGXCreateTransferContextOUT->eError =
129                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
130                                                                                         (IMG_VOID **) &hPrivDataInt,
131                                                                                         psRGXCreateTransferContextIN->hPrivData,
132                                                                                         PVRSRV_HANDLE_TYPE_DEV_PRIV_DATA);
133                                         if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
134                                         {
135                                                 goto RGXCreateTransferContext_exit;
136                                         }
137                                 }
138
139
140         psRGXCreateTransferContextOUT->eError =
141                 PVRSRVRGXCreateTransferContextKM(psConnection,
142                                         hDevNodeInt,
143                                         psRGXCreateTransferContextIN->ui32Priority,
144                                         psRGXCreateTransferContextIN->sMCUFenceAddr,
145                                         psRGXCreateTransferContextIN->ui32FrameworkCmdize,
146                                         psFrameworkCmdInt,
147                                         hPrivDataInt,
148                                         &psTransferContextInt);
149         /* Exit early if bridged call fails */
150         if(psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
151         {
152                 goto RGXCreateTransferContext_exit;
153         }
154
155
156         psRGXCreateTransferContextOUT->eError = PVRSRVAllocHandle(psConnection->psHandleBase,
157                                                         &psRGXCreateTransferContextOUT->hTransferContext,
158                                                         (IMG_VOID *) psTransferContextInt,
159                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT,
160                                                         PVRSRV_HANDLE_ALLOC_FLAG_MULTI
161                                                         ,(PFN_HANDLE_RELEASE)&PVRSRVRGXDestroyTransferContextKM);
162         if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
163         {
164                 goto RGXCreateTransferContext_exit;
165         }
166
167
168
169
170 RGXCreateTransferContext_exit:
171         if (psRGXCreateTransferContextOUT->eError != PVRSRV_OK)
172         {
173                 if (psTransferContextInt)
174                 {
175                         PVRSRVRGXDestroyTransferContextKM(psTransferContextInt);
176                 }
177         }
178
179         if (psFrameworkCmdInt)
180                 OSFreeMem(psFrameworkCmdInt);
181
182         return 0;
183 }
184
185 static IMG_INT
186 PVRSRVBridgeRGXDestroyTransferContext(IMG_UINT32 ui32DispatchTableEntry,
187                                           PVRSRV_BRIDGE_IN_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextIN,
188                                           PVRSRV_BRIDGE_OUT_RGXDESTROYTRANSFERCONTEXT *psRGXDestroyTransferContextOUT,
189                                          CONNECTION_DATA *psConnection)
190 {
191
192
193
194
195
196
197
198
199
200         psRGXDestroyTransferContextOUT->eError =
201                 PVRSRVReleaseHandle(psConnection->psHandleBase,
202                                         (IMG_HANDLE) psRGXDestroyTransferContextIN->hTransferContext,
203                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
204         if ((psRGXDestroyTransferContextOUT->eError != PVRSRV_OK) && (psRGXDestroyTransferContextOUT->eError != PVRSRV_ERROR_RETRY))
205         {
206                 PVR_ASSERT(0);
207                 goto RGXDestroyTransferContext_exit;
208         }
209
210
211
212 RGXDestroyTransferContext_exit:
213
214         return 0;
215 }
216
217 static IMG_INT
218 PVRSRVBridgeRGXSubmitTransfer(IMG_UINT32 ui32DispatchTableEntry,
219                                           PVRSRV_BRIDGE_IN_RGXSUBMITTRANSFER *psRGXSubmitTransferIN,
220                                           PVRSRV_BRIDGE_OUT_RGXSUBMITTRANSFER *psRGXSubmitTransferOUT,
221                                          CONNECTION_DATA *psConnection)
222 {
223         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
224         IMG_UINT32 *ui32ClientFenceCountInt = IMG_NULL;
225         SYNC_PRIMITIVE_BLOCK * **psFenceUFOSyncPrimBlockInt = IMG_NULL;
226         IMG_HANDLE **hFenceUFOSyncPrimBlockInt2 = IMG_NULL;
227         IMG_UINT32 **ui32FenceSyncOffsetInt = IMG_NULL;
228         IMG_UINT32 **ui32FenceValueInt = IMG_NULL;
229         IMG_UINT32 *ui32ClientUpdateCountInt = IMG_NULL;
230         SYNC_PRIMITIVE_BLOCK * **psUpdateUFOSyncPrimBlockInt = IMG_NULL;
231         IMG_HANDLE **hUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
232         IMG_UINT32 **ui32UpdateSyncOffsetInt = IMG_NULL;
233         IMG_UINT32 **ui32UpdateValueInt = IMG_NULL;
234         IMG_UINT32 *ui32ServerSyncCountInt = IMG_NULL;
235         IMG_UINT32 **ui32ServerSyncFlagsInt = IMG_NULL;
236         SERVER_SYNC_PRIMITIVE * **psServerSyncInt = IMG_NULL;
237         IMG_HANDLE **hServerSyncInt2 = IMG_NULL;
238         IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
239         IMG_UINT32 *ui32CommandSizeInt = IMG_NULL;
240         IMG_UINT8 **ui8FWCommandInt = IMG_NULL;
241         IMG_UINT32 *ui32TQPrepareFlagsInt = IMG_NULL;
242
243
244
245
246         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
247         {
248                 ui32ClientFenceCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
249                 if (!ui32ClientFenceCountInt)
250                 {
251                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
252         
253                         goto RGXSubmitTransfer_exit;
254                 }
255         }
256
257                         /* Copy the data over */
258                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ClientFenceCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
259                                 || (OSCopyFromUser(NULL, ui32ClientFenceCountInt, psRGXSubmitTransferIN->pui32ClientFenceCount,
260                                 psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
261                         {
262                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
263
264                                 goto RGXSubmitTransfer_exit;
265                         }
266         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
267         {
268                 IMG_UINT32 ui32Pass=0;
269                 IMG_UINT32 i;
270                 IMG_UINT32 ui32AllocSize=0;
271                 IMG_UINT32 ui32Size;
272                 IMG_UINT8 *pui8Ptr = IMG_NULL;
273                 IMG_UINT32 ui32AllocSize2=0;
274                 IMG_UINT32 ui32Size2;
275                 IMG_UINT8 *pui8Ptr2 = IMG_NULL;
276
277                 /*
278                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
279                         Keeps allocation cost down and simplifies the free path
280                 */
281                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
282                 {
283                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
284                         ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
285                         if (ui32Pass == 0)
286                         {
287                                 ui32AllocSize += ui32Size;
288                                 ui32AllocSize2 += ui32Size2;
289                         }
290                         else
291                         {
292                                 pui8Ptr = OSAllocMem(ui32AllocSize);
293                                 if (pui8Ptr == IMG_NULL)
294                                 {
295                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
296                                         goto RGXSubmitTransfer_exit;
297                                 }
298                                 psFenceUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
299                                 pui8Ptr += ui32Size;
300                                 pui8Ptr2 = OSAllocMem(ui32AllocSize2);
301                                 if (pui8Ptr2 == IMG_NULL)
302                                 {
303                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
304                                         goto RGXSubmitTransfer_exit;
305                                 }
306                                 hFenceUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
307                                 pui8Ptr2 += ui32Size2;
308                         }
309                         
310                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
311                         {
312                                 ui32Size = ui32ClientFenceCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);         
313                                 ui32Size2 = ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE);            
314                                 if (ui32Size)
315                                 {
316                                         if (ui32Pass == 0)
317                                         {
318                                                 ui32AllocSize += ui32Size;
319                                                 ui32AllocSize2 += ui32Size2;
320                                         }
321                                         else
322                                         {
323                                                 psFenceUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
324                                                 pui8Ptr += ui32Size;
325                                                 hFenceUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
326                                                 pui8Ptr2 += ui32Size2;
327                                         }
328                                 }
329                         }
330                 }
331         }
332
333         {
334                 IMG_UINT32 i;
335                 IMG_HANDLE **psPtr;
336
337                 /* Loop over all the pointers in the array copying the data into the kernel */
338                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
339                 {
340                         /* Copy the pointer over from the client side */
341                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
342                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phFenceUFOSyncPrimBlock[i],
343                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
344                         {
345                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
346
347                                 goto RGXSubmitTransfer_exit;
348                         }
349                         /* Copy the data over */
350                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE)))
351                                 || (OSCopyFromUser(NULL, (hFenceUFOSyncPrimBlockInt2[i]), psPtr,
352                                 (ui32ClientFenceCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
353                         {
354                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
355
356                                 goto RGXSubmitTransfer_exit;
357                         }
358                 }
359         }
360         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
361         {
362                 IMG_UINT32 ui32Pass=0;
363                 IMG_UINT32 i;
364                 IMG_UINT32 ui32AllocSize=0;
365                 IMG_UINT32 ui32Size;
366                 IMG_UINT8 *pui8Ptr = IMG_NULL;
367
368                 /*
369                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
370                         Keeps allocation cost down and simplifies the free path
371                 */
372                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
373                 {
374                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
375                         if (ui32Pass == 0)
376                         {
377                                 ui32AllocSize += ui32Size;
378                         }
379                         else
380                         {
381                                 pui8Ptr = OSAllocMem(ui32AllocSize);
382                                 if (pui8Ptr == IMG_NULL)
383                                 {
384                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
385                                         goto RGXSubmitTransfer_exit;
386                                 }
387                                 ui32FenceSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
388                                 pui8Ptr += ui32Size;
389                         }
390                         
391                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
392                         {
393                                 ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);             
394                                 if (ui32Size)
395                                 {
396                                         if (ui32Pass == 0)
397                                         {
398                                                 ui32AllocSize += ui32Size;
399                                         }
400                                         else
401                                         {
402                                                 ui32FenceSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
403                                                 pui8Ptr += ui32Size;
404                                         }
405                                 }
406                         }
407                 }
408         }
409
410         {
411                 IMG_UINT32 i;
412                 IMG_UINT32 **psPtr;
413
414                 /* Loop over all the pointers in the array copying the data into the kernel */
415                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
416                 {
417                         /* Copy the pointer over from the client side */
418                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32FenceSyncOffset[i], sizeof(IMG_UINT32 **))
419                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceSyncOffset[i],
420                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
421                         {
422                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
423
424                                 goto RGXSubmitTransfer_exit;
425                         }
426                         /* Copy the data over */
427                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
428                                 || (OSCopyFromUser(NULL, (ui32FenceSyncOffsetInt[i]), psPtr,
429                                 (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
430                         {
431                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
432
433                                 goto RGXSubmitTransfer_exit;
434                         }
435                 }
436         }
437         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
438         {
439                 IMG_UINT32 ui32Pass=0;
440                 IMG_UINT32 i;
441                 IMG_UINT32 ui32AllocSize=0;
442                 IMG_UINT32 ui32Size;
443                 IMG_UINT8 *pui8Ptr = IMG_NULL;
444
445                 /*
446                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
447                         Keeps allocation cost down and simplifies the free path
448                 */
449                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
450                 {
451                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
452                         if (ui32Pass == 0)
453                         {
454                                 ui32AllocSize += ui32Size;
455                         }
456                         else
457                         {
458                                 pui8Ptr = OSAllocMem(ui32AllocSize);
459                                 if (pui8Ptr == IMG_NULL)
460                                 {
461                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
462                                         goto RGXSubmitTransfer_exit;
463                                 }
464                                 ui32FenceValueInt = (IMG_UINT32 **) pui8Ptr;
465                                 pui8Ptr += ui32Size;
466                         }
467                         
468                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
469                         {
470                                 ui32Size = ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32);             
471                                 if (ui32Size)
472                                 {
473                                         if (ui32Pass == 0)
474                                         {
475                                                 ui32AllocSize += ui32Size;
476                                         }
477                                         else
478                                         {
479                                                 ui32FenceValueInt[i] = (IMG_UINT32 *) pui8Ptr;
480                                                 pui8Ptr += ui32Size;
481                                         }
482                                 }
483                         }
484                 }
485         }
486
487         {
488                 IMG_UINT32 i;
489                 IMG_UINT32 **psPtr;
490
491                 /* Loop over all the pointers in the array copying the data into the kernel */
492                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
493                 {
494                         /* Copy the pointer over from the client side */
495                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32FenceValue[i], sizeof(IMG_UINT32 **))
496                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32FenceValue[i],
497                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
498                         {
499                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
500
501                                 goto RGXSubmitTransfer_exit;
502                         }
503                         /* Copy the data over */
504                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32)))
505                                 || (OSCopyFromUser(NULL, (ui32FenceValueInt[i]), psPtr,
506                                 (ui32ClientFenceCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
507                         {
508                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
509
510                                 goto RGXSubmitTransfer_exit;
511                         }
512                 }
513         }
514         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
515         {
516                 ui32ClientUpdateCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
517                 if (!ui32ClientUpdateCountInt)
518                 {
519                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
520         
521                         goto RGXSubmitTransfer_exit;
522                 }
523         }
524
525                         /* Copy the data over */
526                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ClientUpdateCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
527                                 || (OSCopyFromUser(NULL, ui32ClientUpdateCountInt, psRGXSubmitTransferIN->pui32ClientUpdateCount,
528                                 psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
529                         {
530                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
531
532                                 goto RGXSubmitTransfer_exit;
533                         }
534         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
535         {
536                 IMG_UINT32 ui32Pass=0;
537                 IMG_UINT32 i;
538                 IMG_UINT32 ui32AllocSize=0;
539                 IMG_UINT32 ui32Size;
540                 IMG_UINT8 *pui8Ptr = IMG_NULL;
541                 IMG_UINT32 ui32AllocSize2=0;
542                 IMG_UINT32 ui32Size2;
543                 IMG_UINT8 *pui8Ptr2 = IMG_NULL;
544
545                 /*
546                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
547                         Keeps allocation cost down and simplifies the free path
548                 */
549                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
550                 {
551                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SYNC_PRIMITIVE_BLOCK * *);
552                         ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
553                         if (ui32Pass == 0)
554                         {
555                                 ui32AllocSize += ui32Size;
556                                 ui32AllocSize2 += ui32Size2;
557                         }
558                         else
559                         {
560                                 pui8Ptr = OSAllocMem(ui32AllocSize);
561                                 if (pui8Ptr == IMG_NULL)
562                                 {
563                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
564                                         goto RGXSubmitTransfer_exit;
565                                 }
566                                 psUpdateUFOSyncPrimBlockInt = (SYNC_PRIMITIVE_BLOCK * **) pui8Ptr;
567                                 pui8Ptr += ui32Size;
568                                 pui8Ptr2 = OSAllocMem(ui32AllocSize2);
569                                 if (pui8Ptr2 == IMG_NULL)
570                                 {
571                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
572                                         goto RGXSubmitTransfer_exit;
573                                 }
574                                 hUpdateUFOSyncPrimBlockInt2 = (IMG_HANDLE **) pui8Ptr2;
575                                 pui8Ptr2 += ui32Size2;
576                         }
577                         
578                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
579                         {
580                                 ui32Size = ui32ClientUpdateCountInt[i] * sizeof(SYNC_PRIMITIVE_BLOCK *);                
581                                 ui32Size2 = ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE);           
582                                 if (ui32Size)
583                                 {
584                                         if (ui32Pass == 0)
585                                         {
586                                                 ui32AllocSize += ui32Size;
587                                                 ui32AllocSize2 += ui32Size2;
588                                         }
589                                         else
590                                         {
591                                                 psUpdateUFOSyncPrimBlockInt[i] = (SYNC_PRIMITIVE_BLOCK * *) pui8Ptr;
592                                                 pui8Ptr += ui32Size;
593                                                 hUpdateUFOSyncPrimBlockInt2[i] = (IMG_HANDLE *) pui8Ptr2;
594                                                 pui8Ptr2 += ui32Size2;
595                                         }
596                                 }
597                         }
598                 }
599         }
600
601         {
602                 IMG_UINT32 i;
603                 IMG_HANDLE **psPtr;
604
605                 /* Loop over all the pointers in the array copying the data into the kernel */
606                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
607                 {
608                         /* Copy the pointer over from the client side */
609                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i], sizeof(IMG_HANDLE **))
610                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phUpdateUFOSyncPrimBlock[i],
611                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
612                         {
613                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
614
615                                 goto RGXSubmitTransfer_exit;
616                         }
617                         /* Copy the data over */
618                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE)))
619                                 || (OSCopyFromUser(NULL, (hUpdateUFOSyncPrimBlockInt2[i]), psPtr,
620                                 (ui32ClientUpdateCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
621                         {
622                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
623
624                                 goto RGXSubmitTransfer_exit;
625                         }
626                 }
627         }
628         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
629         {
630                 IMG_UINT32 ui32Pass=0;
631                 IMG_UINT32 i;
632                 IMG_UINT32 ui32AllocSize=0;
633                 IMG_UINT32 ui32Size;
634                 IMG_UINT8 *pui8Ptr = IMG_NULL;
635
636                 /*
637                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
638                         Keeps allocation cost down and simplifies the free path
639                 */
640                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
641                 {
642                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
643                         if (ui32Pass == 0)
644                         {
645                                 ui32AllocSize += ui32Size;
646                         }
647                         else
648                         {
649                                 pui8Ptr = OSAllocMem(ui32AllocSize);
650                                 if (pui8Ptr == IMG_NULL)
651                                 {
652                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
653                                         goto RGXSubmitTransfer_exit;
654                                 }
655                                 ui32UpdateSyncOffsetInt = (IMG_UINT32 **) pui8Ptr;
656                                 pui8Ptr += ui32Size;
657                         }
658                         
659                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
660                         {
661                                 ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);            
662                                 if (ui32Size)
663                                 {
664                                         if (ui32Pass == 0)
665                                         {
666                                                 ui32AllocSize += ui32Size;
667                                         }
668                                         else
669                                         {
670                                                 ui32UpdateSyncOffsetInt[i] = (IMG_UINT32 *) pui8Ptr;
671                                                 pui8Ptr += ui32Size;
672                                         }
673                                 }
674                         }
675                 }
676         }
677
678         {
679                 IMG_UINT32 i;
680                 IMG_UINT32 **psPtr;
681
682                 /* Loop over all the pointers in the array copying the data into the kernel */
683                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
684                 {
685                         /* Copy the pointer over from the client side */
686                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i], sizeof(IMG_UINT32 **))
687                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateSyncOffset[i],
688                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
689                         {
690                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
691
692                                 goto RGXSubmitTransfer_exit;
693                         }
694                         /* Copy the data over */
695                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
696                                 || (OSCopyFromUser(NULL, (ui32UpdateSyncOffsetInt[i]), psPtr,
697                                 (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
698                         {
699                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
700
701                                 goto RGXSubmitTransfer_exit;
702                         }
703                 }
704         }
705         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
706         {
707                 IMG_UINT32 ui32Pass=0;
708                 IMG_UINT32 i;
709                 IMG_UINT32 ui32AllocSize=0;
710                 IMG_UINT32 ui32Size;
711                 IMG_UINT8 *pui8Ptr = IMG_NULL;
712
713                 /*
714                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
715                         Keeps allocation cost down and simplifies the free path
716                 */
717                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
718                 {
719                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
720                         if (ui32Pass == 0)
721                         {
722                                 ui32AllocSize += ui32Size;
723                         }
724                         else
725                         {
726                                 pui8Ptr = OSAllocMem(ui32AllocSize);
727                                 if (pui8Ptr == IMG_NULL)
728                                 {
729                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
730                                         goto RGXSubmitTransfer_exit;
731                                 }
732                                 ui32UpdateValueInt = (IMG_UINT32 **) pui8Ptr;
733                                 pui8Ptr += ui32Size;
734                         }
735                         
736                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
737                         {
738                                 ui32Size = ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32);            
739                                 if (ui32Size)
740                                 {
741                                         if (ui32Pass == 0)
742                                         {
743                                                 ui32AllocSize += ui32Size;
744                                         }
745                                         else
746                                         {
747                                                 ui32UpdateValueInt[i] = (IMG_UINT32 *) pui8Ptr;
748                                                 pui8Ptr += ui32Size;
749                                         }
750                                 }
751                         }
752                 }
753         }
754
755         {
756                 IMG_UINT32 i;
757                 IMG_UINT32 **psPtr;
758
759                 /* Loop over all the pointers in the array copying the data into the kernel */
760                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
761                 {
762                         /* Copy the pointer over from the client side */
763                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32UpdateValue[i], sizeof(IMG_UINT32 **))
764                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32UpdateValue[i],
765                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
766                         {
767                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
768
769                                 goto RGXSubmitTransfer_exit;
770                         }
771                         /* Copy the data over */
772                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32)))
773                                 || (OSCopyFromUser(NULL, (ui32UpdateValueInt[i]), psPtr,
774                                 (ui32ClientUpdateCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
775                         {
776                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
777
778                                 goto RGXSubmitTransfer_exit;
779                         }
780                 }
781         }
782         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
783         {
784                 ui32ServerSyncCountInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
785                 if (!ui32ServerSyncCountInt)
786                 {
787                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
788         
789                         goto RGXSubmitTransfer_exit;
790                 }
791         }
792
793                         /* Copy the data over */
794                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32ServerSyncCount, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
795                                 || (OSCopyFromUser(NULL, ui32ServerSyncCountInt, psRGXSubmitTransferIN->pui32ServerSyncCount,
796                                 psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
797                         {
798                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
799
800                                 goto RGXSubmitTransfer_exit;
801                         }
802         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
803         {
804                 IMG_UINT32 ui32Pass=0;
805                 IMG_UINT32 i;
806                 IMG_UINT32 ui32AllocSize=0;
807                 IMG_UINT32 ui32Size;
808                 IMG_UINT8 *pui8Ptr = IMG_NULL;
809
810                 /*
811                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
812                         Keeps allocation cost down and simplifies the free path
813                 */
814                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
815                 {
816                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32 *);
817                         if (ui32Pass == 0)
818                         {
819                                 ui32AllocSize += ui32Size;
820                         }
821                         else
822                         {
823                                 pui8Ptr = OSAllocMem(ui32AllocSize);
824                                 if (pui8Ptr == IMG_NULL)
825                                 {
826                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
827                                         goto RGXSubmitTransfer_exit;
828                                 }
829                                 ui32ServerSyncFlagsInt = (IMG_UINT32 **) pui8Ptr;
830                                 pui8Ptr += ui32Size;
831                         }
832                         
833                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
834                         {
835                                 ui32Size = ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32);              
836                                 if (ui32Size)
837                                 {
838                                         if (ui32Pass == 0)
839                                         {
840                                                 ui32AllocSize += ui32Size;
841                                         }
842                                         else
843                                         {
844                                                 ui32ServerSyncFlagsInt[i] = (IMG_UINT32 *) pui8Ptr;
845                                                 pui8Ptr += ui32Size;
846                                         }
847                                 }
848                         }
849                 }
850         }
851
852         {
853                 IMG_UINT32 i;
854                 IMG_UINT32 **psPtr;
855
856                 /* Loop over all the pointers in the array copying the data into the kernel */
857                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
858                 {
859                         /* Copy the pointer over from the client side */
860                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui32ServerSyncFlags[i], sizeof(IMG_UINT32 **))
861                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui32ServerSyncFlags[i],
862                                 sizeof(IMG_UINT32 **)) != PVRSRV_OK) )
863                         {
864                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
865
866                                 goto RGXSubmitTransfer_exit;
867                         }
868                         /* Copy the data over */
869                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32)))
870                                 || (OSCopyFromUser(NULL, (ui32ServerSyncFlagsInt[i]), psPtr,
871                                 (ui32ServerSyncCountInt[i] * sizeof(IMG_UINT32))) != PVRSRV_OK) )
872                         {
873                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
874
875                                 goto RGXSubmitTransfer_exit;
876                         }
877                 }
878         }
879         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
880         {
881                 IMG_UINT32 ui32Pass=0;
882                 IMG_UINT32 i;
883                 IMG_UINT32 ui32AllocSize=0;
884                 IMG_UINT32 ui32Size;
885                 IMG_UINT8 *pui8Ptr = IMG_NULL;
886                 IMG_UINT32 ui32AllocSize2=0;
887                 IMG_UINT32 ui32Size2;
888                 IMG_UINT8 *pui8Ptr2 = IMG_NULL;
889
890                 /*
891                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
892                         Keeps allocation cost down and simplifies the free path
893                 */
894                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
895                 {
896                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(SERVER_SYNC_PRIMITIVE * *);
897                         ui32Size2 = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_HANDLE *);
898                         if (ui32Pass == 0)
899                         {
900                                 ui32AllocSize += ui32Size;
901                                 ui32AllocSize2 += ui32Size2;
902                         }
903                         else
904                         {
905                                 pui8Ptr = OSAllocMem(ui32AllocSize);
906                                 if (pui8Ptr == IMG_NULL)
907                                 {
908                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
909                                         goto RGXSubmitTransfer_exit;
910                                 }
911                                 psServerSyncInt = (SERVER_SYNC_PRIMITIVE * **) pui8Ptr;
912                                 pui8Ptr += ui32Size;
913                                 pui8Ptr2 = OSAllocMem(ui32AllocSize2);
914                                 if (pui8Ptr2 == IMG_NULL)
915                                 {
916                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
917                                         goto RGXSubmitTransfer_exit;
918                                 }
919                                 hServerSyncInt2 = (IMG_HANDLE **) pui8Ptr2;
920                                 pui8Ptr2 += ui32Size2;
921                         }
922                         
923                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
924                         {
925                                 ui32Size = ui32ServerSyncCountInt[i] * sizeof(SERVER_SYNC_PRIMITIVE *);         
926                                 ui32Size2 = ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE);             
927                                 if (ui32Size)
928                                 {
929                                         if (ui32Pass == 0)
930                                         {
931                                                 ui32AllocSize += ui32Size;
932                                                 ui32AllocSize2 += ui32Size2;
933                                         }
934                                         else
935                                         {
936                                                 psServerSyncInt[i] = (SERVER_SYNC_PRIMITIVE * *) pui8Ptr;
937                                                 pui8Ptr += ui32Size;
938                                                 hServerSyncInt2[i] = (IMG_HANDLE *) pui8Ptr2;
939                                                 pui8Ptr2 += ui32Size2;
940                                         }
941                                 }
942                         }
943                 }
944         }
945
946         {
947                 IMG_UINT32 i;
948                 IMG_HANDLE **psPtr;
949
950                 /* Loop over all the pointers in the array copying the data into the kernel */
951                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
952                 {
953                         /* Copy the pointer over from the client side */
954                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->phServerSync[i], sizeof(IMG_HANDLE **))
955                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->phServerSync[i],
956                                 sizeof(IMG_HANDLE **)) != PVRSRV_OK) )
957                         {
958                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
959
960                                 goto RGXSubmitTransfer_exit;
961                         }
962                         /* Copy the data over */
963                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE)))
964                                 || (OSCopyFromUser(NULL, (hServerSyncInt2[i]), psPtr,
965                                 (ui32ServerSyncCountInt[i] * sizeof(IMG_HANDLE))) != PVRSRV_OK) )
966                         {
967                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
968
969                                 goto RGXSubmitTransfer_exit;
970                         }
971                 }
972         }
973         if (psRGXSubmitTransferIN->ui32NumCheckFenceFDs != 0)
974         {
975                 i32CheckFenceFDsInt = OSAllocMem(psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
976                 if (!i32CheckFenceFDsInt)
977                 {
978                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
979         
980                         goto RGXSubmitTransfer_exit;
981                 }
982         }
983
984                         /* Copy the data over */
985                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pi32CheckFenceFDs, psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
986                                 || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXSubmitTransferIN->pi32CheckFenceFDs,
987                                 psRGXSubmitTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
988                         {
989                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
990
991                                 goto RGXSubmitTransfer_exit;
992                         }
993         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
994         {
995                 ui32CommandSizeInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
996                 if (!ui32CommandSizeInt)
997                 {
998                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
999         
1000                         goto RGXSubmitTransfer_exit;
1001                 }
1002         }
1003
1004                         /* Copy the data over */
1005                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32CommandSize, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
1006                                 || (OSCopyFromUser(NULL, ui32CommandSizeInt, psRGXSubmitTransferIN->pui32CommandSize,
1007                                 psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1008                         {
1009                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1010
1011                                 goto RGXSubmitTransfer_exit;
1012                         }
1013         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
1014         {
1015                 IMG_UINT32 ui32Pass=0;
1016                 IMG_UINT32 i;
1017                 IMG_UINT32 ui32AllocSize=0;
1018                 IMG_UINT32 ui32Size;
1019                 IMG_UINT8 *pui8Ptr = IMG_NULL;
1020
1021                 /*
1022                         Two pass loop, 1st find out the size and 2nd allocation and set offsets.
1023                         Keeps allocation cost down and simplifies the free path
1024                 */
1025                 for (ui32Pass=0;ui32Pass<2;ui32Pass++)
1026                 {
1027                         ui32Size = psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT8 *);
1028                         if (ui32Pass == 0)
1029                         {
1030                                 ui32AllocSize += ui32Size;
1031                         }
1032                         else
1033                         {
1034                                 pui8Ptr = OSAllocMem(ui32AllocSize);
1035                                 if (pui8Ptr == IMG_NULL)
1036                                 {
1037                                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1038                                         goto RGXSubmitTransfer_exit;
1039                                 }
1040                                 ui8FWCommandInt = (IMG_UINT8 **) pui8Ptr;
1041                                 pui8Ptr += ui32Size;
1042                         }
1043                         
1044                         for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1045                         {
1046                                 ui32Size = ui32CommandSizeInt[i] * sizeof(IMG_UINT8);           
1047                                 if (ui32Size)
1048                                 {
1049                                         if (ui32Pass == 0)
1050                                         {
1051                                                 ui32AllocSize += ui32Size;
1052                                         }
1053                                         else
1054                                         {
1055                                                 ui8FWCommandInt[i] = (IMG_UINT8 *) pui8Ptr;
1056                                                 pui8Ptr += ui32Size;
1057                                         }
1058                                 }
1059                         }
1060                 }
1061         }
1062
1063         {
1064                 IMG_UINT32 i;
1065                 IMG_UINT8 **psPtr;
1066
1067                 /* Loop over all the pointers in the array copying the data into the kernel */
1068                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1069                 {
1070                         /* Copy the pointer over from the client side */
1071                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) &psRGXSubmitTransferIN->pui8FWCommand[i], sizeof(IMG_UINT8 **))
1072                                 || (OSCopyFromUser(NULL, &psPtr, &psRGXSubmitTransferIN->pui8FWCommand[i],
1073                                 sizeof(IMG_UINT8 **)) != PVRSRV_OK) )
1074                         {
1075                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1076
1077                                 goto RGXSubmitTransfer_exit;
1078                         }
1079                         /* Copy the data over */
1080                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psPtr, (ui32CommandSizeInt[i] * sizeof(IMG_UINT8)))
1081                                 || (OSCopyFromUser(NULL, (ui8FWCommandInt[i]), psPtr,
1082                                 (ui32CommandSizeInt[i] * sizeof(IMG_UINT8))) != PVRSRV_OK) )
1083                         {
1084                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1085
1086                                 goto RGXSubmitTransfer_exit;
1087                         }
1088                 }
1089         }
1090         if (psRGXSubmitTransferIN->ui32PrepareCount != 0)
1091         {
1092                 ui32TQPrepareFlagsInt = OSAllocMem(psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32));
1093                 if (!ui32TQPrepareFlagsInt)
1094                 {
1095                         psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1096         
1097                         goto RGXSubmitTransfer_exit;
1098                 }
1099         }
1100
1101                         /* Copy the data over */
1102                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXSubmitTransferIN->pui32TQPrepareFlags, psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32))
1103                                 || (OSCopyFromUser(NULL, ui32TQPrepareFlagsInt, psRGXSubmitTransferIN->pui32TQPrepareFlags,
1104                                 psRGXSubmitTransferIN->ui32PrepareCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1105                         {
1106                                 psRGXSubmitTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1107
1108                                 goto RGXSubmitTransfer_exit;
1109                         }
1110
1111
1112
1113                                 {
1114                                         /* Look up the address from the handle */
1115                                         psRGXSubmitTransferOUT->eError =
1116                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1117                                                                                         (IMG_VOID **) &psTransferContextInt,
1118                                                                                         psRGXSubmitTransferIN->hTransferContext,
1119                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
1120                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1121                                         {
1122                                                 goto RGXSubmitTransfer_exit;
1123                                         }
1124                                 }
1125
1126
1127         {
1128                 IMG_UINT32 i;
1129
1130                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1131                 {
1132                         IMG_UINT32 j;
1133                         for (j=0;j<ui32ClientFenceCountInt[i];j++)
1134                         {
1135                                 {
1136                                         /* Look up the address from the handle */
1137                                         psRGXSubmitTransferOUT->eError =
1138                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1139                                                                                         (IMG_VOID **) &psFenceUFOSyncPrimBlockInt[i][j],
1140                                                                                         hFenceUFOSyncPrimBlockInt2[i][j],
1141                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1142                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1143                                         {
1144                                                 goto RGXSubmitTransfer_exit;
1145                                         }
1146                                 }
1147
1148                         }
1149                 }
1150         }
1151
1152         {
1153                 IMG_UINT32 i;
1154
1155                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1156                 {
1157                         IMG_UINT32 j;
1158                         for (j=0;j<ui32ClientUpdateCountInt[i];j++)
1159                         {
1160                                 {
1161                                         /* Look up the address from the handle */
1162                                         psRGXSubmitTransferOUT->eError =
1163                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1164                                                                                         (IMG_VOID **) &psUpdateUFOSyncPrimBlockInt[i][j],
1165                                                                                         hUpdateUFOSyncPrimBlockInt2[i][j],
1166                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1167                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1168                                         {
1169                                                 goto RGXSubmitTransfer_exit;
1170                                         }
1171                                 }
1172
1173                         }
1174                 }
1175         }
1176
1177         {
1178                 IMG_UINT32 i;
1179
1180                 for (i=0;i<psRGXSubmitTransferIN->ui32PrepareCount;i++)
1181                 {
1182                         IMG_UINT32 j;
1183                         for (j=0;j<ui32ServerSyncCountInt[i];j++)
1184                         {
1185                                 {
1186                                         /* Look up the address from the handle */
1187                                         psRGXSubmitTransferOUT->eError =
1188                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1189                                                                                         (IMG_VOID **) &psServerSyncInt[i][j],
1190                                                                                         hServerSyncInt2[i][j],
1191                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
1192                                         if(psRGXSubmitTransferOUT->eError != PVRSRV_OK)
1193                                         {
1194                                                 goto RGXSubmitTransfer_exit;
1195                                         }
1196                                 }
1197
1198                         }
1199                 }
1200         }
1201
1202         psRGXSubmitTransferOUT->eError =
1203                 PVRSRVRGXSubmitTransferKM(
1204                                         psTransferContextInt,
1205                                         psRGXSubmitTransferIN->ui32PrepareCount,
1206                                         ui32ClientFenceCountInt,
1207                                         psFenceUFOSyncPrimBlockInt,
1208                                         ui32FenceSyncOffsetInt,
1209                                         ui32FenceValueInt,
1210                                         ui32ClientUpdateCountInt,
1211                                         psUpdateUFOSyncPrimBlockInt,
1212                                         ui32UpdateSyncOffsetInt,
1213                                         ui32UpdateValueInt,
1214                                         ui32ServerSyncCountInt,
1215                                         ui32ServerSyncFlagsInt,
1216                                         psServerSyncInt,
1217                                         psRGXSubmitTransferIN->ui32NumCheckFenceFDs,
1218                                         i32CheckFenceFDsInt,
1219                                         psRGXSubmitTransferIN->i32UpdateFenceFD,
1220                                         ui32CommandSizeInt,
1221                                         ui8FWCommandInt,
1222                                         ui32TQPrepareFlagsInt,
1223                                         psRGXSubmitTransferIN->ui32ExternalJobReference,
1224                                         psRGXSubmitTransferIN->ui32InternalJobReference);
1225
1226
1227
1228
1229 RGXSubmitTransfer_exit:
1230         if (ui32ClientFenceCountInt)
1231                 OSFreeMem(ui32ClientFenceCountInt);
1232         if (psFenceUFOSyncPrimBlockInt)
1233                 OSFreeMem(psFenceUFOSyncPrimBlockInt);
1234         if (hFenceUFOSyncPrimBlockInt2)
1235                 OSFreeMem(hFenceUFOSyncPrimBlockInt2);
1236         if (ui32FenceSyncOffsetInt)
1237                 OSFreeMem(ui32FenceSyncOffsetInt);
1238         if (ui32FenceValueInt)
1239                 OSFreeMem(ui32FenceValueInt);
1240         if (ui32ClientUpdateCountInt)
1241                 OSFreeMem(ui32ClientUpdateCountInt);
1242         if (psUpdateUFOSyncPrimBlockInt)
1243                 OSFreeMem(psUpdateUFOSyncPrimBlockInt);
1244         if (hUpdateUFOSyncPrimBlockInt2)
1245                 OSFreeMem(hUpdateUFOSyncPrimBlockInt2);
1246         if (ui32UpdateSyncOffsetInt)
1247                 OSFreeMem(ui32UpdateSyncOffsetInt);
1248         if (ui32UpdateValueInt)
1249                 OSFreeMem(ui32UpdateValueInt);
1250         if (ui32ServerSyncCountInt)
1251                 OSFreeMem(ui32ServerSyncCountInt);
1252         if (ui32ServerSyncFlagsInt)
1253                 OSFreeMem(ui32ServerSyncFlagsInt);
1254         if (psServerSyncInt)
1255                 OSFreeMem(psServerSyncInt);
1256         if (hServerSyncInt2)
1257                 OSFreeMem(hServerSyncInt2);
1258         if (i32CheckFenceFDsInt)
1259                 OSFreeMem(i32CheckFenceFDsInt);
1260         if (ui32CommandSizeInt)
1261                 OSFreeMem(ui32CommandSizeInt);
1262         if (ui8FWCommandInt)
1263                 OSFreeMem(ui8FWCommandInt);
1264         if (ui32TQPrepareFlagsInt)
1265                 OSFreeMem(ui32TQPrepareFlagsInt);
1266
1267         return 0;
1268 }
1269
1270 static IMG_INT
1271 PVRSRVBridgeRGXSetTransferContextPriority(IMG_UINT32 ui32DispatchTableEntry,
1272                                           PVRSRV_BRIDGE_IN_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityIN,
1273                                           PVRSRV_BRIDGE_OUT_RGXSETTRANSFERCONTEXTPRIORITY *psRGXSetTransferContextPriorityOUT,
1274                                          CONNECTION_DATA *psConnection)
1275 {
1276         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
1277
1278
1279
1280
1281
1282
1283
1284                                 {
1285                                         /* Look up the address from the handle */
1286                                         psRGXSetTransferContextPriorityOUT->eError =
1287                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1288                                                                                         (IMG_VOID **) &psTransferContextInt,
1289                                                                                         psRGXSetTransferContextPriorityIN->hTransferContext,
1290                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
1291                                         if(psRGXSetTransferContextPriorityOUT->eError != PVRSRV_OK)
1292                                         {
1293                                                 goto RGXSetTransferContextPriority_exit;
1294                                         }
1295                                 }
1296
1297
1298         psRGXSetTransferContextPriorityOUT->eError =
1299                 PVRSRVRGXSetTransferContextPriorityKM(psConnection,
1300                                         psTransferContextInt,
1301                                         psRGXSetTransferContextPriorityIN->ui32Priority);
1302
1303
1304
1305
1306 RGXSetTransferContextPriority_exit:
1307
1308         return 0;
1309 }
1310
1311 static IMG_INT
1312 PVRSRVBridgeRGXKickSyncTransfer(IMG_UINT32 ui32DispatchTableEntry,
1313                                           PVRSRV_BRIDGE_IN_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferIN,
1314                                           PVRSRV_BRIDGE_OUT_RGXKICKSYNCTRANSFER *psRGXKickSyncTransferOUT,
1315                                          CONNECTION_DATA *psConnection)
1316 {
1317         RGX_SERVER_TQ_CONTEXT * psTransferContextInt = IMG_NULL;
1318         SYNC_PRIMITIVE_BLOCK * *psClientFenceUFOSyncPrimBlockInt = IMG_NULL;
1319         IMG_HANDLE *hClientFenceUFOSyncPrimBlockInt2 = IMG_NULL;
1320         IMG_UINT32 *ui32ClientFenceSyncOffsetInt = IMG_NULL;
1321         IMG_UINT32 *ui32ClientFenceValueInt = IMG_NULL;
1322         SYNC_PRIMITIVE_BLOCK * *psClientUpdateUFOSyncPrimBlockInt = IMG_NULL;
1323         IMG_HANDLE *hClientUpdateUFOSyncPrimBlockInt2 = IMG_NULL;
1324         IMG_UINT32 *ui32ClientUpdateSyncOffsetInt = IMG_NULL;
1325         IMG_UINT32 *ui32ClientUpdateValueInt = IMG_NULL;
1326         IMG_UINT32 *ui32ServerSyncFlagsInt = IMG_NULL;
1327         SERVER_SYNC_PRIMITIVE * *psServerSyncsInt = IMG_NULL;
1328         IMG_HANDLE *hServerSyncsInt2 = IMG_NULL;
1329         IMG_INT32 *i32CheckFenceFDsInt = IMG_NULL;
1330
1331
1332
1333
1334         if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
1335         {
1336                 psClientFenceUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
1337                 if (!psClientFenceUFOSyncPrimBlockInt)
1338                 {
1339                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1340         
1341                         goto RGXKickSyncTransfer_exit;
1342                 }
1343                 hClientFenceUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE));
1344                 if (!hClientFenceUFOSyncPrimBlockInt2)
1345                 {
1346                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1347         
1348                         goto RGXKickSyncTransfer_exit;
1349                 }
1350         }
1351
1352                         /* Copy the data over */
1353                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE))
1354                                 || (OSCopyFromUser(NULL, hClientFenceUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientFenceUFOSyncPrimBlock,
1355                                 psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
1356                         {
1357                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1358
1359                                 goto RGXKickSyncTransfer_exit;
1360                         }
1361         if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
1362         {
1363                 ui32ClientFenceSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
1364                 if (!ui32ClientFenceSyncOffsetInt)
1365                 {
1366                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1367         
1368                         goto RGXKickSyncTransfer_exit;
1369                 }
1370         }
1371
1372                         /* Copy the data over */
1373                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
1374                                 || (OSCopyFromUser(NULL, ui32ClientFenceSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientFenceSyncOffset,
1375                                 psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1376                         {
1377                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1378
1379                                 goto RGXKickSyncTransfer_exit;
1380                         }
1381         if (psRGXKickSyncTransferIN->ui32ClientFenceCount != 0)
1382         {
1383                 ui32ClientFenceValueInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32));
1384                 if (!ui32ClientFenceValueInt)
1385                 {
1386                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1387         
1388                         goto RGXKickSyncTransfer_exit;
1389                 }
1390         }
1391
1392                         /* Copy the data over */
1393                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientFenceValue, psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32))
1394                                 || (OSCopyFromUser(NULL, ui32ClientFenceValueInt, psRGXKickSyncTransferIN->pui32ClientFenceValue,
1395                                 psRGXKickSyncTransferIN->ui32ClientFenceCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1396                         {
1397                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1398
1399                                 goto RGXKickSyncTransfer_exit;
1400                         }
1401         if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
1402         {
1403                 psClientUpdateUFOSyncPrimBlockInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(SYNC_PRIMITIVE_BLOCK *));
1404                 if (!psClientUpdateUFOSyncPrimBlockInt)
1405                 {
1406                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1407         
1408                         goto RGXKickSyncTransfer_exit;
1409                 }
1410                 hClientUpdateUFOSyncPrimBlockInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE));
1411                 if (!hClientUpdateUFOSyncPrimBlockInt2)
1412                 {
1413                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1414         
1415                         goto RGXKickSyncTransfer_exit;
1416                 }
1417         }
1418
1419                         /* Copy the data over */
1420                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE))
1421                                 || (OSCopyFromUser(NULL, hClientUpdateUFOSyncPrimBlockInt2, psRGXKickSyncTransferIN->phClientUpdateUFOSyncPrimBlock,
1422                                 psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
1423                         {
1424                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1425
1426                                 goto RGXKickSyncTransfer_exit;
1427                         }
1428         if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
1429         {
1430                 ui32ClientUpdateSyncOffsetInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
1431                 if (!ui32ClientUpdateSyncOffsetInt)
1432                 {
1433                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1434         
1435                         goto RGXKickSyncTransfer_exit;
1436                 }
1437         }
1438
1439                         /* Copy the data over */
1440                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
1441                                 || (OSCopyFromUser(NULL, ui32ClientUpdateSyncOffsetInt, psRGXKickSyncTransferIN->pui32ClientUpdateSyncOffset,
1442                                 psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1443                         {
1444                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1445
1446                                 goto RGXKickSyncTransfer_exit;
1447                         }
1448         if (psRGXKickSyncTransferIN->ui32ClientUpdateCount != 0)
1449         {
1450                 ui32ClientUpdateValueInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32));
1451                 if (!ui32ClientUpdateValueInt)
1452                 {
1453                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1454         
1455                         goto RGXKickSyncTransfer_exit;
1456                 }
1457         }
1458
1459                         /* Copy the data over */
1460                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ClientUpdateValue, psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32))
1461                                 || (OSCopyFromUser(NULL, ui32ClientUpdateValueInt, psRGXKickSyncTransferIN->pui32ClientUpdateValue,
1462                                 psRGXKickSyncTransferIN->ui32ClientUpdateCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1463                         {
1464                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1465
1466                                 goto RGXKickSyncTransfer_exit;
1467                         }
1468         if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
1469         {
1470                 ui32ServerSyncFlagsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32));
1471                 if (!ui32ServerSyncFlagsInt)
1472                 {
1473                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1474         
1475                         goto RGXKickSyncTransfer_exit;
1476                 }
1477         }
1478
1479                         /* Copy the data over */
1480                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pui32ServerSyncFlags, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32))
1481                                 || (OSCopyFromUser(NULL, ui32ServerSyncFlagsInt, psRGXKickSyncTransferIN->pui32ServerSyncFlags,
1482                                 psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_UINT32)) != PVRSRV_OK) )
1483                         {
1484                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1485
1486                                 goto RGXKickSyncTransfer_exit;
1487                         }
1488         if (psRGXKickSyncTransferIN->ui32ServerSyncCount != 0)
1489         {
1490                 psServerSyncsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(SERVER_SYNC_PRIMITIVE *));
1491                 if (!psServerSyncsInt)
1492                 {
1493                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1494         
1495                         goto RGXKickSyncTransfer_exit;
1496                 }
1497                 hServerSyncsInt2 = OSAllocMem(psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE));
1498                 if (!hServerSyncsInt2)
1499                 {
1500                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1501         
1502                         goto RGXKickSyncTransfer_exit;
1503                 }
1504         }
1505
1506                         /* Copy the data over */
1507                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->phServerSyncs, psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE))
1508                                 || (OSCopyFromUser(NULL, hServerSyncsInt2, psRGXKickSyncTransferIN->phServerSyncs,
1509                                 psRGXKickSyncTransferIN->ui32ServerSyncCount * sizeof(IMG_HANDLE)) != PVRSRV_OK) )
1510                         {
1511                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1512
1513                                 goto RGXKickSyncTransfer_exit;
1514                         }
1515         if (psRGXKickSyncTransferIN->ui32NumCheckFenceFDs != 0)
1516         {
1517                 i32CheckFenceFDsInt = OSAllocMem(psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32));
1518                 if (!i32CheckFenceFDsInt)
1519                 {
1520                         psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1521         
1522                         goto RGXKickSyncTransfer_exit;
1523                 }
1524         }
1525
1526                         /* Copy the data over */
1527                         if ( !OSAccessOK(PVR_VERIFY_READ, (IMG_VOID*) psRGXKickSyncTransferIN->pi32CheckFenceFDs, psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32))
1528                                 || (OSCopyFromUser(NULL, i32CheckFenceFDsInt, psRGXKickSyncTransferIN->pi32CheckFenceFDs,
1529                                 psRGXKickSyncTransferIN->ui32NumCheckFenceFDs * sizeof(IMG_INT32)) != PVRSRV_OK) )
1530                         {
1531                                 psRGXKickSyncTransferOUT->eError = PVRSRV_ERROR_INVALID_PARAMS;
1532
1533                                 goto RGXKickSyncTransfer_exit;
1534                         }
1535
1536
1537
1538                                 {
1539                                         /* Look up the address from the handle */
1540                                         psRGXKickSyncTransferOUT->eError =
1541                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1542                                                                                         (IMG_VOID **) &psTransferContextInt,
1543                                                                                         psRGXKickSyncTransferIN->hTransferContext,
1544                                                                                         PVRSRV_HANDLE_TYPE_RGX_SERVER_TQ_CONTEXT);
1545                                         if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
1546                                         {
1547                                                 goto RGXKickSyncTransfer_exit;
1548                                         }
1549                                 }
1550
1551
1552         {
1553                 IMG_UINT32 i;
1554
1555                 for (i=0;i<psRGXKickSyncTransferIN->ui32ClientFenceCount;i++)
1556                 {
1557                                 {
1558                                         /* Look up the address from the handle */
1559                                         psRGXKickSyncTransferOUT->eError =
1560                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1561                                                                                         (IMG_VOID **) &psClientFenceUFOSyncPrimBlockInt[i],
1562                                                                                         hClientFenceUFOSyncPrimBlockInt2[i],
1563                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1564                                         if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
1565                                         {
1566                                                 goto RGXKickSyncTransfer_exit;
1567                                         }
1568                                 }
1569
1570                 }
1571         }
1572
1573         {
1574                 IMG_UINT32 i;
1575
1576                 for (i=0;i<psRGXKickSyncTransferIN->ui32ClientUpdateCount;i++)
1577                 {
1578                                 {
1579                                         /* Look up the address from the handle */
1580                                         psRGXKickSyncTransferOUT->eError =
1581                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1582                                                                                         (IMG_VOID **) &psClientUpdateUFOSyncPrimBlockInt[i],
1583                                                                                         hClientUpdateUFOSyncPrimBlockInt2[i],
1584                                                                                         PVRSRV_HANDLE_TYPE_SYNC_PRIMITIVE_BLOCK);
1585                                         if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
1586                                         {
1587                                                 goto RGXKickSyncTransfer_exit;
1588                                         }
1589                                 }
1590
1591                 }
1592         }
1593
1594         {
1595                 IMG_UINT32 i;
1596
1597                 for (i=0;i<psRGXKickSyncTransferIN->ui32ServerSyncCount;i++)
1598                 {
1599                                 {
1600                                         /* Look up the address from the handle */
1601                                         psRGXKickSyncTransferOUT->eError =
1602                                                 PVRSRVLookupHandle(psConnection->psHandleBase,
1603                                                                                         (IMG_VOID **) &psServerSyncsInt[i],
1604                                                                                         hServerSyncsInt2[i],
1605                                                                                         PVRSRV_HANDLE_TYPE_SERVER_SYNC_PRIMITIVE);
1606                                         if(psRGXKickSyncTransferOUT->eError != PVRSRV_OK)
1607                                         {
1608                                                 goto RGXKickSyncTransfer_exit;
1609                                         }
1610                                 }
1611
1612                 }
1613         }
1614
1615         psRGXKickSyncTransferOUT->eError =
1616                 PVRSRVRGXKickSyncTransferKM(
1617                                         psTransferContextInt,
1618                                         psRGXKickSyncTransferIN->ui32ClientFenceCount,
1619                                         psClientFenceUFOSyncPrimBlockInt,
1620                                         ui32ClientFenceSyncOffsetInt,
1621                                         ui32ClientFenceValueInt,
1622                                         psRGXKickSyncTransferIN->ui32ClientUpdateCount,
1623                                         psClientUpdateUFOSyncPrimBlockInt,
1624                                         ui32ClientUpdateSyncOffsetInt,
1625                                         ui32ClientUpdateValueInt,
1626                                         psRGXKickSyncTransferIN->ui32ServerSyncCount,
1627                                         ui32ServerSyncFlagsInt,
1628                                         psServerSyncsInt,
1629                                         psRGXKickSyncTransferIN->ui32NumCheckFenceFDs,
1630                                         i32CheckFenceFDsInt,
1631                                         psRGXKickSyncTransferIN->i32UpdateFenceFD,
1632                                         psRGXKickSyncTransferIN->ui32TQPrepareFlags);
1633
1634
1635
1636
1637 RGXKickSyncTransfer_exit:
1638         if (psClientFenceUFOSyncPrimBlockInt)
1639                 OSFreeMem(psClientFenceUFOSyncPrimBlockInt);
1640         if (hClientFenceUFOSyncPrimBlockInt2)
1641                 OSFreeMem(hClientFenceUFOSyncPrimBlockInt2);
1642         if (ui32ClientFenceSyncOffsetInt)
1643                 OSFreeMem(ui32ClientFenceSyncOffsetInt);
1644         if (ui32ClientFenceValueInt)
1645                 OSFreeMem(ui32ClientFenceValueInt);
1646         if (psClientUpdateUFOSyncPrimBlockInt)
1647                 OSFreeMem(psClientUpdateUFOSyncPrimBlockInt);
1648         if (hClientUpdateUFOSyncPrimBlockInt2)
1649                 OSFreeMem(hClientUpdateUFOSyncPrimBlockInt2);
1650         if (ui32ClientUpdateSyncOffsetInt)
1651                 OSFreeMem(ui32ClientUpdateSyncOffsetInt);
1652         if (ui32ClientUpdateValueInt)
1653                 OSFreeMem(ui32ClientUpdateValueInt);
1654         if (ui32ServerSyncFlagsInt)
1655                 OSFreeMem(ui32ServerSyncFlagsInt);
1656         if (psServerSyncsInt)
1657                 OSFreeMem(psServerSyncsInt);
1658         if (hServerSyncsInt2)
1659                 OSFreeMem(hServerSyncsInt2);
1660         if (i32CheckFenceFDsInt)
1661                 OSFreeMem(i32CheckFenceFDsInt);
1662
1663         return 0;
1664 }
1665
1666
1667
1668 /* *************************************************************************** 
1669  * Server bridge dispatch related glue 
1670  */
1671
1672
1673 PVRSRV_ERROR InitRGXTQBridge(IMG_VOID);
1674 PVRSRV_ERROR DeinitRGXTQBridge(IMG_VOID);
1675
1676 /*
1677  * Register all RGXTQ functions with services
1678  */
1679 PVRSRV_ERROR InitRGXTQBridge(IMG_VOID)
1680 {
1681
1682         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXCREATETRANSFERCONTEXT, PVRSRVBridgeRGXCreateTransferContext,
1683                                         IMG_NULL, IMG_NULL,
1684                                         0, 0);
1685
1686         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXDESTROYTRANSFERCONTEXT, PVRSRVBridgeRGXDestroyTransferContext,
1687                                         IMG_NULL, IMG_NULL,
1688                                         0, 0);
1689
1690         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSUBMITTRANSFER, PVRSRVBridgeRGXSubmitTransfer,
1691                                         IMG_NULL, IMG_NULL,
1692                                         0, 0);
1693
1694         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXSETTRANSFERCONTEXTPRIORITY, PVRSRVBridgeRGXSetTransferContextPriority,
1695                                         IMG_NULL, IMG_NULL,
1696                                         0, 0);
1697
1698         SetDispatchTableEntry(PVRSRV_BRIDGE_RGXTQ, PVRSRV_BRIDGE_RGXTQ_RGXKICKSYNCTRANSFER, PVRSRVBridgeRGXKickSyncTransfer,
1699                                         IMG_NULL, IMG_NULL,
1700                                         0, 0);
1701
1702
1703         return PVRSRV_OK;
1704 }
1705
1706 /*
1707  * Unregister all rgxtq functions with services
1708  */
1709 PVRSRV_ERROR DeinitRGXTQBridge(IMG_VOID)
1710 {
1711         return PVRSRV_OK;
1712 }
1713