0f41e881acc6fe4693dd3fc2a214193c03e9c325
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue / services / shared / common / sync.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Services synchronisation interface
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Implements client side code for services synchronisation
6                 interface
7 @License        Dual MIT/GPLv2
8
9 The contents of this file are subject to the MIT license as set out below.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
20
21 Alternatively, the contents of this file may be used under the terms of
22 the GNU General Public License Version 2 ("GPL") in which case the provisions
23 of GPL are applicable instead of those above.
24
25 If you wish to allow use of your version of this file only under the terms of
26 GPL, and not to allow others to use your version of this file under the terms
27 of the MIT license, indicate your decision by deleting the provisions above
28 and replace them with the notice and other provisions required by GPL as set
29 out in the file called "GPL-COPYING" included in this distribution. If you do
30 not delete the provisions above, a recipient may use your version of this file
31 under the terms of either the MIT license or GPL.
32
33 This License is also included in this distribution in the file called
34 "MIT-COPYING".
35
36 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
37 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
39 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
40 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 */ /**************************************************************************/
44
45 #include "img_types.h"
46 #include "client_sync_bridge.h"
47 #include "allocmem.h"
48 #include "osfunc.h"
49 #include "devicemem.h"
50 #include "devicemem_pdump.h"
51 #include "pvr_debug.h"
52 #include "dllist.h"
53 #include "sync.h"
54 #include "sync_internal.h"
55 #include "lock.h"
56 #include "pvr_debug.h"
57
58 #if defined(__KERNEL__)
59 #include "pvrsrv.h"
60 #endif
61
62
63 #define SYNC_BLOCK_LIST_CHUNCK_SIZE     10
64
65 /*
66         This defines the maximum amount of synchronisation memory
67         that can be allocated per SyncPrim context.
68         In reality this number is meaningless as we would run out
69         of synchronisation memory before we reach this limit, but
70         we need to provide a size to the span RA.
71 */
72 #define MAX_SYNC_MEM                            (4 * 1024 * 1024)
73
74 typedef struct _SYNC_BLOCK_LIST_
75 {
76         IMG_UINT32                      ui32BlockCount;                 /*!< Number of contexts in the list */
77         IMG_UINT32                      ui32BlockListSize;              /*!< Size of the array contexts */
78         SYNC_PRIM_BLOCK         **papsSyncPrimBlock;    /*!< Array of syncprim blocks */
79 } SYNC_BLOCK_LIST;
80
81 typedef struct _SYNC_OP_COOKIE_
82 {
83         IMG_UINT32                              ui32SyncCount;
84         IMG_UINT32                              ui32ClientSyncCount;
85         IMG_UINT32                              ui32ServerSyncCount;
86         IMG_BOOL                                bHaveServerSync;
87         IMG_HANDLE                              hBridge;
88         IMG_HANDLE                              hServerCookie;
89
90         SYNC_BLOCK_LIST                 *psSyncBlockList;
91         PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim;
92         /*
93                 Client sync(s) info.
94                 If this changes update the calculation of ui32ClientAllocSize
95         */
96         IMG_UINT32                              *paui32SyncBlockIndex;
97         IMG_UINT32                              *paui32Index;
98         IMG_UINT32                              *paui32Flags;
99         IMG_UINT32                              *paui32FenceValue;
100         IMG_UINT32                              *paui32UpdateValue;
101
102         /*
103                 Server sync(s) info
104                 If this changes update the calculation of ui32ServerAllocSize
105         */
106         IMG_HANDLE                              *pahServerSync;
107         IMG_UINT32              *paui32ServerFlags;
108 } SYNC_OP_COOKIE;
109
110 /*
111         Internal interfaces for management of synchronisation block memory
112 */
113 static PVRSRV_ERROR
114 AllocSyncPrimitiveBlock(SYNC_PRIM_CONTEXT *psContext,
115                                                 SYNC_PRIM_BLOCK **ppsSyncBlock)
116 {
117         SYNC_PRIM_BLOCK *psSyncBlk;
118         DEVMEM_SERVER_EXPORTCOOKIE hServerExportCookie;
119         DEVMEM_EXPORTCOOKIE sExportCookie;
120         PVRSRV_ERROR eError;
121
122         psSyncBlk = OSAllocMem(sizeof(SYNC_PRIM_BLOCK));
123         if (psSyncBlk == IMG_NULL)
124         {
125                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
126                 goto fail_alloc;
127         }
128         psSyncBlk->psContext = psContext;
129
130         /* Allocate sync prim block */
131         eError = BridgeAllocSyncPrimitiveBlock(psContext->hBridge,
132                                                                                    psContext->hDeviceNode,
133                                                                                    &psSyncBlk->hServerSyncPrimBlock,
134                                                                                    &psSyncBlk->ui32FirmwareAddr,
135                                                                                    &psSyncBlk->ui32SyncBlockSize,
136                                                                                    &hServerExportCookie);
137         if (eError != PVRSRV_OK)
138         {
139                 goto fail_blockalloc;
140         }
141
142         /* Make it mappable by the client */
143         eError = DevmemMakeServerExportClientExport(psContext->hBridge,
144                                                                                                 hServerExportCookie,
145                                                                                                 &sExportCookie);
146         if (eError != PVRSRV_OK)
147         {
148                 goto fail_export;
149         }
150
151         /* Get CPU mapping of the memory block */
152         eError = DevmemImport(psContext->hBridge,
153                                                   &sExportCookie,
154                                                   PVRSRV_MEMALLOCFLAG_CPU_READABLE,
155                                                   &psSyncBlk->hMemDesc);
156
157         /*
158                 Regardless of success or failure we "undo" the export
159         */
160         DevmemUnmakeServerExportClientExport(psContext->hBridge,
161                                                                                  &sExportCookie);
162
163         if (eError != PVRSRV_OK)
164         {
165                 goto fail_import;
166         }
167
168         eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc,
169                                                                           (IMG_PVOID *) &psSyncBlk->pui32LinAddr);
170         if (eError != PVRSRV_OK)
171         {
172                 goto fail_cpuvaddr;
173         }
174
175         *ppsSyncBlock = psSyncBlk;
176         return PVRSRV_OK;
177
178 fail_cpuvaddr:
179         DevmemFree(psSyncBlk->hMemDesc);
180 fail_import:
181 fail_export:
182         BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
183                                                                  psSyncBlk->hServerSyncPrimBlock);
184 fail_blockalloc:
185         OSFreeMem(psSyncBlk);
186 fail_alloc:
187         return eError;
188 }
189
190 static IMG_VOID
191 FreeSyncPrimitiveBlock(SYNC_PRIM_BLOCK *psSyncBlk)
192 {
193         SYNC_PRIM_CONTEXT *psContext = psSyncBlk->psContext;
194
195         DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc);
196         DevmemFree(psSyncBlk->hMemDesc);
197         BridgeFreeSyncPrimitiveBlock(psContext->hBridge,
198                                                                  psSyncBlk->hServerSyncPrimBlock);
199         OSFreeMem(psSyncBlk);
200 }
201
202 static IMG_BOOL
203 SyncPrimBlockImport(RA_PERARENA_HANDLE hArena,
204                                         RA_LENGTH_T uSize,
205                                         RA_FLAGS_T uFlags,
206                                         RA_BASE_T *puiBase,
207                                         RA_LENGTH_T *puiActualSize,
208                                         RA_PERISPAN_HANDLE *phImport)
209 {
210         SYNC_PRIM_CONTEXT *psContext = hArena;
211         SYNC_PRIM_BLOCK *psSyncBlock = IMG_NULL;
212         RA_LENGTH_T uiSpanSize;
213         PVRSRV_ERROR eError;
214         IMG_BOOL bRet;
215         PVR_UNREFERENCED_PARAMETER(uFlags);
216
217         PVR_ASSERT(hArena != IMG_NULL);
218
219         /* Check we've not be called with an unexpected size */
220         PVR_ASSERT(uSize == sizeof(IMG_UINT32));
221
222         /*
223                 Ensure the synprim context doesn't go away while we have sync blocks
224                 attached to it
225         */
226         OSLockAcquire(psContext->hLock);
227         psContext->ui32RefCount++;
228         OSLockRelease(psContext->hLock);
229
230         /* Allocate the block of memory */
231         eError = AllocSyncPrimitiveBlock(psContext, &psSyncBlock);
232         if (eError != PVRSRV_OK)
233         {
234                 PVR_DPF((PVR_DBG_ERROR, "Failed to allocation syncprim block (%d)", eError));
235                 goto fail_syncblockalloc;
236         }
237
238         /* Allocate a span for it */
239         bRet = RA_Alloc(psContext->psSpanRA,
240                                         psSyncBlock->ui32SyncBlockSize,
241                                         0,
242                                         psSyncBlock->ui32SyncBlockSize,
243                                         &psSyncBlock->uiSpanBase,
244                                         &uiSpanSize,
245                                         IMG_NULL);
246         if (bRet == IMG_FALSE)
247         {
248                 goto fail_spanalloc;
249         }
250
251         /*
252                 There is no reason the span RA should return an allocation larger
253                 then we request
254         */
255         PVR_ASSERT(uiSpanSize == psSyncBlock->ui32SyncBlockSize);
256
257         *puiBase = psSyncBlock->uiSpanBase;
258         *puiActualSize = psSyncBlock->ui32SyncBlockSize;
259         *phImport = psSyncBlock;
260         return IMG_TRUE;
261
262 fail_spanalloc:
263         FreeSyncPrimitiveBlock(psSyncBlock);
264 fail_syncblockalloc:
265         OSLockAcquire(psContext->hLock);
266         psContext->ui32RefCount--;
267         OSLockRelease(psContext->hLock);
268
269         return IMG_FALSE;
270 }
271
272 static IMG_VOID
273 SyncPrimBlockUnimport(RA_PERARENA_HANDLE hArena,
274                                           RA_BASE_T uiBase,
275                                           RA_PERISPAN_HANDLE hImport)
276 {
277         SYNC_PRIM_CONTEXT *psContext = hArena;
278         SYNC_PRIM_BLOCK *psSyncBlock = hImport;
279
280         PVR_ASSERT(psContext != IMG_NULL);
281         PVR_ASSERT(psSyncBlock != IMG_NULL);
282
283         PVR_ASSERT(uiBase == psSyncBlock->uiSpanBase);
284
285         /* Free the span this import is using */
286         RA_Free(psContext->psSpanRA, uiBase);
287
288         /* Free the syncpim block */
289         FreeSyncPrimitiveBlock(psSyncBlock);
290
291         /*      Drop our reference to the syncprim context */
292         OSLockAcquire(psContext->hLock);
293         psContext->ui32RefCount--;
294         OSLockRelease(psContext->hLock);
295 }
296
297 static INLINE IMG_UINT32 SyncPrimGetOffset(SYNC_PRIM *psSyncInt)
298 {
299         IMG_UINT64 ui64Temp;
300         
301         PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);
302
303         
304         ui64Temp =  psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
305         PVR_ASSERT(ui64Temp<IMG_UINT32_MAX);
306         return (IMG_UINT32)ui64Temp;
307 }
308
309 static IMG_VOID SyncPrimGetCPULinAddr(SYNC_PRIM *psSyncInt)
310 {
311         SYNC_PRIM_BLOCK *psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
312
313         psSyncInt->sCommon.pui32LinAddr = psSyncBlock->pui32LinAddr +
314                                                                           (SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32));
315 }
316
317 static IMG_VOID SyncPrimLocalFree(SYNC_PRIM *psSyncInt)
318 {
319         SYNC_PRIM_BLOCK *psSyncBlock;
320         SYNC_PRIM_CONTEXT *psContext;
321
322         PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);
323         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
324         psContext = psSyncBlock->psContext;
325
326         RA_Free(psContext->psSubAllocRA, psSyncInt->u.sLocal.uiSpanAddr);
327 }
328
329 static IMG_VOID SyncPrimServerFree(SYNC_PRIM *psSyncInt)
330 {
331         PVRSRV_ERROR eError;
332
333         eError = BridgeServerSyncFree(psSyncInt->u.sServer.hBridge,
334                                                                   psSyncInt->u.sServer.hServerSync);
335         if (eError != PVRSRV_OK)
336         {
337                 /* Doesn't matter if the free fails as resman will cleanup */
338                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimServerFree failed"));
339         }
340 }
341
342 static IMG_UINT32 SyncPrimGetFirmwareAddrLocal(SYNC_PRIM *psSyncInt)
343 {
344         SYNC_PRIM_BLOCK *psSyncBlock;
345
346         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
347         return psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psSyncInt);    
348 }
349
350 static IMG_UINT32 SyncPrimGetFirmwareAddrServer(SYNC_PRIM *psSyncInt)
351 {
352         return psSyncInt->u.sServer.ui32FirmwareAddr;
353 }
354
355 #if !defined(__KERNEL__)
356 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleLocal(SYNC_PRIM *psSyncInt)
357 {
358         return psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge;
359 }
360
361 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleServer(SYNC_PRIM *psSyncInt)
362 {
363         return psSyncInt->u.sServer.hBridge;
364 }
365
366 static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
367 {
368         SYNC_PRIM *psSyncInt;
369         PVR_ASSERT(psSync != IMG_NULL);
370         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
371
372         if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
373         {
374                 return _SyncPrimGetBridgeHandleLocal(psSyncInt);
375         }
376         else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
377         {
378                 return _SyncPrimGetBridgeHandleServer(psSyncInt);
379         }
380         else
381         {
382                 PVR_DPF((PVR_DBG_ERROR, "_SyncPrimGetBridgeHandle: Invalid sync type"));
383                 /*
384                         Either the client has given us a bad pointer or there is an
385                         error in this module
386                 */
387                 PVR_ASSERT(IMG_FALSE);
388                 return 0;
389         }
390 }
391 #endif
392
393 /*
394         Internal interfaces for management of syncprim block lists
395 */
396 static SYNC_BLOCK_LIST *_SyncPrimBlockListCreate(IMG_VOID)
397 {
398         SYNC_BLOCK_LIST *psBlockList;
399
400         psBlockList = OSAllocMem(sizeof(SYNC_BLOCK_LIST) +
401                                                                 (sizeof(SYNC_PRIM_BLOCK *)
402                                                                 * SYNC_BLOCK_LIST_CHUNCK_SIZE));
403         if (!psBlockList)
404         {
405                 return IMG_NULL;
406         }
407
408         psBlockList->ui32BlockCount = 0;
409         psBlockList->ui32BlockListSize = SYNC_BLOCK_LIST_CHUNCK_SIZE;
410
411         psBlockList->papsSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *)
412                                                                                                         * SYNC_BLOCK_LIST_CHUNCK_SIZE);
413         if (!psBlockList->papsSyncPrimBlock)
414         {
415                 OSFreeMem(psBlockList);
416                 return IMG_NULL;
417         }
418
419         OSMemSet(psBlockList->papsSyncPrimBlock,
420                          0,
421                          sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);
422
423         return psBlockList;
424 }
425
426 static PVRSRV_ERROR _SyncPrimBlockListAdd(SYNC_BLOCK_LIST *psBlockList,
427                                                                                         SYNC_PRIM_BLOCK *psSyncPrimBlock)
428 {
429         IMG_UINT32 i;
430
431         /* Check the context isn't already on the list */
432         for (i=0;i<psBlockList->ui32BlockCount;i++)
433         {
434                 if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
435                 {
436                         return PVRSRV_OK;
437                 }
438         }
439
440         /* Check we have space for a new item */
441         if (psBlockList->ui32BlockCount == psBlockList->ui32BlockListSize)
442         {
443                 SYNC_PRIM_BLOCK **papsNewSyncPrimBlock;
444
445                 papsNewSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *) *
446                                                                                         (psBlockList->ui32BlockCount +
447                                                                                         SYNC_BLOCK_LIST_CHUNCK_SIZE));
448                 if (!papsNewSyncPrimBlock)
449                 {
450                         return PVRSRV_ERROR_OUT_OF_MEMORY;
451                 }
452
453                 OSMemSet(psBlockList->papsSyncPrimBlock,
454                                  0,
455                                  sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);
456                 OSMemCopy(papsNewSyncPrimBlock,
457                                   psBlockList->papsSyncPrimBlock,
458                                   sizeof(SYNC_PRIM_CONTEXT *) *
459                                   psBlockList->ui32BlockCount);
460
461                 OSFreeMem(psBlockList->papsSyncPrimBlock);
462
463                 psBlockList->papsSyncPrimBlock = papsNewSyncPrimBlock;
464                 psBlockList->ui32BlockListSize += SYNC_BLOCK_LIST_CHUNCK_SIZE;
465         }
466
467         /* Add the context to the list */
468         psBlockList->papsSyncPrimBlock[psBlockList->ui32BlockCount++] = psSyncPrimBlock;
469         return PVRSRV_OK;
470 }
471
472 static PVRSRV_ERROR _SyncPrimBlockListBlockToIndex(SYNC_BLOCK_LIST *psBlockList,
473                                                                                                    SYNC_PRIM_BLOCK *psSyncPrimBlock,
474                                                                                                    IMG_UINT32 *pui32Index)
475 {
476         IMG_UINT32 i;
477
478         for (i=0;i<psBlockList->ui32BlockCount;i++)
479         {
480                 if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
481                 {
482                         *pui32Index = i;
483                         return PVRSRV_OK;
484                 }
485         }
486
487         return PVRSRV_ERROR_INVALID_PARAMS;
488 }
489
490 static PVRSRV_ERROR _SyncPrimBlockListHandleArrayCreate(SYNC_BLOCK_LIST *psBlockList,
491                                                                                                                 IMG_UINT32 *pui32BlockHandleCount,
492                                                                                                                 IMG_HANDLE **ppahHandleList)
493 {
494         IMG_HANDLE *pahHandleList;
495         IMG_UINT32 i;
496
497         pahHandleList = OSAllocMem(sizeof(IMG_HANDLE) *
498                                                            psBlockList->ui32BlockCount);
499         if (!pahHandleList)
500         {
501                 return PVRSRV_ERROR_OUT_OF_MEMORY;
502         }
503
504         for (i=0;i<psBlockList->ui32BlockCount;i++)
505         {
506                 pahHandleList[i] = psBlockList->papsSyncPrimBlock[i]->hServerSyncPrimBlock;
507         }
508
509         *ppahHandleList = pahHandleList;
510         *pui32BlockHandleCount = psBlockList->ui32BlockCount;
511
512         return PVRSRV_OK;
513 }
514
515 static IMG_VOID _SyncPrimBlockListHandleArrayDestroy(IMG_HANDLE *pahHandleList)
516 {
517         OSFreeMem(pahHandleList);
518 }
519
520 static IMG_UINT32 _SyncPrimBlockListGetClientValue(SYNC_BLOCK_LIST *psBlockList,
521                                                                                                    IMG_UINT32 ui32BlockIndex,
522                                                                                                    IMG_UINT32 ui32Index)
523 {
524         return psBlockList->papsSyncPrimBlock[ui32BlockIndex]->pui32LinAddr[ui32Index];
525 }
526
527 static IMG_VOID _SyncPrimBlockListDestroy(SYNC_BLOCK_LIST *psBlockList)
528 {
529         OSFreeMem(psBlockList->papsSyncPrimBlock);
530         OSFreeMem(psBlockList);
531 }
532
533 static INLINE IMG_UINT32 _Log2(IMG_UINT32 ui32Align)
534 {
535         IMG_UINT32 ui32Log2Align = 0;
536         while (!(ui32Align & 1))
537         {
538                 ui32Log2Align++;
539                 ui32Align = ui32Align >> 1;
540         }
541         PVR_ASSERT(ui32Align == 1);
542
543         return ui32Log2Align;
544 }
545
546 /*
547         External interfaces
548 */
549
550 IMG_INTERNAL PVRSRV_ERROR
551 SyncPrimContextCreate(SYNC_BRIDGE_HANDLE hBridge,
552                                           IMG_HANDLE hDeviceNode,
553                                           PSYNC_PRIM_CONTEXT *phSyncPrimContext)
554 {
555         SYNC_PRIM_CONTEXT *psContext;
556         PVRSRV_ERROR eError;
557
558         psContext = OSAllocMem(sizeof(SYNC_PRIM_CONTEXT));
559         if (psContext == IMG_NULL)
560         {
561                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
562                 goto fail_alloc;
563         }
564
565         psContext->hBridge = hBridge;
566         psContext->hDeviceNode = hDeviceNode;
567
568         eError = OSLockCreate(&psContext->hLock, LOCK_TYPE_PASSIVE);
569         if ( eError != PVRSRV_OK)
570         {
571                 goto fail_lockcreate;
572         }
573         
574         OSSNPrintf(psContext->azName, SYNC_PRIM_NAME_SIZE, "Sync Prim RA-%p", psContext);
575         OSSNPrintf(psContext->azSpanName, SYNC_PRIM_NAME_SIZE, "Sync Prim span RA-%p", psContext);
576
577         /*
578                 Create the RA for sub-allocations of the SynPrim's
579
580                 Note:
581                 The import size doesn't matter here as the server will pass
582                 back the blocksize when does the import which overrides
583                 what we specify here.
584         */
585
586         psContext->psSubAllocRA = RA_Create(psContext->azName,
587                                                                                 /* Params for imports */
588                                                                                 _Log2(sizeof(IMG_UINT32)),
589                                                                                 RA_LOCKCLASS_2,
590                                                                                 SyncPrimBlockImport,
591                                                                                 SyncPrimBlockUnimport,
592                                                                                 psContext);
593         if (psContext->psSubAllocRA == IMG_NULL)
594         {
595                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
596                 goto fail_suballoc;
597         }
598
599         /*
600                 Create the span-management RA
601
602                 The RA requires that we work with linear spans. For our use
603                 here we don't require this behaviour as we're always working
604                 within offsets of blocks (imports). However, we need to keep
605                 the RA happy so we create the "span" management RA which
606                 ensures that all are imports are added to the RA in a linear
607                 fashion
608         */
609         psContext->psSpanRA = RA_Create(psContext->azSpanName,
610                                                                         /* Params for imports */
611                                                                         0,
612                                                                         RA_LOCKCLASS_1,
613                                                                         IMG_NULL,
614                                                                         IMG_NULL,
615                                                                         IMG_NULL);
616         if (psContext->psSpanRA == IMG_NULL)
617         {
618                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
619                 goto fail_span;
620         }
621
622         if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_MEM, 0, IMG_NULL))
623         {
624                 RA_Delete(psContext->psSpanRA);
625                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
626                 goto fail_span;
627         }
628
629         psContext->ui32RefCount = 1;
630
631         *phSyncPrimContext = psContext;
632         return PVRSRV_OK;
633 fail_span:
634         RA_Delete(psContext->psSubAllocRA);
635 fail_suballoc:
636         OSLockDestroy(psContext->hLock);
637 fail_lockcreate:
638         OSFreeMem(psContext);
639 fail_alloc:
640         return eError;
641 }
642
643 IMG_INTERNAL IMG_VOID SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext)
644 {
645         SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
646         IMG_BOOL bDoRefCheck = IMG_TRUE;
647
648
649 #if defined(__KERNEL__)
650         PVRSRV_DATA *psPVRSRVData = PVRSRVGetPVRSRVData();
651         if (psPVRSRVData->eServicesState != PVRSRV_SERVICES_STATE_OK)
652         {
653                 bDoRefCheck =  IMG_FALSE;
654         }
655 #endif
656         OSLockAcquire(psContext->hLock);
657         if (--psContext->ui32RefCount != 0)
658         {
659                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimContextDestroy: Refcount non-zero: %d", psContext->ui32RefCount));
660
661                 if (bDoRefCheck)
662                 {
663                         PVR_ASSERT(0);
664                 }
665                 return;
666         }
667         /*
668                 If we fail above then we won't release the lock. However, if that
669                 happens things have already gone very wrong and we bail to save
670                 freeing memory which might still be in use and holding this lock
671                 will show up if anyone is trying to use this context after it has
672                 been destroyed.
673         */
674         OSLockRelease(psContext->hLock);
675
676         RA_Delete(psContext->psSpanRA);
677         RA_Delete(psContext->psSubAllocRA);
678         OSLockDestroy(psContext->hLock);
679         OSFreeMem(psContext);
680 }
681
682 IMG_INTERNAL PVRSRV_ERROR SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
683                                                                                 PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
684                                                                                 const IMG_CHAR *pszClassName)
685 {
686         SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
687         SYNC_PRIM_BLOCK *psSyncBlock;
688         SYNC_PRIM *psNewSync;
689         PVRSRV_ERROR eError;
690         RA_BASE_T uiSpanAddr;
691
692         psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
693         if (psNewSync == IMG_NULL)
694         {
695                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
696                 goto fail_alloc;
697         }
698
699         if (!RA_Alloc(psContext->psSubAllocRA,
700                                   sizeof(IMG_UINT32),
701                                   0,
702                                   sizeof(IMG_UINT32),
703                                   &uiSpanAddr,
704                                   IMG_NULL,
705                                   (RA_PERISPAN_HANDLE *) &psSyncBlock))
706         {
707                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
708                 goto fail_raalloc;
709         }
710         psNewSync->eType = SYNC_PRIM_TYPE_LOCAL;
711         psNewSync->u.sLocal.uiSpanAddr = uiSpanAddr;
712         psNewSync->u.sLocal.psSyncBlock = psSyncBlock;
713         SyncPrimGetCPULinAddr(psNewSync);
714         *ppsSync = &psNewSync->sCommon;
715
716 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
717         {
718                 IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
719                 if(pszClassName)
720                 {
721                         /* Copy the class name annotation into a fixed-size array */
722                         OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
723                         szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
724                 }
725                 else
726                 {
727                         /* No class name annotation */
728                         szClassName[0] = 0;
729                 }
730                 /* record this sync */
731                 eError = BridgeSyncRecordAdd(
732                                         psSyncBlock->psContext->hBridge,
733                                         &psNewSync->u.sLocal.hRecord,
734                                         psSyncBlock->hServerSyncPrimBlock,
735                                         psSyncBlock->ui32FirmwareAddr,
736                                         SyncPrimGetOffset(psNewSync),
737 #if defined(__KERNEL__)
738                                         IMG_TRUE,
739 #else
740                                         IMG_FALSE,
741 #endif
742                                         OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
743                                         szClassName);
744         }
745 #else
746         PVR_UNREFERENCED_PARAMETER(pszClassName);
747 #endif /* if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
748
749         return PVRSRV_OK;
750
751 fail_raalloc:
752         OSFreeMem(psNewSync);
753 fail_alloc:
754         PVR_ASSERT(eError != PVRSRV_OK);
755
756         return eError;
757 }
758
759 IMG_INTERNAL IMG_VOID SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync)
760 {
761         SYNC_PRIM *psSyncInt;
762
763         PVR_ASSERT(psSync != IMG_NULL);
764         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
765
766         if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
767         {
768 #if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
769                 PVRSRV_ERROR eError;
770                 /* remove this sync record */
771                 eError = BridgeSyncRecordRemoveByHandle(
772                                                 psSyncInt->u.sLocal.psSyncBlock->psContext->hBridge,
773                                                 psSyncInt->u.sLocal.hRecord);
774                 PVR_ASSERT(PVRSRV_OK == eError);
775 #endif
776                 SyncPrimLocalFree(psSyncInt);
777         }
778         else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
779         {
780                 SyncPrimServerFree(psSyncInt);
781         }
782         else
783         {
784                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimFree: Invalid sync type"));
785                 /*
786                         Either the client has given us a bad pointer or there is an
787                         error in this module
788                 */
789                 PVR_ASSERT(IMG_FALSE);
790                 return;
791         }
792
793         OSFreeMem(psSyncInt);
794 }
795
796 static IMG_VOID
797 _SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value)
798 {
799         PVRSRV_ERROR eError;
800
801         if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
802         {
803                 SYNC_PRIM_BLOCK *psSyncBlock;
804                 SYNC_PRIM_CONTEXT *psContext;
805
806                 psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
807                 psContext = psSyncBlock->psContext;
808
809                 eError = BridgeSyncPrimSet(psContext->hBridge,
810                                                                         psSyncBlock->hServerSyncPrimBlock,
811                                                                         SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32),
812                                                                         ui32Value);
813                 PVR_ASSERT(eError == PVRSRV_OK);
814         }
815         else
816         {
817                 eError = BridgeServerSyncPrimSet(psSyncInt->u.sServer.hBridge,
818                                                                         psSyncInt->u.sServer.hServerSync,
819                                                                         ui32Value);
820                 PVR_ASSERT(eError == PVRSRV_OK);
821
822         }
823 }
824
825 #if defined(NO_HARDWARE)
826 IMG_INTERNAL IMG_VOID
827 SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
828 {
829         SYNC_PRIM *psSyncInt;
830
831         PVR_ASSERT(psSync != IMG_NULL);
832         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
833
834         /* There is no check for the psSyncInt to be LOCAL as this call
835            substitutes the Firmware updating a sync and that sync could
836            be a server one */
837
838         _SyncPrimSetValue(psSyncInt, ui32Value);
839 }
840 #endif
841
842 IMG_INTERNAL IMG_VOID
843 SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
844 {
845         SYNC_PRIM *psSyncInt;
846
847         PVR_ASSERT(psSync != IMG_NULL);
848         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
849
850         if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
851         {
852                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimSet: Invalid sync type"));
853                 /*PVR_ASSERT(IMG_FALSE);*/
854                 return;
855         }
856
857         _SyncPrimSetValue(psSyncInt, ui32Value);
858
859 #if defined(PDUMP)
860         SyncPrimPDump(psSync);
861 #endif
862
863 }
864
865 IMG_INTERNAL IMG_UINT32 SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync)
866 {
867         SYNC_PRIM *psSyncInt;
868         PVR_ASSERT(psSync != IMG_NULL);
869         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
870
871         if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
872         {
873                 return SyncPrimGetFirmwareAddrLocal(psSyncInt);
874         }
875         else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
876         {
877                 return SyncPrimGetFirmwareAddrServer(psSyncInt);
878         }
879         else
880         {
881                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetFirmwareAddr: Invalid sync type"));
882                 /*
883                         Either the client has given us a bad pointer or there is an
884                         error in this module
885                 */
886                 PVR_ASSERT(IMG_FALSE);
887                 return 0;
888         }
889 }
890
891 #if !defined(__KERNEL__)
892 IMG_INTERNAL PVRSRV_ERROR SyncPrimDumpSyncs(IMG_UINT32 ui32SyncCount, PVRSRV_CLIENT_SYNC_PRIM **papsSync, const IMG_CHAR *pcszExtraInfo)
893 {
894 #if defined(PVRSRV_NEED_PVR_DPF)
895         SYNC_PRIM *psSyncInt;
896         PVRSRV_CLIENT_SYNC_PRIM **papsServerSync;
897         IMG_UINT32 ui32ServerSyncs = 0;
898         IMG_UINT32 *pui32UID = IMG_NULL;
899         IMG_UINT32 *pui32FWAddr = IMG_NULL;
900         IMG_UINT32 *pui32CurrentOp = IMG_NULL;
901         IMG_UINT32 *pui32NextOp = IMG_NULL;
902         IMG_UINT32 i;
903         PVRSRV_ERROR eError = PVRSRV_OK;
904
905         papsServerSync = OSAllocMem(ui32SyncCount * sizeof(PVRSRV_CLIENT_SYNC_PRIM *));
906         if (!papsServerSync)
907         {
908                 return PVRSRV_ERROR_OUT_OF_MEMORY;
909         }
910
911         for (i = 0; i < ui32SyncCount; i++)
912         {
913                 psSyncInt = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
914                 if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
915                 {
916                         PVR_DPF((PVR_DBG_ERROR, "%s: sync=local  fw=0x%x curr=0x%04x",
917                                          pcszExtraInfo,
918                                          SyncPrimGetFirmwareAddrLocal(psSyncInt),
919                                          *psSyncInt->sCommon.pui32LinAddr));
920                 }
921                 else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
922                 {
923                         papsServerSync[ui32ServerSyncs++] = papsSync[i];
924                 }
925                 else
926                 {
927                         PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Invalid sync type"));
928                         /*
929                            Either the client has given us a bad pointer or there is an
930                            error in this module
931                            */
932                         PVR_ASSERT(IMG_FALSE);
933                         eError = PVRSRV_ERROR_INVALID_PARAMS;
934                         goto err_free;
935                 }
936         }
937
938         if (ui32ServerSyncs > 0)
939         {
940                 pui32UID = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
941                 if (!pui32UID)
942                 {
943                         eError = PVRSRV_ERROR_OUT_OF_MEMORY;
944                         goto err_free;
945                 }
946                 pui32FWAddr = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
947                 if (!pui32FWAddr)
948                 {
949                         eError = PVRSRV_ERROR_OUT_OF_MEMORY;
950                         goto err_free;
951                 }
952                 pui32CurrentOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
953                 if (!pui32CurrentOp)
954                 {
955                         eError = PVRSRV_ERROR_OUT_OF_MEMORY;
956                         goto err_free;
957                 }
958                 pui32NextOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
959                 if (!pui32NextOp)
960                 {
961                         eError = PVRSRV_ERROR_OUT_OF_MEMORY;
962                         goto err_free;
963                 }
964                 eError = SyncPrimServerGetStatus(ui32ServerSyncs, papsServerSync,
965                                                                                  pui32UID,
966                                                                                  pui32FWAddr,
967                                                                                  pui32CurrentOp,
968                                                                                  pui32NextOp);
969                 if (eError != PVRSRV_OK)
970                 {
971                         PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Error querying server sync status (%d)",
972                                          eError));
973                         goto err_free;
974                 }
975                 for (i = 0; i < ui32ServerSyncs; i++)
976                 {
977                         PVR_DPF((PVR_DBG_ERROR, "%s: sync=server fw=0x%x curr=0x%04x next=0x%04x id=%u%s",
978                                          pcszExtraInfo,
979                                          pui32FWAddr[i],
980                                          pui32CurrentOp[i],
981                                          pui32NextOp[i],
982                                          pui32UID[i],
983                                          (pui32NextOp[i] - pui32CurrentOp[i] == 1) ? " *" : 
984                                          (pui32NextOp[i] - pui32CurrentOp[i] >  1) ? " **" : 
985                                          ""));
986                 }
987         }
988
989 err_free:
990         OSFreeMem(papsServerSync);
991         if (pui32UID)
992         {
993                 OSFreeMem(pui32UID);
994         }
995         if (pui32FWAddr)
996         {
997                 OSFreeMem(pui32FWAddr);
998         }
999         if (pui32CurrentOp)
1000         {
1001                 OSFreeMem(pui32CurrentOp);
1002         }
1003         if (pui32NextOp)
1004         {
1005                 OSFreeMem(pui32NextOp);
1006         }
1007         return eError;
1008 #else
1009         PVR_UNREFERENCED_PARAMETER(ui32SyncCount);
1010         PVR_UNREFERENCED_PARAMETER(papsSync);
1011         PVR_UNREFERENCED_PARAMETER(pcszExtraInfo);
1012         return PVRSRV_OK;
1013 #endif
1014 }
1015 #endif
1016
1017 IMG_INTERNAL
1018 PVRSRV_ERROR SyncPrimOpCreate(IMG_UINT32 ui32SyncCount,
1019                                                           PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim,
1020                                                           PSYNC_OP_COOKIE *ppsCookie)
1021 {
1022         SYNC_OP_COOKIE *psNewCookie;
1023         SYNC_BLOCK_LIST *psSyncBlockList;
1024         IMG_UINT32 ui32ServerSyncCount = 0;
1025         IMG_UINT32 ui32ClientSyncCount = 0;
1026         IMG_UINT32 ui32ServerAllocSize;
1027         IMG_UINT32 ui32ClientAllocSize;
1028         IMG_UINT32 ui32TotalAllocSize;
1029         IMG_UINT32 ui32ServerIndex = 0;
1030         IMG_UINT32 ui32ClientIndex = 0;
1031         IMG_UINT32 i;
1032         IMG_UINT32 ui32SyncBlockCount;
1033         IMG_HANDLE hBridge;
1034         IMG_HANDLE *pahHandleList;
1035         IMG_CHAR *pcPtr;
1036         PVRSRV_ERROR eError;
1037
1038         psSyncBlockList = _SyncPrimBlockListCreate();
1039         
1040         if (!psSyncBlockList)
1041         {
1042                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1043                 goto e0;
1044         }
1045
1046         for (i=0;i<ui32SyncCount;i++)
1047         {
1048                 if (SyncPrimIsServerSync(papsSyncPrim[i]))
1049                 {
1050                         ui32ServerSyncCount++;
1051                 }
1052                 else
1053                 {
1054                         SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
1055
1056                         ui32ClientSyncCount++;
1057                         eError = _SyncPrimBlockListAdd(psSyncBlockList, psSync->u.sLocal.psSyncBlock);
1058                         if (eError != PVRSRV_OK)
1059                         {
1060                                 goto e1;
1061                         }
1062                 }
1063         }
1064
1065         ui32ServerAllocSize = ui32ServerSyncCount * (sizeof(IMG_HANDLE) + sizeof(IMG_UINT32));
1066         ui32ClientAllocSize = ui32ClientSyncCount * (5 * sizeof(IMG_UINT32));
1067         ui32TotalAllocSize = sizeof(SYNC_OP_COOKIE) +
1068                                                          (sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount) +
1069                                                          ui32ServerAllocSize + 
1070                                                          ui32ClientAllocSize;
1071
1072         psNewCookie = OSAllocMem(ui32TotalAllocSize);
1073         pcPtr = (IMG_CHAR *) psNewCookie;
1074
1075         if (!psNewCookie)
1076         {
1077                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1078                 goto e1;
1079         }
1080
1081         /* Setup the pointers */
1082         pcPtr += sizeof(SYNC_OP_COOKIE);
1083         psNewCookie->papsSyncPrim = (PVRSRV_CLIENT_SYNC_PRIM **) pcPtr;
1084
1085         pcPtr += sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount;
1086         psNewCookie->paui32SyncBlockIndex = (IMG_UINT32 *) pcPtr;
1087
1088         pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1089         psNewCookie->paui32Index = (IMG_UINT32 *) pcPtr;
1090         
1091         pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1092         psNewCookie->paui32Flags = (IMG_UINT32 *) pcPtr;
1093
1094         pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1095         psNewCookie->paui32FenceValue = (IMG_UINT32 *) pcPtr;
1096
1097         pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1098         psNewCookie->paui32UpdateValue = (IMG_UINT32 *) pcPtr;
1099
1100         pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
1101         psNewCookie->pahServerSync =(IMG_HANDLE *) pcPtr;
1102         pcPtr += sizeof(IMG_HANDLE) * ui32ServerSyncCount;
1103
1104         psNewCookie->paui32ServerFlags =(IMG_UINT32 *) pcPtr;
1105         pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;
1106
1107         /* Check the pointer setup went ok */
1108         PVR_ASSERT(pcPtr == (((IMG_CHAR *) psNewCookie) + ui32TotalAllocSize));
1109
1110         psNewCookie->ui32SyncCount = ui32SyncCount;
1111         psNewCookie->ui32ServerSyncCount = ui32ServerSyncCount;
1112         psNewCookie->ui32ClientSyncCount = ui32ClientSyncCount;
1113         psNewCookie->psSyncBlockList = psSyncBlockList;
1114
1115         /*
1116                 Get the bridge handle from the 1st sync.
1117
1118                 Note: We assume the all syncs have been created with the same
1119                           services connection.
1120         */
1121         if (SyncPrimIsServerSync(papsSyncPrim[0]))
1122         {
1123                 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
1124
1125                 hBridge = psSync->u.sServer.hBridge;
1126         }
1127         else
1128         {
1129                 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];
1130
1131                 hBridge = psSync->u.sLocal.psSyncBlock->psContext->hBridge;             
1132         }
1133
1134         psNewCookie->hBridge = hBridge;
1135
1136         if (ui32ServerSyncCount)
1137         {
1138                 psNewCookie->bHaveServerSync = IMG_TRUE;
1139         }
1140         else
1141         {
1142                 psNewCookie->bHaveServerSync = IMG_FALSE;
1143         }
1144
1145         /* Fill in the server and client sync data */
1146         for (i=0;i<ui32SyncCount;i++)
1147         {
1148                 SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];
1149
1150                 if (SyncPrimIsServerSync(papsSyncPrim[i]))
1151                 {
1152                         psNewCookie->pahServerSync[ui32ServerIndex] = psSync->u.sServer.hServerSync;
1153
1154                         ui32ServerIndex++;
1155                 }
1156                 else
1157                 {
1158                         /* Location of sync */
1159                         eError = _SyncPrimBlockListBlockToIndex(psSyncBlockList,
1160                                                                                                         psSync->u.sLocal.psSyncBlock,
1161                                                                                                         &psNewCookie->paui32SyncBlockIndex[ui32ClientIndex]);
1162                         if (eError != PVRSRV_OK)
1163                         {
1164                                 goto e2;
1165                         }
1166
1167                         /* Workout the index to sync */
1168                         psNewCookie->paui32Index[ui32ClientIndex] =
1169                                         SyncPrimGetOffset(psSync)/sizeof(IMG_UINT32);
1170
1171                         ui32ClientIndex++;
1172                 }
1173
1174                 psNewCookie->papsSyncPrim[i] = papsSyncPrim[i];
1175         }
1176
1177         eError = _SyncPrimBlockListHandleArrayCreate(psSyncBlockList,
1178                                                                                                  &ui32SyncBlockCount,
1179                                                                                                  &pahHandleList);
1180         if (eError !=PVRSRV_OK)
1181         {
1182                 goto e2;
1183         }
1184
1185         /*
1186                 Create the server side cookie. Here we pass in all the unchanging
1187                 data so we only need to pass in the minimum at takeop time
1188         */
1189         eError = BridgeSyncPrimOpCreate(hBridge,
1190                                                                         ui32SyncBlockCount,
1191                                                                         pahHandleList,
1192                                                                         psNewCookie->ui32ClientSyncCount,
1193                                                                         psNewCookie->paui32SyncBlockIndex,
1194                                                                         psNewCookie->paui32Index,
1195                                                                         psNewCookie->ui32ServerSyncCount,
1196                                                                         psNewCookie->pahServerSync,
1197                                                                         &psNewCookie->hServerCookie);
1198
1199         /* Free the handle list regardless of error */
1200         _SyncPrimBlockListHandleArrayDestroy(pahHandleList);
1201
1202         if (eError != PVRSRV_OK)
1203         {
1204                 goto e2;
1205         }
1206
1207         *ppsCookie = psNewCookie;
1208         return PVRSRV_OK;
1209
1210 e2:
1211         OSFreeMem(psNewCookie);
1212 e1:
1213         _SyncPrimBlockListDestroy(psSyncBlockList);
1214 e0:
1215         return eError;
1216 }
1217
1218 IMG_INTERNAL
1219 PVRSRV_ERROR SyncPrimOpTake(PSYNC_OP_COOKIE psCookie,
1220                                                         IMG_UINT32 ui32SyncCount,
1221                                                         PVRSRV_CLIENT_SYNC_PRIM_OP *pasSyncOp)
1222 {
1223         PVRSRV_ERROR eError;
1224         IMG_UINT32 ui32ServerIndex = 0;
1225         IMG_UINT32 ui32ClientIndex = 0;
1226         IMG_UINT32 i;
1227
1228         /* Copy client sync operations */
1229         for (i=0;i<ui32SyncCount;i++)
1230         {
1231                 /*
1232                         Sanity check the client passes in the same syncs as the
1233                         ones we got at create time
1234                 */
1235                 if (psCookie->papsSyncPrim[i] != pasSyncOp[i].psSync)
1236                 {
1237                         return PVRSRV_ERROR_INVALID_PARAMS;
1238                 }
1239
1240                 if (SyncPrimIsServerSync(pasSyncOp[i].psSync))
1241                 {
1242                         psCookie->paui32ServerFlags[ui32ServerIndex] =
1243                                         pasSyncOp[i].ui32Flags;
1244
1245                         ui32ServerIndex++;
1246                 }
1247                 else
1248                 {
1249                         /* Client operation information */
1250                         psCookie->paui32Flags[ui32ClientIndex] =
1251                                         pasSyncOp[i].ui32Flags;
1252                         psCookie->paui32FenceValue[ui32ClientIndex] =
1253                                         pasSyncOp[i].ui32FenceValue;
1254                         psCookie->paui32UpdateValue[ui32ClientIndex] =
1255                                         pasSyncOp[i].ui32UpdateValue;
1256
1257                         ui32ClientIndex++;
1258                 }
1259         }
1260
1261         eError = BridgeSyncPrimOpTake(psCookie->hBridge,
1262                                                                   psCookie->hServerCookie,
1263                                                                   psCookie->ui32ClientSyncCount,
1264                                                                   psCookie->paui32Flags,
1265                                                                   psCookie->paui32FenceValue,
1266                                                                   psCookie->paui32UpdateValue,
1267                                                                   psCookie->ui32ServerSyncCount,
1268                                                                   psCookie->paui32ServerFlags);
1269
1270         return eError;
1271 }
1272
1273 IMG_INTERNAL
1274 PVRSRV_ERROR SyncPrimOpReady(PSYNC_OP_COOKIE psCookie,
1275                                                          IMG_BOOL *pbReady)
1276 {
1277         PVRSRV_ERROR eError;
1278         PVR_ASSERT(psCookie != IMG_NULL);
1279
1280         /*
1281                 If we have a server sync we have no choice
1282                 but to do the check in the server
1283         */
1284         if (psCookie->bHaveServerSync)
1285         {
1286                 eError = BridgeSyncPrimOpReady(psCookie->hBridge,
1287                                                                            psCookie->hServerCookie,
1288                                                                            pbReady);
1289                 if (eError != PVRSRV_OK)
1290                 {
1291                         PVR_DPF((PVR_DBG_ERROR,
1292                                          "%s: Failed to do sync check in server (Error = %d)",
1293                                          __FUNCTION__, eError));
1294                         goto e0;
1295                 }
1296         }
1297         else
1298         {
1299                 IMG_UINT32 i;
1300                 IMG_UINT32 ui32SnapShot;
1301                 IMG_BOOL bReady = IMG_TRUE;
1302
1303                 for (i=0;i<psCookie->ui32ClientSyncCount;i++)
1304                 {
1305                         if ((psCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK) == 0)
1306                         {
1307                                 continue;
1308                         }
1309
1310                         ui32SnapShot = _SyncPrimBlockListGetClientValue(psCookie->psSyncBlockList,
1311                                                                                                                         psCookie->paui32SyncBlockIndex[i],
1312                                                                                                                         psCookie->paui32Index[i]);
1313                         if (ui32SnapShot != psCookie->paui32FenceValue[i])
1314                         {
1315                                 bReady = IMG_FALSE;
1316                                 break;
1317                         }
1318                 }
1319
1320                 *pbReady = bReady;
1321         }
1322
1323         return PVRSRV_OK;
1324 e0:
1325         PVR_ASSERT(eError != PVRSRV_OK);
1326         return eError;
1327 }
1328
1329 IMG_INTERNAL
1330 PVRSRV_ERROR SyncPrimOpComplete(PSYNC_OP_COOKIE psCookie)
1331 {
1332         PVRSRV_ERROR eError;
1333
1334         eError = BridgeSyncPrimOpComplete(psCookie->hBridge,
1335                                                                           psCookie->hServerCookie);
1336
1337         return eError;
1338 }
1339
1340 IMG_INTERNAL
1341 IMG_VOID SyncPrimOpDestroy(PSYNC_OP_COOKIE psCookie)
1342 {
1343         PVRSRV_ERROR eError;
1344
1345         eError = BridgeSyncPrimOpDestroy(psCookie->hBridge,
1346                                                                          psCookie->hServerCookie);
1347         PVR_ASSERT(eError == PVRSRV_OK);
1348
1349         _SyncPrimBlockListDestroy(psCookie->psSyncBlockList);
1350         OSFreeMem(psCookie);
1351 }
1352
1353 IMG_INTERNAL
1354 PVRSRV_ERROR SyncPrimOpResolve(PSYNC_OP_COOKIE psCookie,
1355                                                            IMG_UINT32 *pui32SyncCount,
1356                                                            PVRSRV_CLIENT_SYNC_PRIM_OP **ppsSyncOp)
1357 {
1358         IMG_UINT32 ui32ServerIndex = 0;
1359         IMG_UINT32 ui32ClientIndex = 0;
1360         PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOps;
1361         IMG_UINT32 i;
1362
1363         psSyncOps = OSAllocMem(sizeof(PVRSRV_CLIENT_SYNC_PRIM_OP) * 
1364                                                    psCookie->ui32SyncCount);
1365         if (!psSyncOps)
1366         {
1367                 return PVRSRV_ERROR_OUT_OF_MEMORY;
1368         }
1369         
1370         for (i=0; i<psCookie->ui32SyncCount; i++)
1371         {
1372                 psSyncOps[i].psSync = psCookie->papsSyncPrim[i];
1373                 if (SyncPrimIsServerSync(psCookie->papsSyncPrim[i]))
1374                 {
1375                         psSyncOps[i].ui32FenceValue = 0;
1376                         psSyncOps[i].ui32UpdateValue = 0;
1377                         psSyncOps[i].ui32Flags = psCookie->paui32ServerFlags[ui32ServerIndex];
1378                         ui32ServerIndex++;
1379                 }
1380                 else
1381                 {
1382                         psSyncOps[i].ui32FenceValue = psCookie->paui32FenceValue[ui32ClientIndex]; 
1383                         psSyncOps[i].ui32UpdateValue = psCookie->paui32UpdateValue[ui32ClientIndex]; 
1384                         psSyncOps[i].ui32Flags = psCookie->paui32Flags[ui32ClientIndex];
1385                         ui32ClientIndex++;
1386                 }
1387         }
1388
1389         *ppsSyncOp = psSyncOps;
1390         *pui32SyncCount = psCookie->ui32SyncCount;
1391
1392         return PVRSRV_OK;
1393 }
1394
1395 #if !defined(__KERNEL__)
1396 IMG_INTERNAL
1397 PVRSRV_ERROR SyncPrimServerAlloc(SYNC_BRIDGE_HANDLE hBridge,
1398                                                                  IMG_HANDLE hDeviceNode,
1399                                                                  PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
1400                                                                  const IMG_CHAR *pszClassName
1401                                                                  PVR_DBG_FILELINE_PARAM)
1402 {
1403         IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
1404         SYNC_PRIM *psNewSync;
1405         PVRSRV_ERROR eError;
1406
1407 #if !defined(PVR_SYNC_PRIM_ALLOC_TRACE)
1408         PVR_DBG_FILELINE_UNREF();
1409 #endif
1410         psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
1411         if (psNewSync == IMG_NULL)
1412         {
1413                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1414                 goto e0;
1415         }
1416         OSMemSet(psNewSync, 0, sizeof(SYNC_PRIM));
1417
1418         if(pszClassName)
1419         {
1420                 /* Copy the class name annotation into a fixed-size array */
1421                 OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
1422                 szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
1423         }
1424         else
1425         {
1426                 /* No class name annotation */
1427                 szClassName[0] = 0;
1428         }
1429
1430         eError = BridgeServerSyncAlloc(hBridge,
1431                                                                    hDeviceNode,
1432                                                                    &psNewSync->u.sServer.hServerSync,
1433                                                                    &psNewSync->u.sServer.ui32FirmwareAddr,
1434                                                                    OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
1435                                                                    szClassName);
1436
1437         if (eError != PVRSRV_OK)
1438         {
1439                 goto e1;
1440         }
1441
1442 #if defined(PVR_SYNC_PRIM_ALLOC_TRACE)
1443         PVR_DPF((PVR_DBG_WARNING, "Allocated sync=server fw=0x%x [%p]" PVR_DBG_FILELINE_FMT,
1444                          psNewSync->u.sServer.ui32FirmwareAddr, &psNewSync->sCommon PVR_DBG_FILELINE_ARG));
1445 #endif
1446
1447         psNewSync->eType = SYNC_PRIM_TYPE_SERVER;
1448         psNewSync->u.sServer.hBridge = hBridge;
1449         *ppsSync = &psNewSync->sCommon;
1450
1451         return PVRSRV_OK;
1452 e1:
1453         OSFreeMem(psNewSync);
1454 e0:
1455         return eError;
1456 }
1457
1458 IMG_INTERNAL
1459 PVRSRV_ERROR SyncPrimServerGetStatus(IMG_UINT32 ui32SyncCount,
1460                                                                          PVRSRV_CLIENT_SYNC_PRIM **papsSync,
1461                                                                          IMG_UINT32 *pui32UID,
1462                                                                          IMG_UINT32 *pui32FWAddr,
1463                                                                          IMG_UINT32 *pui32CurrentOp,
1464                                                                          IMG_UINT32 *pui32NextOp)
1465 {
1466         PVRSRV_ERROR eError;
1467         IMG_UINT32 i;
1468         SYNC_BRIDGE_HANDLE hBridge = _SyncPrimGetBridgeHandle(papsSync[0]);
1469         IMG_HANDLE *pahServerHandle;
1470
1471         pahServerHandle = OSAllocMem(sizeof(IMG_HANDLE) * ui32SyncCount);
1472         if (pahServerHandle == IMG_NULL)
1473         {
1474                 eError = PVRSRV_ERROR_OUT_OF_MEMORY;
1475                 goto e0;
1476         }
1477
1478         /*
1479                 Check that all the sync we've been passed are server syncs
1480                 and that they all are on the same connection.
1481         */
1482         for (i=0;i<ui32SyncCount;i++)
1483         {
1484                 SYNC_PRIM *psIntSync = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
1485
1486                 if (!SyncPrimIsServerSync(papsSync[i]))
1487                 {
1488                         eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
1489                         goto e1;
1490                 }
1491
1492                 if (hBridge != _SyncPrimGetBridgeHandle(papsSync[i]))
1493                 {
1494                         PVR_DPF((PVR_DBG_ERROR, "SyncServerGetStatus: Sync connection is different\n"));
1495                         eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
1496                         goto e1;
1497                 }
1498
1499                 pahServerHandle[i] = psIntSync->u.sServer.hServerSync;
1500         }
1501
1502         eError = BridgeServerSyncGetStatus(hBridge,
1503                                                                            ui32SyncCount,
1504                                                                            pahServerHandle,
1505                                                                            pui32UID,
1506                                                                            pui32FWAddr,
1507                                                                            pui32CurrentOp,
1508                                                                            pui32NextOp);
1509         OSFreeMem(pahServerHandle);
1510
1511         if (eError != PVRSRV_OK)
1512         {
1513                 goto e0;
1514         }
1515         return PVRSRV_OK;
1516
1517 e1:
1518         OSFreeMem(pahServerHandle);
1519 e0:
1520         PVR_ASSERT(eError != PVRSRV_OK);
1521         return eError;
1522 }
1523
1524 #endif
1525
1526 IMG_INTERNAL
1527 IMG_BOOL SyncPrimIsServerSync(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1528 {
1529         SYNC_PRIM *psSyncInt;
1530
1531         PVR_ASSERT(psSync != IMG_NULL);
1532         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1533         if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
1534         {
1535                 return IMG_TRUE;
1536         }
1537
1538         return IMG_FALSE;
1539 }
1540
1541 IMG_INTERNAL
1542 IMG_HANDLE SyncPrimGetServerHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1543 {
1544         SYNC_PRIM *psSyncInt;
1545
1546         PVR_ASSERT(psSync != IMG_NULL);
1547         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1548         PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_SERVER);
1549
1550         return psSyncInt->u.sServer.hServerSync;
1551 }
1552
1553 IMG_INTERNAL
1554 PVRSRV_ERROR SyncPrimServerQueueOp(PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOp)
1555 {
1556         SYNC_PRIM *psSyncInt;
1557         IMG_BOOL bUpdate;
1558         PVRSRV_ERROR eError;
1559
1560         PVR_ASSERT(psSyncOp != IMG_NULL);
1561         psSyncInt = IMG_CONTAINER_OF(psSyncOp->psSync, SYNC_PRIM, sCommon);
1562         if (psSyncInt->eType != SYNC_PRIM_TYPE_SERVER)
1563         {
1564                 return PVRSRV_ERROR_INVALID_SYNC_PRIM;
1565         }
1566
1567         PVR_ASSERT(psSyncOp->ui32Flags != 0);
1568         if (psSyncOp->ui32Flags & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
1569         {
1570                 bUpdate = IMG_TRUE;
1571         }else
1572         {
1573                 bUpdate = IMG_FALSE;
1574         }
1575
1576         eError = BridgeServerSyncQueueHWOp(psSyncInt->u.sServer.hBridge,
1577                                                                               psSyncInt->u.sServer.hServerSync,
1578                                                                                   bUpdate,
1579                                                                               &psSyncOp->ui32FenceValue,
1580                                                                               &psSyncOp->ui32UpdateValue);
1581         return eError;
1582 }
1583
1584 #if defined(PDUMP)
1585 IMG_INTERNAL IMG_VOID SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync)
1586 {
1587         SYNC_PRIM *psSyncInt;
1588         SYNC_PRIM_BLOCK *psSyncBlock;
1589         SYNC_PRIM_CONTEXT *psContext;
1590         PVRSRV_ERROR eError;
1591
1592         PVR_ASSERT(psSync != IMG_NULL);
1593         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1594
1595         if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1596         {
1597                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
1598                 PVR_ASSERT(IMG_FALSE);
1599                 return;
1600         }
1601
1602         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1603         psContext = psSyncBlock->psContext;
1604
1605         eError = BridgeSyncPrimPDump(psContext->hBridge,
1606                                                                  psSyncBlock->hServerSyncPrimBlock,
1607                                                                  SyncPrimGetOffset(psSyncInt));
1608
1609         if (eError != PVRSRV_OK)
1610         {
1611                 PVR_DPF((PVR_DBG_ERROR,
1612                                 "%s: failed with error %d",
1613                                 __FUNCTION__, eError));
1614         }
1615     PVR_ASSERT(eError == PVRSRV_OK);
1616 }
1617
1618 IMG_INTERNAL IMG_VOID SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
1619 {
1620         SYNC_PRIM *psSyncInt;
1621         SYNC_PRIM_BLOCK *psSyncBlock;
1622         SYNC_PRIM_CONTEXT *psContext;
1623         PVRSRV_ERROR eError;
1624
1625         PVR_ASSERT(psSync != IMG_NULL);
1626         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1627
1628         if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1629         {
1630                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
1631                 PVR_ASSERT(IMG_FALSE);
1632                 return;
1633         }
1634
1635         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1636         psContext = psSyncBlock->psContext;
1637
1638         eError = BridgeSyncPrimPDumpValue(psContext->hBridge,
1639                                                                  psSyncBlock->hServerSyncPrimBlock,
1640                                                                  SyncPrimGetOffset(psSyncInt),
1641                                                                  ui32Value);
1642
1643         if (eError != PVRSRV_OK)
1644         {
1645                 PVR_DPF((PVR_DBG_ERROR,
1646                                 "%s: failed with error %d",
1647                                 __FUNCTION__, eError));
1648         }
1649     PVR_ASSERT(eError == PVRSRV_OK);
1650 }
1651
1652 IMG_INTERNAL IMG_VOID SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
1653                                                                            IMG_UINT32 ui32Value,
1654                                                                            IMG_UINT32 ui32Mask,
1655                                                                            PDUMP_POLL_OPERATOR eOperator,
1656                                                                            IMG_UINT32 ui32PDumpFlags)
1657 {
1658         SYNC_PRIM *psSyncInt;
1659         SYNC_PRIM_BLOCK *psSyncBlock;
1660         SYNC_PRIM_CONTEXT *psContext;
1661         PVRSRV_ERROR eError;
1662
1663         PVR_ASSERT(psSync != IMG_NULL);
1664         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1665
1666         if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1667         {
1668                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpPol: Invalid sync type (expected SYNC_PRIM_TYPE_LOCAL)"));
1669                 PVR_ASSERT(IMG_FALSE);
1670                 return;
1671         }
1672
1673         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1674         psContext = psSyncBlock->psContext;
1675
1676         eError = BridgeSyncPrimPDumpPol(psContext->hBridge,
1677                                                                         psSyncBlock->hServerSyncPrimBlock,
1678                                                                         SyncPrimGetOffset(psSyncInt),
1679                                                                         ui32Value,
1680                                                                         ui32Mask,
1681                                                                         eOperator,
1682                                                                         ui32PDumpFlags);
1683
1684         if (eError != PVRSRV_OK)
1685         {
1686                 PVR_DPF((PVR_DBG_ERROR,
1687                                 "%s: failed with error %d",
1688                                 __FUNCTION__, eError));
1689         }
1690     PVR_ASSERT(eError == PVRSRV_OK);
1691 }
1692
1693 IMG_INTERNAL IMG_VOID SyncPrimOpPDumpPol(PSYNC_OP_COOKIE psCookie,
1694                                                                            PDUMP_POLL_OPERATOR eOperator,
1695                                                                            IMG_UINT32 ui32PDumpFlags)
1696 {
1697         PVRSRV_ERROR eError;
1698
1699         PVR_ASSERT(psCookie != IMG_NULL);
1700
1701         eError = BridgeSyncPrimOpPDumpPol(psCookie->hBridge,
1702                                                                         psCookie->hServerCookie,
1703                                                                         eOperator,
1704                                                                         ui32PDumpFlags);
1705
1706         if (eError != PVRSRV_OK)
1707         {
1708                 PVR_DPF((PVR_DBG_ERROR,
1709                                 "%s: failed with error %d",
1710                                 __FUNCTION__, eError));
1711         }
1712         
1713     PVR_ASSERT(eError == PVRSRV_OK);
1714 }
1715
1716 IMG_INTERNAL IMG_VOID SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
1717                                                                            IMG_UINT64 uiWriteOffset,
1718                                                                            IMG_UINT64 uiPacketSize,
1719                                                                            IMG_UINT64 uiBufferSize)
1720 {
1721         SYNC_PRIM *psSyncInt;
1722         SYNC_PRIM_BLOCK *psSyncBlock;
1723         SYNC_PRIM_CONTEXT *psContext;
1724         PVRSRV_ERROR eError;
1725
1726         PVR_ASSERT(psSync != IMG_NULL);
1727         psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
1728
1729         if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
1730         {
1731                 PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpCBP: Invalid sync type"));
1732                 PVR_ASSERT(IMG_FALSE);
1733                 return;
1734         }
1735
1736         psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
1737         psContext = psSyncBlock->psContext;
1738
1739         
1740 #if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
1741         PVR_ASSERT(uiWriteOffset<IMG_UINT32_MAX);
1742         PVR_ASSERT(uiPacketSize<IMG_UINT32_MAX);
1743         PVR_ASSERT(uiBufferSize<IMG_UINT32_MAX);
1744 #endif
1745         eError = BridgeSyncPrimPDumpCBP(psContext->hBridge,
1746                                                                         psSyncBlock->hServerSyncPrimBlock,
1747                                                                         SyncPrimGetOffset(psSyncInt),
1748                                                                         (IMG_UINT32)uiWriteOffset,
1749                                                                         (IMG_UINT32)uiPacketSize,
1750                                                                         (IMG_UINT32)uiBufferSize);
1751
1752         if (eError != PVRSRV_OK)
1753         {
1754                 PVR_DPF((PVR_DBG_ERROR,
1755                                 "%s: failed with error %d",
1756                                 __FUNCTION__, eError));
1757         }
1758     PVR_ASSERT(eError == PVRSRV_OK);
1759 }
1760
1761 #endif
1762