/*************************************************************************/ /*!
@File
@Title          Services synchronisation interface
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description    Implements client side code for services synchronisation
                interface
@License        Dual MIT/GPLv2

The contents of this file are subject to the MIT license as set out below.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

Alternatively, the contents of this file may be used under the terms of
the GNU General Public License Version 2 ("GPL") in which case the provisions
of GPL are applicable instead of those above.

If you wish to allow use of your version of this file only under the terms of
GPL, and not to allow others to use your version of this file under the terms
of the MIT license, indicate your decision by deleting the provisions above
and replace them with the notice and other provisions required by GPL as set
out in the file called "GPL-COPYING" included in this distribution. If you do
not delete the provisions above, a recipient may use your version of this file
under the terms of either the MIT license or GPL.

This License is also included in this distribution in the file called
"MIT-COPYING".

EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ /**************************************************************************/

#include "img_types.h"
#include "client_sync_bridge.h"
#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
#include "client_synctracking_bridge.h"
#endif
#include "pvr_bridge.h"
#include "allocmem.h"
#include "osfunc.h"
#include "devicemem.h"
#include "devicemem_pdump.h"
#include "pvr_debug.h"
#include "dllist.h"
#include "sync.h"
#include "sync_internal.h"
#include "lock.h"
#include "log2.h"
/* FIXME */
#if defined(__KERNEL__)
#include "pvrsrv.h"
#endif


#define SYNC_BLOCK_LIST_CHUNCK_SIZE	10

/*
	This defines the maximum amount of synchronisation memory
	that can be allocated per SyncPrim context.
	In reality this number is meaningless as we would run out
	of synchronisation memory before we reach this limit, but
	we need to provide a size to the span RA.
*/
#define MAX_SYNC_MEM				(4 * 1024 * 1024)

typedef struct _SYNC_BLOCK_LIST_
{
	IMG_UINT32			ui32BlockCount;			/*!< Number of contexts in the list */
	IMG_UINT32			ui32BlockListSize;		/*!< Size of the array contexts */
	SYNC_PRIM_BLOCK		**papsSyncPrimBlock;	/*!< Array of syncprim blocks */
} SYNC_BLOCK_LIST;

typedef struct _SYNC_OP_COOKIE_
{
	IMG_UINT32				ui32SyncCount;
	IMG_UINT32				ui32ClientSyncCount;
	IMG_UINT32				ui32ServerSyncCount;
	IMG_BOOL				bHaveServerSync;
	IMG_HANDLE				hBridge;
	IMG_HANDLE				hServerCookie;

	SYNC_BLOCK_LIST			*psSyncBlockList;
	PVRSRV_CLIENT_SYNC_PRIM	**papsSyncPrim;
	/*
		Client sync(s) info.
		If this changes update the calculation of ui32ClientAllocSize
	*/
	IMG_UINT32				*paui32SyncBlockIndex;
	IMG_UINT32				*paui32Index;
	IMG_UINT32				*paui32Flags;
	IMG_UINT32				*paui32FenceValue;
	IMG_UINT32				*paui32UpdateValue;

	/*
		Server sync(s) info
		If this changes update the calculation of ui32ServerAllocSize
	*/
	IMG_HANDLE				*pahServerSync;
	IMG_UINT32              *paui32ServerFlags;
} SYNC_OP_COOKIE;

/* forward declaration */
static PVRSRV_ERROR
_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value);

/*
	Internal interfaces for management of SYNC_PRIM_CONTEXT
*/
static void
_SyncPrimContextUnref(SYNC_PRIM_CONTEXT *psContext)
{
	if (!OSAtomicRead(&psContext->hRefCount))
	{
		PVR_DPF((PVR_DBG_ERROR, "_SyncPrimContextUnref context already freed"));
	}
	else if (0 == OSAtomicDecrement(&psContext->hRefCount))
	{
		/* SyncPrimContextDestroy only when no longer referenced */
		RA_Delete(psContext->psSpanRA);
		RA_Delete(psContext->psSubAllocRA);
		OSFreeMem(psContext);
	}
}

static void
_SyncPrimContextRef(SYNC_PRIM_CONTEXT *psContext)
{
	if (!OSAtomicRead(&psContext->hRefCount))
	{
		PVR_DPF((PVR_DBG_ERROR, "_SyncPrimContextRef context use after free"));
	}
	else
	{
		OSAtomicIncrement(&psContext->hRefCount);
	}
}

/*
	Internal interfaces for management of synchronisation block memory
*/
static PVRSRV_ERROR
AllocSyncPrimitiveBlock(SYNC_PRIM_CONTEXT *psContext,
						SYNC_PRIM_BLOCK **ppsSyncBlock)
{
	SYNC_PRIM_BLOCK *psSyncBlk;
	IMG_HANDLE hSyncPMR;
	IMG_HANDLE hSyncImportHandle;
	IMG_DEVMEM_SIZE_T uiImportSize;
	PVRSRV_ERROR eError;

	psSyncBlk = OSAllocMem(sizeof(SYNC_PRIM_BLOCK));
	if (psSyncBlk == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_alloc;
	}
	psSyncBlk->psContext = psContext;

	/* Allocate sync prim block */
	eError = BridgeAllocSyncPrimitiveBlock(psContext->hDevConnection,
	                                       &psSyncBlk->hServerSyncPrimBlock,
										   &psSyncBlk->ui32FirmwareAddr,
										   &psSyncBlk->ui32SyncBlockSize,
										   &hSyncPMR);
	if (eError != PVRSRV_OK)
	{
		goto fail_blockalloc;
	}

	/* Make it mappable by the client */
	eError = DevmemMakeLocalImportHandle(psContext->hDevConnection,
										hSyncPMR,
										&hSyncImportHandle);
	if (eError != PVRSRV_OK)
	{
		goto fail_export;
	}

	/* Get CPU mapping of the memory block */
	eError = DevmemLocalImport(psContext->hDevConnection,
	                           hSyncImportHandle,
	                           PVRSRV_MEMALLOCFLAG_CPU_READABLE,
	                           &psSyncBlk->hMemDesc,
	                           &uiImportSize,
	                           "SyncPrimitiveBlock");

	/*
		Regardless of success or failure we "undo" the export
	*/
	DevmemUnmakeLocalImportHandle(psContext->hDevConnection,
								 hSyncImportHandle);

	if (eError != PVRSRV_OK)
	{
		goto fail_import;
	}

	eError = DevmemAcquireCpuVirtAddr(psSyncBlk->hMemDesc,
									  (void **) &psSyncBlk->pui32LinAddr);
	if (eError != PVRSRV_OK)
	{
		goto fail_cpuvaddr;
	}

	*ppsSyncBlock = psSyncBlk;
	return PVRSRV_OK;

fail_cpuvaddr:
	DevmemFree(psSyncBlk->hMemDesc);
fail_import:
fail_export:
	BridgeFreeSyncPrimitiveBlock(psContext->hDevConnection,
								 psSyncBlk->hServerSyncPrimBlock);
fail_blockalloc:
	OSFreeMem(psSyncBlk);
fail_alloc:
	return eError;
}

static void
FreeSyncPrimitiveBlock(SYNC_PRIM_BLOCK *psSyncBlk)
{
	SYNC_PRIM_CONTEXT *psContext = psSyncBlk->psContext;

	DevmemReleaseCpuVirtAddr(psSyncBlk->hMemDesc);
	DevmemFree(psSyncBlk->hMemDesc);
	BridgeFreeSyncPrimitiveBlock(psContext->hDevConnection,
								 psSyncBlk->hServerSyncPrimBlock);
	OSFreeMem(psSyncBlk);
}

static PVRSRV_ERROR
SyncPrimBlockImport(RA_PERARENA_HANDLE hArena,
					RA_LENGTH_T uSize,
					RA_FLAGS_T uFlags,
					const IMG_CHAR *pszAnnotation,
					RA_BASE_T *puiBase,
					RA_LENGTH_T *puiActualSize,
					RA_PERISPAN_HANDLE *phImport)
{
	SYNC_PRIM_CONTEXT *psContext = hArena;
	SYNC_PRIM_BLOCK *psSyncBlock = NULL;
	RA_LENGTH_T uiSpanSize;
	PVRSRV_ERROR eError;
	PVR_UNREFERENCED_PARAMETER(uFlags);

	/* Check we've not be called with an unexpected size */
	if (!hArena || sizeof(IMG_UINT32) != uSize)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input params", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto e0;
	}

	/*
		Ensure the synprim context doesn't go away while we have sync blocks
		attached to it
	*/
	_SyncPrimContextRef(psContext);

	/* Allocate the block of memory */
	eError = AllocSyncPrimitiveBlock(psContext, &psSyncBlock);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "Failed to allocate syncprim block (%d)", eError));
		goto fail_syncblockalloc;
	}

	/* Allocate a span for it */
	eError = RA_Alloc(psContext->psSpanRA,
					psSyncBlock->ui32SyncBlockSize,
					RA_NO_IMPORT_MULTIPLIER,
					0,
					psSyncBlock->ui32SyncBlockSize,
					pszAnnotation,
					&psSyncBlock->uiSpanBase,
					&uiSpanSize,
					NULL);
	if (eError != PVRSRV_OK)
	{
		goto fail_spanalloc;
	}

	/*
		There is no reason the span RA should return an allocation larger
		then we request
	*/
	PVR_ASSERT(uiSpanSize == psSyncBlock->ui32SyncBlockSize);

	*puiBase = psSyncBlock->uiSpanBase;
	*puiActualSize = psSyncBlock->ui32SyncBlockSize;
	*phImport = psSyncBlock;
	return PVRSRV_OK;

fail_spanalloc:
	FreeSyncPrimitiveBlock(psSyncBlock);
fail_syncblockalloc:
	_SyncPrimContextUnref(psContext);
e0:
	return eError;
}

static void
SyncPrimBlockUnimport(RA_PERARENA_HANDLE hArena,
					  RA_BASE_T uiBase,
					  RA_PERISPAN_HANDLE hImport)
{
	SYNC_PRIM_CONTEXT *psContext = hArena;
	SYNC_PRIM_BLOCK *psSyncBlock = hImport;

	if (!psContext || !psSyncBlock || uiBase != psSyncBlock->uiSpanBase)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input params", __FUNCTION__));
		return;
	}

	/* Free the span this import is using */
	RA_Free(psContext->psSpanRA, uiBase);

	/* Free the syncpim block */
	FreeSyncPrimitiveBlock(psSyncBlock);

	/*	Drop our reference to the syncprim context */
	_SyncPrimContextUnref(psContext);
}

static INLINE IMG_UINT32 SyncPrimGetOffset(SYNC_PRIM *psSyncInt)
{
	IMG_UINT64 ui64Temp;
	
	PVR_ASSERT(psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL);

	/* FIXME: Subtracting a 64-bit address from another and then implicit
	 * cast to 32-bit number. Need to review all call sequences that use this
	 * function, added explicit casting for now.
	 */
	ui64Temp =  psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
	PVR_ASSERT(ui64Temp<IMG_UINT32_MAX);
	return (IMG_UINT32)ui64Temp;
}

static void SyncPrimGetCPULinAddr(SYNC_PRIM *psSyncInt)
{
	SYNC_PRIM_BLOCK *psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;

	psSyncInt->sCommon.pui32LinAddr = psSyncBlock->pui32LinAddr +
									  (SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32));
}

static void SyncPrimLocalFree(SYNC_PRIM *psSyncInt)
{
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM_CONTEXT *psContext;

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	psContext = psSyncBlock->psContext;

	{
		PVRSRV_ERROR eError;
		IMG_HANDLE hConn =
				psSyncInt->u.sLocal.psSyncBlock->psContext->hDevConnection;

#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
		if(PVRSRVIsBridgeEnabled(hConn, PVRSRV_BRIDGE_SYNCTRACKING))
		{
			if(psSyncInt->u.sLocal.hRecord)
			{
				/* remove this sync record */
				eError = BridgeSyncRecordRemoveByHandle(hConn,
				                                        psSyncInt->u.sLocal.hRecord);
				if (PVRSRV_OK != eError)
				{
					PVR_DPF((PVR_DBG_ERROR, "%s: failed to remove SyncRecord", __FUNCTION__));
				}
			}
		}
		else
#endif /* if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
		{
			IMG_UINT32 ui32FWAddr = psSyncBlock->ui32FirmwareAddr +
					SyncPrimGetOffset(psSyncInt);

			eError = BridgeSyncFreeEvent(hConn, ui32FWAddr);
			if (eError != PVRSRV_OK)
			{
				PVR_DPF((PVR_DBG_WARNING, "BridgeSyncAllocEvent failed with error:"
				        " %d", eError));
			}
		}
	}
	/* reset the sync prim value as it is freed.
	 * this guarantees the client sync allocated to the client will
	 * have a value of zero and the client does not need to
	 * explicitly initialise the sync value to zero.
	 * the allocation of the backing memory for the sync prim block
	 * is done with ZERO_ON_ALLOC so the memory is initially all zero.
	 */
	(void) _SyncPrimSetValue(psSyncInt, LOCAL_SYNC_PRIM_RESET_VALUE);

	RA_Free(psContext->psSubAllocRA, psSyncInt->u.sLocal.uiSpanAddr);
	OSFreeMem(psSyncInt);
	_SyncPrimContextUnref(psContext);
}

static void SyncPrimServerFree(SYNC_PRIM *psSyncInt)
{
	PVRSRV_ERROR eError;

	eError = BridgeServerSyncFree(psSyncInt->u.sServer.hBridge,
								  psSyncInt->u.sServer.hServerSync);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimServerFree failed"));
	}
	OSFreeMem(psSyncInt);
}

static void SyncPrimLocalUnref(SYNC_PRIM *psSyncInt)
{
	if (!OSAtomicRead(&psSyncInt->u.sLocal.hRefCount))
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimLocalUnref sync already freed"));
	}
	else if (0 == OSAtomicDecrement(&psSyncInt->u.sLocal.hRefCount))
	{
		SyncPrimLocalFree(psSyncInt);
	}
}

static void SyncPrimLocalRef(SYNC_PRIM *psSyncInt)
{
	if (!OSAtomicRead(&psSyncInt->u.sLocal.hRefCount))
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimLocalRef sync use after free"));
	}
	else
	{
		OSAtomicIncrement(&psSyncInt->u.sLocal.hRefCount);
	}
}

static IMG_UINT32 SyncPrimGetFirmwareAddrLocal(SYNC_PRIM *psSyncInt)
{
	SYNC_PRIM_BLOCK *psSyncBlock;

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	return psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psSyncInt);	
}

static IMG_UINT32 SyncPrimGetFirmwareAddrServer(SYNC_PRIM *psSyncInt)
{
	return psSyncInt->u.sServer.ui32FirmwareAddr;
}

#if !defined(__KERNEL__)
static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleLocal(SYNC_PRIM *psSyncInt)
{
	return psSyncInt->u.sLocal.psSyncBlock->psContext->hDevConnection;
}

static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandleServer(SYNC_PRIM *psSyncInt)
{
	return psSyncInt->u.sServer.hBridge;
}

static SYNC_BRIDGE_HANDLE _SyncPrimGetBridgeHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
{
	SYNC_PRIM *psSyncInt;

	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		return _SyncPrimGetBridgeHandleLocal(psSyncInt);
	}
	else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
	{
		return _SyncPrimGetBridgeHandleServer(psSyncInt);
	}
	else
	{
		PVR_DPF((PVR_DBG_ERROR, "_SyncPrimGetBridgeHandle: Invalid sync type"));
		/*
			Either the client has given us a bad pointer or there is an
			error in this module
		*/
		return 0;
	}
}
#endif

/*
	Internal interfaces for management of syncprim block lists
*/
static SYNC_BLOCK_LIST *_SyncPrimBlockListCreate(void)
{
	SYNC_BLOCK_LIST *psBlockList;

	psBlockList = OSAllocMem(sizeof(SYNC_BLOCK_LIST));
	if (!psBlockList)
	{
		return NULL;
	}

	psBlockList->ui32BlockCount = 0;
	psBlockList->ui32BlockListSize = SYNC_BLOCK_LIST_CHUNCK_SIZE;

	psBlockList->papsSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *)
													* SYNC_BLOCK_LIST_CHUNCK_SIZE);
	if (!psBlockList->papsSyncPrimBlock)
	{
		OSFreeMem(psBlockList);
		return NULL;
	}

	OSCachedMemSet(psBlockList->papsSyncPrimBlock,
			 0,
			 sizeof(SYNC_PRIM_BLOCK *) * psBlockList->ui32BlockListSize);

	return psBlockList;
}

static PVRSRV_ERROR _SyncPrimBlockListAdd(SYNC_BLOCK_LIST *psBlockList,
											SYNC_PRIM_BLOCK *psSyncPrimBlock)
{
	IMG_UINT32 i;

	/* Check the context isn't already on the list */
	for (i=0;i<psBlockList->ui32BlockCount;i++)
	{
		if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
		{
			return PVRSRV_OK;
		}
	}

	/* Check we have space for a new item */
	if (psBlockList->ui32BlockCount == psBlockList->ui32BlockListSize)
	{
		SYNC_PRIM_BLOCK	**papsNewSyncPrimBlock;

		papsNewSyncPrimBlock = OSAllocMem(sizeof(SYNC_PRIM_BLOCK *) *
											(psBlockList->ui32BlockListSize +
											SYNC_BLOCK_LIST_CHUNCK_SIZE));
		if (!papsNewSyncPrimBlock)
		{
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}

		OSCachedMemCopy(papsNewSyncPrimBlock,
				  psBlockList->papsSyncPrimBlock,
				  sizeof(SYNC_PRIM_CONTEXT *) *
				  psBlockList->ui32BlockListSize);

		OSFreeMem(psBlockList->papsSyncPrimBlock);

		psBlockList->papsSyncPrimBlock = papsNewSyncPrimBlock;
		psBlockList->ui32BlockListSize += SYNC_BLOCK_LIST_CHUNCK_SIZE;
	}

	/* Add the context to the list */
	psBlockList->papsSyncPrimBlock[psBlockList->ui32BlockCount++] = psSyncPrimBlock;
	return PVRSRV_OK;
}

static PVRSRV_ERROR _SyncPrimBlockListBlockToIndex(SYNC_BLOCK_LIST *psBlockList,
												   SYNC_PRIM_BLOCK *psSyncPrimBlock,
												   IMG_UINT32 *pui32Index)
{
	IMG_UINT32 i;

	for (i=0;i<psBlockList->ui32BlockCount;i++)
	{
		if (psBlockList->papsSyncPrimBlock[i] == psSyncPrimBlock)
		{
			*pui32Index = i;
			return PVRSRV_OK;
		}
	}

	return PVRSRV_ERROR_INVALID_PARAMS;
}

static PVRSRV_ERROR _SyncPrimBlockListHandleArrayCreate(SYNC_BLOCK_LIST *psBlockList,
														IMG_UINT32 *pui32BlockHandleCount,
														IMG_HANDLE **ppahHandleList)
{
	IMG_HANDLE *pahHandleList;
	IMG_UINT32 i;

	pahHandleList = OSAllocMem(sizeof(IMG_HANDLE) *
							   psBlockList->ui32BlockCount);
	if (!pahHandleList)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	for (i=0;i<psBlockList->ui32BlockCount;i++)
	{
		pahHandleList[i] = psBlockList->papsSyncPrimBlock[i]->hServerSyncPrimBlock;
	}

	*ppahHandleList = pahHandleList;
	*pui32BlockHandleCount = psBlockList->ui32BlockCount;

	return PVRSRV_OK;
}

static void _SyncPrimBlockListHandleArrayDestroy(IMG_HANDLE *pahHandleList)
{
	OSFreeMem(pahHandleList);
}

static IMG_UINT32 _SyncPrimBlockListGetClientValue(SYNC_BLOCK_LIST *psBlockList,
												   IMG_UINT32 ui32BlockIndex,
												   IMG_UINT32 ui32Index)
{
	return psBlockList->papsSyncPrimBlock[ui32BlockIndex]->pui32LinAddr[ui32Index];
}

static void _SyncPrimBlockListDestroy(SYNC_BLOCK_LIST *psBlockList)
{
	OSFreeMem(psBlockList->papsSyncPrimBlock);
	OSFreeMem(psBlockList);
}


static INLINE IMG_UINT32 _Log2(IMG_UINT32 ui32Align)
{
	PVR_ASSERT(IsPower2(ui32Align));
	return ExactLog2(ui32Align);
}

/*
	External interfaces
*/

IMG_INTERNAL PVRSRV_ERROR
SyncPrimContextCreate(SHARED_DEV_CONNECTION hDevConnection,
                      PSYNC_PRIM_CONTEXT *phSyncPrimContext)
{
	SYNC_PRIM_CONTEXT *psContext;
	PVRSRV_ERROR eError;

	psContext = OSAllocMem(sizeof(SYNC_PRIM_CONTEXT));
	if (psContext == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_alloc;
	}

	psContext->hDevConnection = hDevConnection;

	OSSNPrintf(psContext->azName, SYNC_PRIM_NAME_SIZE, "Sync Prim RA-%p", psContext);
	OSSNPrintf(psContext->azSpanName, SYNC_PRIM_NAME_SIZE, "Sync Prim span RA-%p", psContext);

	/*
		Create the RA for sub-allocations of the SynPrim's

		Note:
		The import size doesn't matter here as the server will pass
		back the blocksize when does the import which overrides
		what we specify here.
	*/

	psContext->psSubAllocRA = RA_Create(psContext->azName,
										/* Params for imports */
										_Log2(sizeof(IMG_UINT32)),
										RA_LOCKCLASS_2,
										SyncPrimBlockImport,
										SyncPrimBlockUnimport,
										psContext,
										IMG_FALSE);
	if (psContext->psSubAllocRA == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_suballoc;
	}

	/*
		Create the span-management RA

		The RA requires that we work with linear spans. For our use
		here we don't require this behaviour as we're always working
		within offsets of blocks (imports). However, we need to keep
		the RA happy so we create the "span" management RA which
		ensures that all are imports are added to the RA in a linear
		fashion
	*/
	psContext->psSpanRA = RA_Create(psContext->azSpanName,
									/* Params for imports */
									0,
									RA_LOCKCLASS_1,
									NULL,
									NULL,
									NULL,
									IMG_FALSE);
	if (psContext->psSpanRA == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_span;
	}

	if (!RA_Add(psContext->psSpanRA, 0, MAX_SYNC_MEM, 0, NULL))
	{
		RA_Delete(psContext->psSpanRA);
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_span;
	}

	OSAtomicWrite(&psContext->hRefCount, 1);

	*phSyncPrimContext = psContext;
	return PVRSRV_OK;
fail_span:
	RA_Delete(psContext->psSubAllocRA);
fail_suballoc:
	OSFreeMem(psContext);
fail_alloc:
	return eError;
}

IMG_INTERNAL void SyncPrimContextDestroy(PSYNC_PRIM_CONTEXT hSyncPrimContext)
{
	SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
	if (1 != OSAtomicRead(&psContext->hRefCount))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s attempted with active references, may be the result of a race", __FUNCTION__));
	}
#if defined(PVRSRV_FORCE_UNLOAD_IF_BAD_STATE)
#if defined(__KERNEL__)
	if (PVRSRVGetPVRSRVData()->eServicesState != PVRSRV_SERVICES_STATE_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: Forcing context destruction due to bad driver state.", __FUNCTION__));
		OSAtomicWrite(&psContext->hRefCount, 1);
	}
#endif
#endif
	_SyncPrimContextUnref(psContext);
}

static PVRSRV_ERROR _SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
                                   PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
                                   const IMG_CHAR *pszClassName,
                                   IMG_BOOL bServerSync)
{
	SYNC_PRIM_CONTEXT *psContext = hSyncPrimContext;
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM *psNewSync;
	PVRSRV_ERROR eError;
	RA_BASE_T uiSpanAddr;

	if (!hSyncPrimContext)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid context", __func__));
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
	if (psNewSync == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto fail_alloc;
	}

	eError = RA_Alloc(psContext->psSubAllocRA,
	                  sizeof(IMG_UINT32),
	                  RA_NO_IMPORT_MULTIPLIER,
	                  0,
	                  sizeof(IMG_UINT32),
	                  "Sync_Prim",
	                  &uiSpanAddr,
	                  NULL,
	                  (RA_PERISPAN_HANDLE *) &psSyncBlock);
	if (PVRSRV_OK != eError)
	{
		goto fail_raalloc;
	}
	psNewSync->eType = SYNC_PRIM_TYPE_LOCAL;
	OSAtomicWrite(&psNewSync->u.sLocal.hRefCount, 1);
	psNewSync->u.sLocal.uiSpanAddr = uiSpanAddr;
	psNewSync->u.sLocal.psSyncBlock = psSyncBlock;
	SyncPrimGetCPULinAddr(psNewSync);
	*ppsSync = &psNewSync->sCommon;
	_SyncPrimContextRef(psContext);

#if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING)
	if(PVRSRVIsBridgeEnabled(psSyncBlock->psContext->hDevConnection, PVRSRV_BRIDGE_SYNCTRACKING))
	{
		IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
		if(pszClassName)
		{
			/* Copy the class name annotation into a fixed-size array */
			OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
			szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
		}
		else
		{
			/* No class name annotation */
			szClassName[0] = 0;
		}
		/* record this sync */
		eError = BridgeSyncRecordAdd(
					psSyncBlock->psContext->hDevConnection,
					&psNewSync->u.sLocal.hRecord,
					psSyncBlock->hServerSyncPrimBlock,
					psSyncBlock->ui32FirmwareAddr,
					SyncPrimGetOffset(psNewSync),
					bServerSync,
					OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
					szClassName);
		if (PVRSRV_OK != eError)
		{
			PVR_DPF((PVR_DBG_ERROR, "%s: failed to add SyncRecord \"%s\" (%s)",
											__FUNCTION__,
											szClassName,
											PVRSRVGETERRORSTRING(eError)));
			psNewSync->u.sLocal.hRecord = NULL;
		}
	}
	else
#endif /* if defined(PVRSRV_ENABLE_FULL_SYNC_TRACKING) */
	{
		eError = BridgeSyncAllocEvent(hSyncPrimContext->hDevConnection,
		                              bServerSync,
		                              psSyncBlock->ui32FirmwareAddr + SyncPrimGetOffset(psNewSync),
		                              OSStringNLength(pszClassName, SYNC_MAX_CLASS_NAME_LEN),
		                              pszClassName);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_WARNING, "BridgeSyncAllocEvent failed with error: %d",
			        eError));
		}
	}

	return PVRSRV_OK;

fail_raalloc:
	OSFreeMem(psNewSync);
fail_alloc:
	return eError;
}

#if defined(__KERNEL__)
IMG_INTERNAL PVRSRV_ERROR SyncPrimAllocForServerSync(PSYNC_PRIM_CONTEXT hSyncPrimContext,
										PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
										const IMG_CHAR *pszClassName)
{
	return _SyncPrimAlloc(hSyncPrimContext,
					  ppsSync,
					  pszClassName,
					  IMG_TRUE);
}
#endif

IMG_INTERNAL PVRSRV_ERROR SyncPrimAlloc(PSYNC_PRIM_CONTEXT hSyncPrimContext,
										PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
										const IMG_CHAR *pszClassName)
{
	return _SyncPrimAlloc(hSyncPrimContext,
	                      ppsSync,
	                      pszClassName,
	                      IMG_FALSE);
}

static PVRSRV_ERROR
_SyncPrimSetValue(SYNC_PRIM *psSyncInt, IMG_UINT32 ui32Value)
{
	PVRSRV_ERROR eError;

	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		SYNC_PRIM_BLOCK *psSyncBlock;
		SYNC_PRIM_CONTEXT *psContext;

		psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
		psContext = psSyncBlock->psContext;

		eError = BridgeSyncPrimSet(psContext->hDevConnection,
									psSyncBlock->hServerSyncPrimBlock,
									SyncPrimGetOffset(psSyncInt)/sizeof(IMG_UINT32),
									ui32Value);
	}
	else
	{
		eError = BridgeServerSyncPrimSet(psSyncInt->u.sServer.hBridge,
									psSyncInt->u.sServer.hServerSync,
									ui32Value);
	}
	/* These functions don't actually fail */
	return eError;
}

IMG_INTERNAL PVRSRV_ERROR SyncPrimFree(PVRSRV_CLIENT_SYNC_PRIM *psSync)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}

	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		SyncPrimLocalUnref(psSyncInt);
	}
	else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
	{
		SyncPrimServerFree(psSyncInt);
	}
	else
	{
		/*
			Either the client has given us a bad pointer or there is an
			error in this module
		*/
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid sync type", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto err_out;
	}

err_out:
	return eError;
}

#if defined(NO_HARDWARE)
IMG_INTERNAL PVRSRV_ERROR
SyncPrimNoHwUpdate(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	/* There is no check for the psSyncInt to be LOCAL as this call
	   substitutes the Firmware updating a sync and that sync could
	   be a server one */

	eError =  _SyncPrimSetValue(psSyncInt, ui32Value);

err_out:
	return eError;
}
#endif

IMG_INTERNAL PVRSRV_ERROR
SyncPrimSet(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: null sync pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}

	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimSet: Invalid sync type"));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto err_out;
	}

	eError = _SyncPrimSetValue(psSyncInt, ui32Value);

#if defined(PDUMP)
	SyncPrimPDump(psSync);
#endif
err_out:
	return eError;
}

IMG_INTERNAL PVRSRV_ERROR SyncPrimLocalGetHandleAndOffset(PVRSRV_CLIENT_SYNC_PRIM *psSync,
							IMG_HANDLE *phBlock,
							IMG_UINT32 *pui32Offset)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	if(!psSync || !phBlock || !pui32Offset)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimGetHandleAndOffset: invalid input pointer"));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}

	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		*phBlock = psSyncInt->u.sLocal.psSyncBlock->hServerSyncPrimBlock;
		*pui32Offset = psSyncInt->u.sLocal.uiSpanAddr - psSyncInt->u.sLocal.psSyncBlock->uiSpanBase;
	}
	else
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: psSync not a Local sync prim (%d)",
			__FUNCTION__, psSyncInt->eType));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}

err_out:
	return eError;
}

IMG_INTERNAL PVRSRV_ERROR
SyncPrimGetFirmwareAddr(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 *pui32FwAddr)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	*pui32FwAddr = 0;
	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto err_out;
	}

	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		*pui32FwAddr = SyncPrimGetFirmwareAddrLocal(psSyncInt);
	}
	else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
	{
		*pui32FwAddr = SyncPrimGetFirmwareAddrServer(psSyncInt);
	}
	else
	{
		/* Either the client has given us a bad pointer or there is an
		 * error in this module
		 */
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid sync type", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto err_out;
	}

err_out:
	return eError;
}

#if !defined(__KERNEL__)
IMG_INTERNAL PVRSRV_ERROR SyncPrimDumpSyncs(IMG_UINT32 ui32SyncCount, PVRSRV_CLIENT_SYNC_PRIM **papsSync, const IMG_CHAR *pcszExtraInfo)
{
#if defined(PVRSRV_NEED_PVR_DPF)
	SYNC_PRIM *psSyncInt;
	PVRSRV_CLIENT_SYNC_PRIM **papsServerSync;
	IMG_UINT32 ui32ServerSyncs = 0;
	IMG_UINT32 *pui32UID = NULL;
	IMG_UINT32 *pui32FWAddr = NULL;
	IMG_UINT32 *pui32CurrentOp = NULL;
	IMG_UINT32 *pui32NextOp = NULL;
	IMG_UINT32 i;
	PVRSRV_ERROR eError = PVRSRV_OK;

	papsServerSync = OSAllocMem(ui32SyncCount * sizeof(PVRSRV_CLIENT_SYNC_PRIM *));
	if (!papsServerSync)
	{
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	for (i = 0; i < ui32SyncCount; i++)
	{
		psSyncInt = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);
		if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
		{
			PVR_DPF((PVR_DBG_ERROR, "%s: sync=local  fw=0x%x curr=0x%04x",
					 pcszExtraInfo,
					 SyncPrimGetFirmwareAddrLocal(psSyncInt),
					 *psSyncInt->sCommon.pui32LinAddr));
		}
		else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
		{
			papsServerSync[ui32ServerSyncs++] = papsSync[i];
		}
		else
		{
			PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Invalid sync type"));
			/*
			   Either the client has given us a bad pointer or there is an
			   error in this module
			   */
			eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
			goto err_free;
		}
	}

	if (ui32ServerSyncs > 0)
	{
		pui32UID = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
		if (!pui32UID)
		{
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto err_free;
		}
		pui32FWAddr = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
		if (!pui32FWAddr)
		{
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto err_free;
		}
		pui32CurrentOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
		if (!pui32CurrentOp)
		{
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto err_free;
		}
		pui32NextOp = OSAllocMem(ui32ServerSyncs * sizeof(IMG_UINT32));
		if (!pui32NextOp)
		{
			eError = PVRSRV_ERROR_OUT_OF_MEMORY;
			goto err_free;
		}
		eError = SyncPrimServerGetStatus(ui32ServerSyncs, papsServerSync,
										 pui32UID,
										 pui32FWAddr,
										 pui32CurrentOp,
										 pui32NextOp);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "SyncPrimDumpSyncs: Error querying server sync status (%d)",
					 eError));
			goto err_free;
		}
		for (i = 0; i < ui32ServerSyncs; i++)
		{
			PVR_DPF((PVR_DBG_ERROR, "%s: sync=server fw=0x%x curr=0x%04x next=0x%04x id=%u%s",
					 pcszExtraInfo,
					 pui32FWAddr[i],
					 pui32CurrentOp[i],
					 pui32NextOp[i],
					 pui32UID[i],
					 (pui32NextOp[i] - pui32CurrentOp[i] == 1) ? " *" : 
					 (pui32NextOp[i] - pui32CurrentOp[i] >  1) ? " **" : 
					 ""));
		}
	}

err_free:
	OSFreeMem(papsServerSync);
	if (pui32UID)
	{
		OSFreeMem(pui32UID);
	}
	if (pui32FWAddr)
	{
		OSFreeMem(pui32FWAddr);
	}
	if (pui32CurrentOp)
	{
		OSFreeMem(pui32CurrentOp);
	}
	if (pui32NextOp)
	{
		OSFreeMem(pui32NextOp);
	}
	return eError;
#else
	PVR_UNREFERENCED_PARAMETER(ui32SyncCount);
	PVR_UNREFERENCED_PARAMETER(papsSync);
	PVR_UNREFERENCED_PARAMETER(pcszExtraInfo);
	return PVRSRV_OK;
#endif
}
#endif

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpCreate(IMG_UINT32 ui32SyncCount,
			  PVRSRV_CLIENT_SYNC_PRIM **papsSyncPrim,
			  PSYNC_OP_COOKIE *ppsCookie)
{
	SYNC_OP_COOKIE *psNewCookie;
	SYNC_BLOCK_LIST *psSyncBlockList;
	IMG_UINT32 ui32ServerSyncCount = 0;
	IMG_UINT32 ui32ClientSyncCount = 0;
	IMG_UINT32 ui32ServerAllocSize;
	IMG_UINT32 ui32ClientAllocSize;
	IMG_UINT32 ui32TotalAllocSize;
	IMG_UINT32 ui32ServerIndex = 0;
	IMG_UINT32 ui32ClientIndex = 0;
	IMG_UINT32 i;
	IMG_UINT32 ui32SyncBlockCount;
	IMG_HANDLE hBridge;
	IMG_HANDLE *pahHandleList;
	IMG_CHAR *pcPtr;
	PVRSRV_ERROR eError;
	IMG_BOOL bServerSync;

	psSyncBlockList = _SyncPrimBlockListCreate();

	if (!psSyncBlockList)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e0;
	}

	for (i=0;i<ui32SyncCount;i++)
	{
		eError = SyncPrimIsServerSync(papsSyncPrim[i], &bServerSync);
		if (PVRSRV_OK != eError) goto e1;
		if (bServerSync)
		{
			ui32ServerSyncCount++;
		}
		else
		{
			SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];

			ui32ClientSyncCount++;
			eError = _SyncPrimBlockListAdd(psSyncBlockList, psSync->u.sLocal.psSyncBlock);
			if (eError != PVRSRV_OK)
			{
				goto e1;
			}
		}
	}

	ui32ServerAllocSize = ui32ServerSyncCount * (sizeof(IMG_HANDLE) + sizeof(IMG_UINT32));
	ui32ClientAllocSize = ui32ClientSyncCount * (5 * sizeof(IMG_UINT32));
	ui32TotalAllocSize = sizeof(SYNC_OP_COOKIE) +
							 (sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount) +
							 ui32ServerAllocSize + 
							 ui32ClientAllocSize;

	psNewCookie = OSAllocMem(ui32TotalAllocSize);
	pcPtr = (IMG_CHAR *) psNewCookie;

	if (!psNewCookie)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e1;
	}

	/* Setup the pointers */
	pcPtr += sizeof(SYNC_OP_COOKIE);
	psNewCookie->papsSyncPrim = (PVRSRV_CLIENT_SYNC_PRIM **) pcPtr;

	pcPtr += sizeof(PVRSRV_CLIENT_SYNC_PRIM *) * ui32SyncCount;
	psNewCookie->paui32SyncBlockIndex = (IMG_UINT32 *) pcPtr;

	pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
	psNewCookie->paui32Index = (IMG_UINT32 *) pcPtr;

	pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
	psNewCookie->paui32Flags = (IMG_UINT32 *) pcPtr;

	pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
	psNewCookie->paui32FenceValue = (IMG_UINT32 *) pcPtr;

	pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
	psNewCookie->paui32UpdateValue = (IMG_UINT32 *) pcPtr;

	pcPtr += sizeof(IMG_UINT32) * ui32ClientSyncCount;
	psNewCookie->pahServerSync =(IMG_HANDLE *) pcPtr;
	pcPtr += sizeof(IMG_HANDLE) * ui32ServerSyncCount;

	psNewCookie->paui32ServerFlags =(IMG_UINT32 *) pcPtr;
	pcPtr += sizeof(IMG_UINT32) * ui32ServerSyncCount;

	/* Check the pointer setup went ok */
	if (!(pcPtr == (((IMG_CHAR *) psNewCookie) + ui32TotalAllocSize)))
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: cookie setup failed", __FUNCTION__));
		eError = PVRSRV_ERROR_INTERNAL_ERROR;
		goto e2;
	}

	psNewCookie->ui32SyncCount = ui32SyncCount;
	psNewCookie->ui32ServerSyncCount = ui32ServerSyncCount;
	psNewCookie->ui32ClientSyncCount = ui32ClientSyncCount;
	psNewCookie->psSyncBlockList = psSyncBlockList;

	/*
		Get the bridge handle from the 1st sync.

		Note: We assume the all syncs have been created with the same
			  services connection.
	*/
	eError = SyncPrimIsServerSync(papsSyncPrim[0], &bServerSync);
	if (PVRSRV_OK != eError) goto e2;
	if (bServerSync)
	{
		SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];

		hBridge = psSync->u.sServer.hBridge;
	}
	else
	{
		SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[0];

		hBridge = psSync->u.sLocal.psSyncBlock->psContext->hDevConnection;
	}

	psNewCookie->hBridge = hBridge;

	if (ui32ServerSyncCount)
	{
		psNewCookie->bHaveServerSync = IMG_TRUE;
	}
	else
	{
		psNewCookie->bHaveServerSync = IMG_FALSE;
	}

	/* Fill in the server and client sync data */
	for (i=0;i<ui32SyncCount;i++)
	{
		SYNC_PRIM *psSync = (SYNC_PRIM *) papsSyncPrim[i];

		eError = SyncPrimIsServerSync(papsSyncPrim[i], &bServerSync);
		if (PVRSRV_OK != eError) goto e2;
		if (bServerSync)
		{
			psNewCookie->pahServerSync[ui32ServerIndex] = psSync->u.sServer.hServerSync;

			ui32ServerIndex++;
		}
		else
		{
			/* Location of sync */
			eError = _SyncPrimBlockListBlockToIndex(psSyncBlockList,
													psSync->u.sLocal.psSyncBlock,
													&psNewCookie->paui32SyncBlockIndex[ui32ClientIndex]);
			if (eError != PVRSRV_OK)
			{
				goto e2;
			}

			/* Workout the index to sync */
			psNewCookie->paui32Index[ui32ClientIndex] =
					SyncPrimGetOffset(psSync)/sizeof(IMG_UINT32);

			ui32ClientIndex++;
		}

		psNewCookie->papsSyncPrim[i] = papsSyncPrim[i];
	}

	eError = _SyncPrimBlockListHandleArrayCreate(psSyncBlockList,
												 &ui32SyncBlockCount,
												 &pahHandleList);
	if (eError !=PVRSRV_OK)
	{
		goto e2;
	}

	/*
		Create the server side cookie. Here we pass in all the unchanging
		data so we only need to pass in the minimum at takeop time
	*/
	eError = BridgeSyncPrimOpCreate(hBridge,
									ui32SyncBlockCount,
									pahHandleList,
									psNewCookie->ui32ClientSyncCount,
									psNewCookie->paui32SyncBlockIndex,
									psNewCookie->paui32Index,
									psNewCookie->ui32ServerSyncCount,
									psNewCookie->pahServerSync,
									&psNewCookie->hServerCookie);

	/* Free the handle list regardless of error */
	_SyncPrimBlockListHandleArrayDestroy(pahHandleList);

	if (eError != PVRSRV_OK)
	{
		goto e2;
	}

	/* Increase the reference count on all referenced local sync prims
	 * so that they cannot be freed until this Op is finished with
	 */
	for (i=0;i<ui32SyncCount;i++)
	{
		SYNC_PRIM *psSyncInt;
		psSyncInt = IMG_CONTAINER_OF(papsSyncPrim[i], SYNC_PRIM, sCommon);
		if (SYNC_PRIM_TYPE_LOCAL == psSyncInt->eType)
		{
			SyncPrimLocalRef(psSyncInt);
		}
	}

	*ppsCookie = psNewCookie;
	return PVRSRV_OK;

e2:
	OSFreeMem(psNewCookie);
e1:
	_SyncPrimBlockListDestroy(psSyncBlockList);
e0:
	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpTake(PSYNC_OP_COOKIE psCookie,
							IMG_UINT32 ui32SyncCount,
							PVRSRV_CLIENT_SYNC_PRIM_OP *pasSyncOp)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	IMG_UINT32 ui32ServerIndex = 0;
	IMG_UINT32 ui32ClientIndex = 0;
	IMG_UINT32 i;
	IMG_BOOL bServerSync;

	/* Copy client sync operations */
	for (i=0;i<ui32SyncCount;i++)
	{
		/*
			Sanity check the client passes in the same syncs as the
			ones we got at create time
		*/
		if (psCookie->papsSyncPrim[i] != pasSyncOp[i].psSync)
		{
			eError = PVRSRV_ERROR_INVALID_PARAMS;
			goto e0;
		}

		eError = SyncPrimIsServerSync(pasSyncOp[i].psSync, &bServerSync);
		if (PVRSRV_OK != eError) goto e0;
		if (bServerSync)
		{
			psCookie->paui32ServerFlags[ui32ServerIndex] =
					pasSyncOp[i].ui32Flags;

			ui32ServerIndex++;
		}
		else
		{
			/* Client operation information */
			psCookie->paui32Flags[ui32ClientIndex] =
					pasSyncOp[i].ui32Flags;
			psCookie->paui32FenceValue[ui32ClientIndex] =
					pasSyncOp[i].ui32FenceValue;
			psCookie->paui32UpdateValue[ui32ClientIndex] =
					pasSyncOp[i].ui32UpdateValue;

			ui32ClientIndex++;
		}
	}

	eError = BridgeSyncPrimOpTake(psCookie->hBridge,
								  psCookie->hServerCookie,
								  psCookie->ui32ClientSyncCount,
								  psCookie->paui32Flags,
								  psCookie->paui32FenceValue,
								  psCookie->paui32UpdateValue,
								  psCookie->ui32ServerSyncCount,
								  psCookie->paui32ServerFlags);

e0:
	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpReady(PSYNC_OP_COOKIE psCookie,
							 IMG_BOOL *pbReady)
{
	PVRSRV_ERROR eError;
	if (!psCookie)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto e0;
	}

	/*
		If we have a server sync we have no choice
		but to do the check in the server
	*/
	if (psCookie->bHaveServerSync)
	{
		eError = BridgeSyncPrimOpReady(psCookie->hBridge,
									   psCookie->hServerCookie,
									   pbReady);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR,
					 "%s: Failed to do sync check in server (Error = %d)",
					 __FUNCTION__, eError));
			goto e0;
		}
	}
	else
	{
		IMG_UINT32 i;
		IMG_UINT32 ui32SnapShot;
		IMG_BOOL bReady = IMG_TRUE;

		for (i=0;i<psCookie->ui32ClientSyncCount;i++)
		{
			if ((psCookie->paui32Flags[i] & PVRSRV_CLIENT_SYNC_PRIM_OP_CHECK) == 0)
			{
				continue;
			}

			ui32SnapShot = _SyncPrimBlockListGetClientValue(psCookie->psSyncBlockList,
															psCookie->paui32SyncBlockIndex[i],
															psCookie->paui32Index[i]);
			if (ui32SnapShot != psCookie->paui32FenceValue[i])
			{
				bReady = IMG_FALSE;
				break;
			}
		}

		*pbReady = bReady;
	}

	return PVRSRV_OK;
e0:
	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpComplete(PSYNC_OP_COOKIE psCookie)
{
	PVRSRV_ERROR eError;

	eError = BridgeSyncPrimOpComplete(psCookie->hBridge,
									  psCookie->hServerCookie);

	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpDestroy(PSYNC_OP_COOKIE psCookie)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	IMG_UINT32 i;

	eError = BridgeSyncPrimOpDestroy(psCookie->hBridge, psCookie->hServerCookie);
	if (PVRSRV_OK != eError)
	{
		PVR_DPF((PVR_DBG_ERROR,
			"%s: Failed to destroy SyncPrimOp (Error = %d)",
			 __FUNCTION__, eError));
		goto err_out;
	}

	/* Decrease the reference count on all referenced local sync prims
	 * so that they can be freed now this Op is finished with
	 */
	for (i=0;i<psCookie->ui32SyncCount;i++)
	{
		SYNC_PRIM *psSyncInt;
		psSyncInt = IMG_CONTAINER_OF(psCookie->papsSyncPrim[i], SYNC_PRIM, sCommon);
		if (SYNC_PRIM_TYPE_LOCAL == psSyncInt->eType)
		{
			SyncPrimLocalUnref(psSyncInt);
		}
	}

	_SyncPrimBlockListDestroy(psCookie->psSyncBlockList);
	OSFreeMem(psCookie);

err_out:
	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimOpResolve(PSYNC_OP_COOKIE psCookie,
							   IMG_UINT32 *pui32SyncCount,
							   PVRSRV_CLIENT_SYNC_PRIM_OP **ppsSyncOp)
{
	IMG_UINT32 ui32ServerIndex = 0;
	IMG_UINT32 ui32ClientIndex = 0;
	PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOps;
	IMG_UINT32 i;
	IMG_BOOL bServerSync;
	PVRSRV_ERROR eError = PVRSRV_OK;

	psSyncOps = OSAllocMem(sizeof(PVRSRV_CLIENT_SYNC_PRIM_OP) * 
						   psCookie->ui32SyncCount);
	if (!psSyncOps)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e0;
	}

	for (i=0; i<psCookie->ui32SyncCount; i++)
	{
		psSyncOps[i].psSync = psCookie->papsSyncPrim[i];
		eError = SyncPrimIsServerSync(psCookie->papsSyncPrim[i], &bServerSync);
		if (PVRSRV_OK != eError) goto e1;
		if (bServerSync)
		{
			psSyncOps[i].ui32FenceValue = 0;
			psSyncOps[i].ui32UpdateValue = 0;
			psSyncOps[i].ui32Flags = psCookie->paui32ServerFlags[ui32ServerIndex];
			ui32ServerIndex++;
		}
		else
		{
			psSyncOps[i].ui32FenceValue = psCookie->paui32FenceValue[ui32ClientIndex]; 
			psSyncOps[i].ui32UpdateValue = psCookie->paui32UpdateValue[ui32ClientIndex]; 
			psSyncOps[i].ui32Flags = psCookie->paui32Flags[ui32ClientIndex];
			ui32ClientIndex++;
		}
	}

	*ppsSyncOp = psSyncOps;
	*pui32SyncCount = psCookie->ui32SyncCount;

e1:
	OSFreeMem(psSyncOps);
e0:
	return eError;
}

#if !defined(__KERNEL__)
IMG_INTERNAL
PVRSRV_ERROR SyncPrimServerAlloc(SYNC_BRIDGE_HANDLE hBridge,
								 PVRSRV_CLIENT_SYNC_PRIM **ppsSync,
								 const IMG_CHAR *pszClassName
								 PVR_DBG_FILELINE_PARAM)
{
	IMG_CHAR szClassName[SYNC_MAX_CLASS_NAME_LEN];
	SYNC_PRIM *psNewSync;
	PVRSRV_ERROR eError;

#if !defined(PVR_SYNC_PRIM_ALLOC_TRACE)
	PVR_DBG_FILELINE_UNREF();
#endif
	psNewSync = OSAllocMem(sizeof(SYNC_PRIM));
	if (psNewSync == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e0;
	}
	OSCachedMemSet(psNewSync, 0, sizeof(SYNC_PRIM));

	if(pszClassName)
	{
		/* Copy the class name annotation into a fixed-size array */
		OSStringNCopy(szClassName, pszClassName, SYNC_MAX_CLASS_NAME_LEN - 1);
		szClassName[SYNC_MAX_CLASS_NAME_LEN - 1] = 0;
	}
	else
	{
		/* No class name annotation */
		szClassName[0] = 0;
	}

	eError = BridgeServerSyncAlloc(hBridge,
								   &psNewSync->u.sServer.hServerSync,
								   &psNewSync->u.sServer.ui32FirmwareAddr,
								   OSStringNLength(szClassName, SYNC_MAX_CLASS_NAME_LEN),
								   szClassName);

	if (eError != PVRSRV_OK)
	{
		goto e1;
	}

#if defined(PVR_SYNC_PRIM_ALLOC_TRACE)
	PVR_DPF((PVR_DBG_WARNING, "Allocated sync=server fw=0x%x [%p]" PVR_DBG_FILELINE_FMT,
			 psNewSync->u.sServer.ui32FirmwareAddr, &psNewSync->sCommon PVR_DBG_FILELINE_ARG));
#endif

	psNewSync->eType = SYNC_PRIM_TYPE_SERVER;
	psNewSync->u.sServer.hBridge = hBridge;
	*ppsSync = &psNewSync->sCommon;

	return PVRSRV_OK;
e1:
	OSFreeMem(psNewSync);
e0:
	return eError;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimServerGetStatus(IMG_UINT32 ui32SyncCount,
									 PVRSRV_CLIENT_SYNC_PRIM **papsSync,
									 IMG_UINT32 *pui32UID,
									 IMG_UINT32 *pui32FWAddr,
									 IMG_UINT32 *pui32CurrentOp,
									 IMG_UINT32 *pui32NextOp)
{
	PVRSRV_ERROR eError;
	IMG_UINT32 i;
	SYNC_BRIDGE_HANDLE hBridge = NULL;
	IMG_HANDLE *pahServerHandle;
	IMG_BOOL bServerSync;

	if (papsSync[0])
	{
		hBridge = _SyncPrimGetBridgeHandle(papsSync[0]);
	}
	if (!hBridge)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid Sync connection\n", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto e0;
	}

	pahServerHandle = OSAllocMem(sizeof(IMG_HANDLE) * ui32SyncCount);
	if (pahServerHandle == NULL)
	{
		eError = PVRSRV_ERROR_OUT_OF_MEMORY;
		goto e0;
	}

	/*
		Check that all the sync we've been passed are server syncs
		and that they all are on the same connection.
	*/
	for (i=0;i<ui32SyncCount;i++)
	{
		SYNC_PRIM *psIntSync = IMG_CONTAINER_OF(papsSync[i], SYNC_PRIM, sCommon);

		eError = SyncPrimIsServerSync(papsSync[i], &bServerSync);
		if (PVRSRV_OK != eError) goto e1;
		if (!bServerSync)
		{
			eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
			goto e1;
		}

		if (!papsSync[i] || hBridge != _SyncPrimGetBridgeHandle(papsSync[i]))
		{
			PVR_DPF((PVR_DBG_ERROR, "SyncServerGetStatus: Sync connection is different\n"));
			eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
			goto e1;
		}

		pahServerHandle[i] = psIntSync->u.sServer.hServerSync;
	}

	eError = BridgeServerSyncGetStatus(hBridge,
									   ui32SyncCount,
									   pahServerHandle,
									   pui32UID,
									   pui32FWAddr,
									   pui32CurrentOp,
									   pui32NextOp);
	OSFreeMem(pahServerHandle);

	if (eError != PVRSRV_OK)
	{
		goto e0;
	}
	return PVRSRV_OK;

e1:
	OSFreeMem(pahServerHandle);
e0:
	return eError;
}

#endif

IMG_INTERNAL PVRSRV_ERROR
SyncPrimIsServerSync(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_BOOL *pbServerSync)
{
	PVRSRV_ERROR eError = PVRSRV_OK;
	SYNC_PRIM *psSyncInt;

	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto e0;
	}
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType == SYNC_PRIM_TYPE_LOCAL)
	{
		*pbServerSync = IMG_FALSE;
	}
	else if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
	{
		*pbServerSync = IMG_TRUE;
	}
	else
	{
		/* Either the client has given us a bad pointer or there is an
		 * error in this module
		 */
		PVR_DPF((PVR_DBG_ERROR, "%s: Invalid sync type", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto e0;
	}

e0:
	return eError;
}

IMG_INTERNAL
IMG_HANDLE SyncPrimGetServerHandle(PVRSRV_CLIENT_SYNC_PRIM *psSync)
{
	SYNC_PRIM *psSyncInt;

	if (!psSync)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
		goto e0;
	}
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType == SYNC_PRIM_TYPE_SERVER)
	{
		return psSyncInt->u.sServer.hServerSync;
	}
	else
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid sync type (%d)",
			__FUNCTION__, psSyncInt->eType));
		goto e0;
	}
e0:
	return 0;
}

IMG_INTERNAL
PVRSRV_ERROR SyncPrimServerQueueOp(PVRSRV_CLIENT_SYNC_PRIM_OP *psSyncOp)
{
	SYNC_PRIM *psSyncInt;
	IMG_BOOL bUpdate;
	PVRSRV_ERROR eError;

	if (!psSyncOp)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid input pointer", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_PARAMS;
		goto e0;
	}

	psSyncInt = IMG_CONTAINER_OF(psSyncOp->psSync, SYNC_PRIM, sCommon);
	if (psSyncInt->eType != SYNC_PRIM_TYPE_SERVER)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: invalid sync type (%d)",
			__FUNCTION__, psSyncInt->eType));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto e0;
	}
	if (0 == psSyncOp->ui32Flags)
	{
		PVR_DPF((PVR_DBG_ERROR, "%s: no sync flags", __FUNCTION__));
		eError = PVRSRV_ERROR_INVALID_SYNC_PRIM;
		goto e0;
	}

	if (psSyncOp->ui32Flags & PVRSRV_CLIENT_SYNC_PRIM_OP_UPDATE)
	{
		bUpdate = IMG_TRUE;
	}else
	{
		bUpdate = IMG_FALSE;
	}

	eError = BridgeServerSyncQueueHWOp(psSyncInt->u.sServer.hBridge,
									      psSyncInt->u.sServer.hServerSync,
										  bUpdate,
									      &psSyncOp->ui32FenceValue,
									      &psSyncOp->ui32UpdateValue);
e0:
	return eError;
}

#if defined(PDUMP)
IMG_INTERNAL void SyncPrimPDump(PVRSRV_CLIENT_SYNC_PRIM *psSync)
{
	SYNC_PRIM *psSyncInt;
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM_CONTEXT *psContext;
	PVRSRV_ERROR eError;

	PVR_ASSERT(psSync != NULL);
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
		PVR_ASSERT(IMG_FALSE);
		return;
	}

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	psContext = psSyncBlock->psContext;

	eError = BridgeSyncPrimPDump(psContext->hDevConnection,
								 psSyncBlock->hServerSyncPrimBlock,
								 SyncPrimGetOffset(psSyncInt));

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"%s: failed with error %d",
				__FUNCTION__, eError));
	}
    PVR_ASSERT(eError == PVRSRV_OK);
}

IMG_INTERNAL void SyncPrimPDumpValue(PVRSRV_CLIENT_SYNC_PRIM *psSync, IMG_UINT32 ui32Value)
{
	SYNC_PRIM *psSyncInt;
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM_CONTEXT *psContext;
	PVRSRV_ERROR eError;

	PVR_ASSERT(psSync != NULL);
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDump: Invalid sync type"));
		PVR_ASSERT(IMG_FALSE);
		return;
	}

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	psContext = psSyncBlock->psContext;

	eError = BridgeSyncPrimPDumpValue(psContext->hDevConnection,
								 psSyncBlock->hServerSyncPrimBlock,
								 SyncPrimGetOffset(psSyncInt),
								 ui32Value);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"%s: failed with error %d",
				__FUNCTION__, eError));
	}
    PVR_ASSERT(eError == PVRSRV_OK);
}

IMG_INTERNAL void SyncPrimPDumpPol(PVRSRV_CLIENT_SYNC_PRIM *psSync,
								   IMG_UINT32 ui32Value,
								   IMG_UINT32 ui32Mask,
								   PDUMP_POLL_OPERATOR eOperator,
								   IMG_UINT32 ui32PDumpFlags)
{
	SYNC_PRIM *psSyncInt;
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM_CONTEXT *psContext;
	PVRSRV_ERROR eError;

	PVR_ASSERT(psSync != NULL);
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpPol: Invalid sync type (expected SYNC_PRIM_TYPE_LOCAL)"));
		PVR_ASSERT(IMG_FALSE);
		return;
	}

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	psContext = psSyncBlock->psContext;

	eError = BridgeSyncPrimPDumpPol(psContext->hDevConnection,
									psSyncBlock->hServerSyncPrimBlock,
									SyncPrimGetOffset(psSyncInt),
									ui32Value,
									ui32Mask,
									eOperator,
									ui32PDumpFlags);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"%s: failed with error %d",
				__FUNCTION__, eError));
	}
    PVR_ASSERT(eError == PVRSRV_OK);
}

IMG_INTERNAL void SyncPrimOpPDumpPol(PSYNC_OP_COOKIE psCookie,
									 PDUMP_POLL_OPERATOR eOperator,
									 IMG_UINT32 ui32PDumpFlags)
{
	PVRSRV_ERROR eError;

	PVR_ASSERT(psCookie != NULL);

	eError = BridgeSyncPrimOpPDumpPol(psCookie->hBridge,
									psCookie->hServerCookie,
									eOperator,
									ui32PDumpFlags);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"%s: failed with error %d",
				__FUNCTION__, eError));
	}
	
    PVR_ASSERT(eError == PVRSRV_OK);
}

IMG_INTERNAL void SyncPrimPDumpCBP(PVRSRV_CLIENT_SYNC_PRIM *psSync,
								   IMG_UINT64 uiWriteOffset,
								   IMG_UINT64 uiPacketSize,
								   IMG_UINT64 uiBufferSize)
{
	SYNC_PRIM *psSyncInt;
	SYNC_PRIM_BLOCK *psSyncBlock;
	SYNC_PRIM_CONTEXT *psContext;
	PVRSRV_ERROR eError;

	PVR_ASSERT(psSync != NULL);
	psSyncInt = IMG_CONTAINER_OF(psSync, SYNC_PRIM, sCommon);

	if (psSyncInt->eType != SYNC_PRIM_TYPE_LOCAL)
	{
		PVR_DPF((PVR_DBG_ERROR, "SyncPrimPDumpCBP: Invalid sync type"));
		PVR_ASSERT(IMG_FALSE);
		return;
	}

	psSyncBlock = psSyncInt->u.sLocal.psSyncBlock;
	psContext = psSyncBlock->psContext;

	/* FIXME: uiWriteOffset, uiPacketSize, uiBufferSize were changed to
	 * 64-bit quantities to resolve Windows compiler warnings.
	 * However the bridge is only 32-bit hence compiler warnings
	 * of implicit cast and loss of data.
	 * Added explicit cast and assert to remove warning.
	 */
#if (defined(_WIN32) && !defined(_WIN64)) || (defined(LINUX) && defined(__i386__))
	PVR_ASSERT(uiWriteOffset<IMG_UINT32_MAX);
	PVR_ASSERT(uiPacketSize<IMG_UINT32_MAX);
	PVR_ASSERT(uiBufferSize<IMG_UINT32_MAX);
#endif
	eError = BridgeSyncPrimPDumpCBP(psContext->hDevConnection,
									psSyncBlock->hServerSyncPrimBlock,
									SyncPrimGetOffset(psSyncInt),
									(IMG_UINT32)uiWriteOffset,
									(IMG_UINT32)uiPacketSize,
									(IMG_UINT32)uiBufferSize);

	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
				"%s: failed with error %d",
				__FUNCTION__, eError));
	}
    PVR_ASSERT(eError == PVRSRV_OK);
}

#endif

