#include "services_headers.h"
#include "buffer_manager.h"
-#include "pdump_km.h"
+#include "pvr_pdump.h"
#include "pvr_bridge_km.h"
#include <linux/pagemap.h>
return PVRSRV_OK;
}
+static inline
+void get_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
+{
+ syncinfo->refcount++;
+}
+
+static inline
+void put_syncinfo(struct PVRSRV_KERNEL_SYNC_INFO *syncinfo)
+{
+ struct PVRSRV_DEVICE_NODE *dev = syncinfo->dev_cookie;
+
+ syncinfo->refcount--;
+
+ if (!syncinfo->refcount) {
+ HASH_Remove(dev->sync_table,
+ syncinfo->phys_addr.uiAddr);
+ PVRSRVFreeSyncInfoKM(syncinfo);
+ }
+}
+
+static inline
+enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
+ void *mem_context_handle,
+ struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
+ struct IMG_SYS_PHYADDR *phys_addr)
+{
+ enum PVRSRV_ERROR error;
+ struct PVRSRV_DEVICE_NODE *dev;
+
+ dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;
+
+ *syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
+ HASH_Retrieve(dev->sync_table,
+ phys_addr->uiAddr);
+
+ if (!*syncinfo) {
+ /* Dont' have one so create one */
+ error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
+ syncinfo);
+
+ if (error != PVRSRV_OK)
+ return error;
+
+ /* Setup our extra data */
+ (*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
+ (*syncinfo)->dev_cookie = dev_cookie;
+ (*syncinfo)->refcount = 1;
+
+ if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
+ (u32) *syncinfo)) {
+ PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
+ "Failed to add syncobject to hash table");
+ return PVRSRV_ERROR_GENERIC;
+ }
+ } else
+ get_syncinfo(*syncinfo);
+
+ return PVRSRV_OK;
+}
+
static enum PVRSRV_ERROR FreeDeviceMemCallBack(void *pvParam, u32 ui32Param)
{
enum PVRSRV_ERROR eError = PVRSRV_OK;
hOSWrapMem = psMemInfo->sMemBlk.hOSWrapMem;
if (psMemInfo->psKernelSyncInfo)
- eError = PVRSRVFreeSyncInfoKM(psMemInfo->psKernelSyncInfo);
+ put_syncinfo(psMemInfo->psKernelSyncInfo);
if (psMemInfo->sMemBlk.psIntSysPAddr) {
int page_count;
psDeviceNode = (struct PVRSRV_DEVICE_NODE *)hDevCookie;
PVR_ASSERT(psDeviceNode != NULL);
- if (psDeviceNode == NULL) {
+ if (!psDeviceNode || (!pvLinAddr && !psExtSysPAddr)) {
PVR_DPF(PVR_DBG_ERROR,
"PVRSRVWrapExtMemoryKM: invalid parameter");
return PVRSRV_ERROR_INVALID_PARAMS;
psBMHeap = (struct BM_HEAP *)hDevMemHeap;
hDevMemContext = (void *) psBMHeap->pBMContext;
- eError = PVRSRVAllocSyncInfoKM(hDevCookie,
- hDevMemContext,
- &psMemInfo->psKernelSyncInfo);
+ eError = alloc_or_reuse_syncinfo(hDevCookie,
+ hDevMemContext,
+ &psMemInfo->psKernelSyncInfo,
+ psExtSysPAddr);
if (eError != PVRSRV_OK)
goto ErrorExitPhase4;
return PVRSRV_OK;
ErrorExitPhase4:
- if (psMemInfo) {
- FreeDeviceMem(psMemInfo);
-
- psMemInfo = NULL;
- }
+ FreeDeviceMem(psMemInfo);
+ psMemInfo = NULL;
ErrorExitPhase3:
if (psMemInfo) {
}
ErrorExitPhase2:
- if (psIntSysPAddr)
+ if (hOSWrapMem)
OSReleasePhysPageAddr(hOSWrapMem);
ErrorExitPhase1: