/*************************************************************************/ /*!
@File           ri_server.c
@Title          Resource Information (RI) server implementation
@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
@Description    Resource Information (RI) server functions
@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 <stdarg.h>
#include "img_defs.h"
#include "allocmem.h"
#include "pvr_debug.h"
#include "pvrsrv_error.h"
#include "osfunc.h"

#include "srvkm.h"
#include "lock.h"

/* services/include */
#include "pvr_ricommon.h"

/* services/server/include/ */
#include "ri_server.h"

/* services/include/shared/ */
#include "hash.h"
/* services/shared/include/ */
#include "dllist.h"

#include "pmr.h"

/* include/device.h */
#include "device.h"

#if !defined(RI_UNIT_TEST)
#include "pvrsrv.h"
#endif


#if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO)

#define USE_RI_LOCK		1

/*
 * Initial size use for Hash table. (Used to index the RI list entries).
 */
#define _RI_INITIAL_HASH_TABLE_SIZE	64

/*
 * Values written to the 'valid' field of RI structures when created and
 * cleared prior to being destroyed. The code can then check this value
 * before accessing the provided pointer contents as a valid RI structure.
 */
#define _VALID_RI_LIST_ENTRY	0x66bccb66
#define _VALID_RI_SUBLIST_ENTRY	0x77cddc77
#define _INVALID				0x00000000

/*
 * If this define is set to 1, details of the linked lists (addresses,
 * prev/next ptrs, etc) are also output when function RIDumpList() is called.
 */
#define _DUMP_LINKEDLIST_INFO		0


typedef IMG_UINT64 _RI_BASE_T;


/* No +1 in SIZE macros since sizeof includes \0 byte in size */

#define RI_PROC_BUF_SIZE    16

#define RI_MEMDESC_SUM_FRMT     "PID %d %s MEMDESCs Alloc'd:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K) + "\
                                                  "Imported:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K) = "\
                                                     "Total:0x%010" IMG_UINT64_FMTSPECx " (%" IMG_UINT64_FMTSPEC "K)\n"
#define RI_MEMDESC_SUM_BUF_SIZE (sizeof(RI_MEMDESC_SUM_FRMT)+5+RI_PROC_BUF_SIZE+60)


#define RI_PMR_SUM_FRMT     "PID %d %s PMRs Alloc'd:0x%010" IMG_UINT64_FMTSPECx ", %" IMG_UINT64_FMTSPEC "K  "\
                                        "[Physical: 0x%010" IMG_UINT64_FMTSPECx ", %" IMG_UINT64_FMTSPEC "K]\n"
#define RI_PMR_SUM_BUF_SIZE (sizeof(RI_PMR_SUM_FRMT)+(40))

#define RI_PMR_ENTRY_FRMT      "%%sPID:%%-5d <%%p>\t%%-%ds\t0x%%010" IMG_UINT64_FMTSPECx "\t[0x%%010" IMG_UINT64_FMTSPECx "]\t%%c"
#define RI_PMR_ENTRY_BUF_SIZE  (sizeof(RI_PMR_ENTRY_FRMT)+(3+5+16+PVR_ANNOTATION_MAX_LEN+10+10))
#define RI_PMR_ENTRY_FRMT_SIZE (sizeof(RI_PMR_ENTRY_FRMT))

/* Use %5d rather than %d so the output aligns in server/kernel.log, debugFS sees extra spaces */
#define RI_MEMDESC_ENTRY_PROC_FRMT        "[%5d:%s]"
#define RI_MEMDESC_ENTRY_PROC_BUF_SIZE    (sizeof(RI_MEMDESC_ENTRY_PROC_FRMT)+5+16)

#define RI_SYS_ALLOC_IMPORT_FRMT      "{Import from PID %d}"
#define RI_SYS_ALLOC_IMPORT_FRMT_SIZE (sizeof(RI_SYS_ALLOC_IMPORT_FRMT)+5)
static IMG_CHAR g_szSysAllocImport[RI_SYS_ALLOC_IMPORT_FRMT_SIZE];

#define RI_MEMDESC_ENTRY_IMPORT_FRMT     "{Import from PID %d}"
#define RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_IMPORT_FRMT)+5)

#define RI_MEMDESC_ENTRY_UNPINNED_FRMT     "{Unpinned}"
#define RI_MEMDESC_ENTRY_UNPINNED_BUF_SIZE (sizeof(RI_MEMDESC_ENTRY_UNPINNED_FRMT))

#define RI_MEMDESC_ENTRY_FRMT      "%%sPID:%%-5d 0x%%010" IMG_UINT64_FMTSPECx "\t%%-%ds %%s\t0x%%010" IMG_UINT64_FMTSPECx "\t<%%p> %%s%%s%%s%%c"
#define RI_MEMDESC_ENTRY_BUF_SIZE  (sizeof(RI_MEMDESC_ENTRY_FRMT)+(3+5+10+PVR_ANNOTATION_MAX_LEN+RI_MEMDESC_ENTRY_PROC_BUF_SIZE+16+\
                                               RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE+RI_SYS_ALLOC_IMPORT_FRMT_SIZE+RI_MEMDESC_ENTRY_UNPINNED_BUF_SIZE))
#define RI_MEMDESC_ENTRY_FRMT_SIZE (sizeof(RI_MEMDESC_ENTRY_FRMT))


#define RI_FRMT_SIZE_MAX (MAX(RI_MEMDESC_ENTRY_BUF_SIZE,\
                              MAX(RI_PMR_ENTRY_BUF_SIZE,\
                                  MAX(RI_MEMDESC_SUM_BUF_SIZE,\
                                      RI_PMR_SUM_BUF_SIZE))))




/* Structure used to make linked sublist of memory allocations (MEMDESC) */
struct _RI_SUBLIST_ENTRY_
{
	DLLIST_NODE				sListNode;
	struct _RI_LIST_ENTRY_	*psRI;
	IMG_UINT32 				valid;
	IMG_BOOL				bIsImport;
	IMG_BOOL				bIsSuballoc;
	IMG_PID					pid;
	IMG_CHAR				ai8ProcName[RI_PROC_BUF_SIZE];
	IMG_DEV_VIRTADDR 		sVAddr;
	IMG_UINT64				ui64Offset;
	IMG_UINT64				ui64Size;
	IMG_CHAR				ai8TextB[DEVMEM_ANNOTATION_MAX_LEN+1];
	DLLIST_NODE				sProcListNode;
};

/*
 * Structure used to make linked list of PMRs. Sublists of allocations
 * (MEMDESCs) made from these PMRs are chained off these entries.
 */
struct _RI_LIST_ENTRY_
{
	DLLIST_NODE				sListNode;
	DLLIST_NODE				sSysAllocListNode;
	DLLIST_NODE				sSubListFirst;
	IMG_UINT32				valid;
	PMR						*psPMR;
	IMG_PID					pid;
	IMG_CHAR				ai8ProcName[RI_PROC_BUF_SIZE];
	IMG_UINT16				ui16SubListCount;
	IMG_UINT16				ui16MaxSubListCount;
	IMG_UINT32				ui32RIPMRFlags; /* Flags used to indicate the type of allocation */
	IMG_UINT32				ui32Flags; /* Flags used to indicate if PMR appears in ri debugfs output */
};

typedef struct _RI_LIST_ENTRY_ RI_LIST_ENTRY;
typedef struct _RI_SUBLIST_ENTRY_ RI_SUBLIST_ENTRY;

static IMG_UINT16	g_ui16RICount;
static HASH_TABLE	*g_pRIHashTable;
static IMG_UINT16	g_ui16ProcCount;
static HASH_TABLE	*g_pProcHashTable;

static POS_LOCK		g_hRILock;

/* Linked list of PMR allocations made against the PVR_SYS_ALLOC_PID and lock
 * to prevent concurrent access to it.
 */
static POS_LOCK		g_hSysAllocPidListLock;
static DLLIST_NODE	g_sSysAllocPidListHead;

/*
 * Flag used to indicate if RILock should be destroyed when final PMR entry is
 * deleted, i.e. if RIDeInitKM() has already been called before that point but
 * the handle manager has deferred deletion of RI entries.
 */
static IMG_BOOL 	bRIDeInitDeferred = IMG_FALSE;

/*
 * Used as head of linked-list of PMR RI entries - this is useful when we wish
 * to iterate all PMR list entries (when we don't have a PMR ref)
 */
static DLLIST_NODE	sListFirst;

/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */
static void _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry, IMG_BOOL bDebugFs, IMG_UINT16 ui16MaxStrLen, IMG_CHAR *pszEntryString);
/* Function used to produce string containing info for PMR RI entries (used for both debugfs and kernel log output) */
static void _GeneratePMREntryString(RI_LIST_ENTRY *psRIEntry, IMG_BOOL bDebugFs, IMG_UINT16 ui16MaxStrLen, IMG_CHAR *pszEntryString);

static PVRSRV_ERROR _DumpAllEntries (uintptr_t k, uintptr_t v);
static PVRSRV_ERROR _DeleteAllEntries (uintptr_t k, uintptr_t v);
static PVRSRV_ERROR _DeleteAllProcEntries (uintptr_t k, uintptr_t v);
static PVRSRV_ERROR _DumpList(PMR *psPMR, IMG_PID pid);
#define _RIOutput(x) PVR_LOG(x)

#define RI_FLAG_PARSED_BY_DEBUGFS			0x1
#define RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS	0x2
#define RI_FLAG_SYSALLOC_PMR				0x4

static IMG_UINT32
_ProcHashFunc(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen);

static IMG_UINT32
_ProcHashFunc(size_t uKeySize, void *pKey, IMG_UINT32 uHashTabLen)
{
	IMG_UINT32 *p = (IMG_UINT32 *)pKey;
	IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32);
	IMG_UINT32 ui;
	IMG_UINT32 uHashKey = 0;

	PVR_UNREFERENCED_PARAMETER(uHashTabLen);

	for (ui = 0; ui < uKeyLen; ui++)
	{
		IMG_UINT32 uHashPart = *p++;

		uHashPart += (uHashPart << 12);
		uHashPart ^= (uHashPart >> 22);
		uHashPart += (uHashPart << 4);
		uHashPart ^= (uHashPart >> 9);
		uHashPart += (uHashPart << 10);
		uHashPart ^= (uHashPart >> 2);
		uHashPart += (uHashPart << 7);
		uHashPart ^= (uHashPart >> 12);

		uHashKey += uHashPart;
	}

	return uHashKey;
}

static IMG_BOOL
_ProcHashComp(size_t uKeySize, void *pKey1, void *pKey2);

static IMG_BOOL
_ProcHashComp(size_t uKeySize, void *pKey1, void *pKey2)
{
	IMG_UINT32 *p1 = (IMG_UINT32 *)pKey1;
	IMG_UINT32 *p2 = (IMG_UINT32 *)pKey2;
	IMG_UINT32 uKeyLen = uKeySize / sizeof(IMG_UINT32);
	IMG_UINT32 ui;

	for (ui = 0; ui < uKeyLen; ui++)
	{
		if (*p1++ != *p2++)
			return IMG_FALSE;
	}

	return IMG_TRUE;
}

static void _RILock(void)
{
#if (USE_RI_LOCK == 1)
	OSLockAcquire(g_hRILock);
#endif
}

static void _RIUnlock(void)
{
#if (USE_RI_LOCK == 1)
	OSLockRelease(g_hRILock);
#endif
}

/* This value maintains a count of the number of PMRs attributed to the
 * PVR_SYS_ALLOC_PID. Access to this value is protected by g_hRILock, so it
 * does not need to be an ATOMIC_T.
 */
static IMG_UINT32 g_ui32SysAllocPMRCount;


PVRSRV_ERROR RIInitKM(void)
{
	IMG_INT iCharsWritten;
	PVRSRV_ERROR eError;

	bRIDeInitDeferred = IMG_FALSE;

	iCharsWritten = OSSNPrintf(g_szSysAllocImport,
	            RI_SYS_ALLOC_IMPORT_FRMT_SIZE,
	            RI_SYS_ALLOC_IMPORT_FRMT,
	            PVR_SYS_ALLOC_PID);
	PVR_LOG_IF_FALSE((iCharsWritten>0 && iCharsWritten<(IMG_INT32)RI_SYS_ALLOC_IMPORT_FRMT_SIZE), \
			"OSSNPrintf failed to initialise g_szSysAllocImport");

	eError = OSLockCreate(&g_hSysAllocPidListLock);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
		         "%s: OSLockCreate (g_hSysAllocPidListLock) failed (returned %d)",
		         __func__,
		         eError));
	}
	dllist_init(&(g_sSysAllocPidListHead));
#if (USE_RI_LOCK == 1)
	eError = OSLockCreate(&g_hRILock);
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR,
		         "%s: OSLockCreate (g_hRILock) failed (returned %d)",
		         __func__,
		         eError));
	}
#endif
	return eError;
}
void RIDeInitKM(void)
{
#if (USE_RI_LOCK == 1)
	if (g_ui16RICount > 0)
	{
		PVR_DPF((PVR_DBG_WARNING,
		         "%s: called with %d entries remaining - deferring OSLockDestroy()",
		         __func__,
		         g_ui16RICount));
		bRIDeInitDeferred = IMG_TRUE;
	}
	else
	{
		OSLockDestroy(g_hRILock);
		OSLockDestroy(g_hSysAllocPidListLock);
	}
#endif
}

/*!
*******************************************************************************

 @Function	RILockAcquireKM

 @Description
            Acquires the RI Lock (which protects the integrity of the RI
            linked lists). Caller will be suspended until lock is acquired.

 @Return	None

******************************************************************************/
void RILockAcquireKM(void)
{
	_RILock();
}

/*!
*******************************************************************************

 @Function	RILockReleaseKM

 @Description
            Releases the RI Lock (which protects the integrity of the RI
            linked lists).

 @Return	None

******************************************************************************/
void RILockReleaseKM(void)
{
	_RIUnlock();
}

/*!
*******************************************************************************

 @Function	RIWritePMREntryWithOwnerKM

 @Description
            Writes a new Resource Information list entry.
            The new entry will be inserted at the head of the list of
            PMR RI entries and assigned the values provided.

 @input     psPMR - Reference (handle) to the PMR to which this reference relates

 @input     ui32Owner - PID of the process which owns the allocation. This
                        may not be the current process (e.g. a request to
                        grow a buffer may happen in the context of a kernel
                        thread, or we may import further resource for a
                        suballocation made from the FW heap which can then
                        also be utilized by other processes)

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIWritePMREntryWithOwnerKM(PMR *psPMR,
                                        IMG_PID ui32Owner)
{
	PMR *pPMRHashKey = psPMR;
	RI_LIST_ENTRY *psRIEntry;
	uintptr_t hashData;

	/* if Hash table has not been created, create it now */
	if (!g_pRIHashTable)
	{
		g_pRIHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(PMR*), HASH_Func_Default, HASH_Key_Comp_Default);
		g_pProcHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(IMG_PID), _ProcHashFunc, _ProcHashComp);
	}
	if (!g_pRIHashTable || !g_pProcHashTable)
	{
		/* Error - no memory to allocate for Hash table(s) */
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	if (!psPMR)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* Acquire RI Lock */
	_RILock();

	/* Look-up psPMR in Hash Table */
	hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey);
	psRIEntry = (RI_LIST_ENTRY *)hashData;
	if (!psRIEntry)
	{
		/*
		 * If failed to find a matching existing entry, create a new one
		 */
		psRIEntry = (RI_LIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_LIST_ENTRY));
		if (!psRIEntry)
		{
			/* Release RI Lock */
			_RIUnlock();
			/* Error - no memory to allocate for new RI entry */
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}
		else
		{
			IMG_UINT32 ui32PMRFlags = PMR_Flags(psPMR);
			PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)PMR_DeviceNode(psPMR);

			/*
			 * Add new RI Entry
			 */
			if (g_ui16RICount == 0)
			{
				/* Initialise PMR entry linked-list head */
				dllist_init(&sListFirst);
			}
			g_ui16RICount++;

			dllist_init (&(psRIEntry->sSysAllocListNode));
			dllist_init (&(psRIEntry->sSubListFirst));
			psRIEntry->ui16SubListCount = 0;
			psRIEntry->ui16MaxSubListCount = 0;
			psRIEntry->valid = _VALID_RI_LIST_ENTRY;

			/* Check if this PMR should be accounted for under the
			 * PVR_SYS_ALLOC_PID debugFS entry. This should happen if
			 * we are in the driver init phase, the flags indicate
			 * this is a FW local allocation (made from FW heap)
			 * or the owner PID is PVR_SYS_ALLOC_PID.
			 * Also record host dev node allocs on the system PID.
			 */
			if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT ||
				PVRSRV_CHECK_FW_LOCAL(ui32PMRFlags) ||
				ui32Owner == PVR_SYS_ALLOC_PID ||
				psDeviceNode == PVRSRVGetPVRSRVData()->psHostMemDeviceNode)
			{
				psRIEntry->ui32RIPMRFlags = RI_FLAG_SYSALLOC_PMR;
				OSSNPrintf(psRIEntry->ai8ProcName,
						RI_PROC_BUF_SIZE,
						"SysProc");
				psRIEntry->pid = PVR_SYS_ALLOC_PID;
				OSLockAcquire(g_hSysAllocPidListLock);
				/* Add this psRIEntry to the list of entries for PVR_SYS_ALLOC_PID */
				dllist_add_to_tail(&g_sSysAllocPidListHead,(PDLLIST_NODE)&(psRIEntry->sSysAllocListNode));
				OSLockRelease(g_hSysAllocPidListLock);
				g_ui32SysAllocPMRCount++;
			}
			else
			{
				psRIEntry->ui32RIPMRFlags = 0;
				psRIEntry->pid = ui32Owner;
			}

			OSSNPrintf(psRIEntry->ai8ProcName,
					RI_PROC_BUF_SIZE,
					"%s",
					OSGetCurrentClientProcessNameKM());
			/* Add PMR entry to linked-list of all PMR entries */
			dllist_init (&(psRIEntry->sListNode));
			dllist_add_to_tail(&sListFirst,(PDLLIST_NODE)&(psRIEntry->sListNode));
		}

		psRIEntry->psPMR = psPMR;
		psRIEntry->ui32Flags = 0;

		/* Create index entry in Hash Table */
		HASH_Insert_Extended (g_pRIHashTable, (void *)&pPMRHashKey, (uintptr_t)psRIEntry);

		/* Store phRIHandle in PMR structure, so it can delete the associated RI entry when it destroys the PMR */
		PMRStoreRIHandle(psPMR, psRIEntry);
	}
	/* Release RI Lock */
	_RIUnlock();

	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIWritePMREntryKM

 @Description
            Writes a new Resource Information list entry.
            The new entry will be inserted at the head of the list of
            PMR RI entries and assigned the values provided.

 @input     psPMR - Reference (handle) to the PMR to which this reference relates

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIWritePMREntryKM(PMR *psPMR)
{
	return RIWritePMREntryWithOwnerKM(psPMR,
	                                  OSGetCurrentClientProcessIDKM());
}

/*!
*******************************************************************************

 @Function	RIWriteMEMDESCEntryKM

 @Description
            Writes a new Resource Information sublist entry.
            The new entry will be inserted at the head of the sublist of
            the indicated PMR list entry, and assigned the values provided.

 @input     psPMR - Reference (handle) to the PMR to which this MEMDESC RI entry relates
 @input     ui32TextBSize - Length of string provided in psz8TextB parameter
 @input     psz8TextB - String describing this secondary reference (may be null)
 @input     ui64Offset - Offset from the start of the PMR at which this allocation begins
 @input     ui64Size - Size of this allocation
 @input     bIsImport - Flag indicating if this is an allocation or an import
 @input     bIsSuballoc - Flag indicating if this is a sub-allocation
 @output    phRIHandle - Handle to the created RI entry

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIWriteMEMDESCEntryKM(PMR *psPMR,
					   	   	   	   IMG_UINT32 ui32TextBSize,
					   	   	   	   const IMG_CHAR *psz8TextB,
					   	   	   	   IMG_UINT64 ui64Offset,
					   	   	   	   IMG_UINT64 ui64Size,
					   	   	   	   IMG_BOOL bIsImport,
					               IMG_BOOL bIsSuballoc,
					   	   	   	   RI_HANDLE *phRIHandle)
{
	RI_SUBLIST_ENTRY *psRISubEntry;
	RI_LIST_ENTRY *psRIEntry;
	PMR *pPMRHashKey = psPMR;
	uintptr_t hashData;
	IMG_PID	pid;

	/* Check Hash tables have been created (meaning at least one PMR has been defined) */
	if (!g_pRIHashTable || !g_pProcHashTable)
	{
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (!psPMR || !phRIHandle)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* Acquire RI Lock */
	_RILock();

	*phRIHandle = NULL;

	/* Look-up psPMR in Hash Table */
	hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey);
	psRIEntry = (RI_LIST_ENTRY *)hashData;
	if (!psRIEntry)
	{
		/* Release RI Lock */
		_RIUnlock();
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psRISubEntry = (RI_SUBLIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_SUBLIST_ENTRY));
	if (!psRISubEntry)
	{
		/* Release RI Lock */
		_RIUnlock();
		/* Error - no memory to allocate for new RI sublist entry */
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}
	else
	{
		/*
		 * Insert new entry in sublist
		 */
		PDLLIST_NODE currentNode = dllist_get_next_node(&(psRIEntry->sSubListFirst));

		/*
		 * Insert new entry before currentNode
		 */
		if (!currentNode)
		{
			currentNode = &(psRIEntry->sSubListFirst);
		}
		dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sListNode));

		psRISubEntry->psRI = psRIEntry;

		/* Increment number of entries in sublist */
		psRIEntry->ui16SubListCount++;
		if (psRIEntry->ui16SubListCount > psRIEntry->ui16MaxSubListCount)
		{
			psRIEntry->ui16MaxSubListCount = psRIEntry->ui16SubListCount;
		}
		psRISubEntry->valid = _VALID_RI_SUBLIST_ENTRY;
	}

	/* If allocation is made during device or driver initialisation,
	 * track the MEMDESC entry under PVR_SYS_ALLOC_PID, otherwise use
	 * the current PID.
	 * Record host dev node allocations on the system PID.
	 */
	{
		PVRSRV_DEVICE_NODE *psDeviceNode = (PVRSRV_DEVICE_NODE *)PMR_DeviceNode(psRISubEntry->psRI->psPMR);

		if (psDeviceNode->eDevState == PVRSRV_DEVICE_STATE_INIT ||
			psDeviceNode == PVRSRVGetPVRSRVData()->psHostMemDeviceNode)
		{
			psRISubEntry->pid = psRISubEntry->psRI->pid;
		}
		else
		{
			psRISubEntry->pid = OSGetCurrentClientProcessIDKM();
		}
	}

	if (ui32TextBSize > sizeof(psRISubEntry->ai8TextB)-1)
	{
		PVR_DPF((PVR_DBG_WARNING,
				 "%s: TextBSize too long (%u). Text will be truncated "
				 "to %zu characters", __func__,
				 ui32TextBSize, sizeof(psRISubEntry->ai8TextB)-1));
	}

	/* copy ai8TextB field data */
	OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8TextB, sizeof(psRISubEntry->ai8TextB), "%s", psz8TextB);

	psRISubEntry->ui64Offset = ui64Offset;
	psRISubEntry->ui64Size = ui64Size;
	psRISubEntry->bIsImport = bIsImport;
	psRISubEntry->bIsSuballoc = bIsSuballoc;
	OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8ProcName, RI_PROC_BUF_SIZE, "%s", OSGetCurrentClientProcessNameKM());
	dllist_init (&(psRISubEntry->sProcListNode));

	/*
	 *	Now insert this MEMDESC into the proc list
	 */
	/* look-up pid in Hash Table */
	pid = psRISubEntry->pid;
	hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid);
	if (!hashData)
	{
		/*
		 * No allocations for this pid yet
		 */
		HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)&(psRISubEntry->sProcListNode));
		/* Increment number of entries in proc hash table */
		g_ui16ProcCount++;
	}
	else
	{
		/*
		 * Insert allocation into pid allocations linked list
		 */
		PDLLIST_NODE currentNode = (PDLLIST_NODE)hashData;

		/*
		 * Insert new entry
		 */
		dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sProcListNode));
	}
	*phRIHandle = (RI_HANDLE)psRISubEntry;
	/* Release RI Lock */
	_RIUnlock();

	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIWriteProcListEntryKM

 @Description
            Write a new entry in the process list directly. We have to do this
            because there might be no, multiple or changing PMR handles.

            In the common case we have a PMR that will be added to the PMR list
            and one or several MemDescs that are associated to it in a sub-list.
            Additionally these MemDescs will be inserted in the per-process list.

            There might be special descriptors from e.g. new user APIs that
            are associated with no or multiple PMRs and not just one.
            These can be now added to the per-process list (as RI_SUBLIST_ENTRY)
            directly with this function and won't be listed in the PMR list (RIEntry)
            because there might be no PMR.

            To remove entries from the per-process list, just use
            RIDeleteMEMDESCEntryKM().

 @input     psz8TextB - String describing this secondary reference (may be null)
 @input     ui64Size - Size of this allocation
 @input     ui64DevVAddr - Virtual address of this entry
 @output    phRIHandle - Handle to the created RI entry

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIWriteProcListEntryKM(IMG_UINT32 ui32TextBSize,
                                    const IMG_CHAR *psz8TextB,
                                    IMG_UINT64 ui64Size,
                                    IMG_UINT64 ui64DevVAddr,
                                    RI_HANDLE *phRIHandle)
{
	uintptr_t hashData = 0;
	IMG_PID		pid;
	RI_SUBLIST_ENTRY *psRISubEntry = NULL;

	if (!g_pRIHashTable)
	{
		g_pRIHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(PMR*), HASH_Func_Default, HASH_Key_Comp_Default);
		g_pProcHashTable = HASH_Create_Extended(_RI_INITIAL_HASH_TABLE_SIZE, sizeof(IMG_PID), _ProcHashFunc, _ProcHashComp);

		if (!g_pRIHashTable || !g_pProcHashTable)
		{
			/* Error - no memory to allocate for Hash table(s) */
			return PVRSRV_ERROR_OUT_OF_MEMORY;
		}
	}

	/* Acquire RI Lock */
	_RILock();

	*phRIHandle = NULL;

	psRISubEntry = (RI_SUBLIST_ENTRY *)OSAllocZMemNoStats(sizeof(RI_SUBLIST_ENTRY));
	if (!psRISubEntry)
	{
		/* Release RI Lock */
		_RIUnlock();
		/* Error - no memory to allocate for new RI sublist entry */
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	psRISubEntry->valid = _VALID_RI_SUBLIST_ENTRY;

	psRISubEntry->pid = OSGetCurrentClientProcessIDKM();

	if (ui32TextBSize > sizeof(psRISubEntry->ai8TextB)-1)
	{
		PVR_DPF((PVR_DBG_WARNING,
		         "%s: TextBSize too long (%u). Text will be truncated "
		         "to %zu characters", __func__,
		         ui32TextBSize, sizeof(psRISubEntry->ai8TextB)-1));
	}

	/* copy ai8TextB field data */
	OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8TextB, sizeof(psRISubEntry->ai8TextB), "%s", psz8TextB);

	psRISubEntry->ui64Offset = 0;
	psRISubEntry->ui64Size = ui64Size;
	psRISubEntry->sVAddr.uiAddr = ui64DevVAddr;
	psRISubEntry->bIsImport = IMG_FALSE;
	psRISubEntry->bIsSuballoc = IMG_FALSE;
	OSSNPrintf((IMG_CHAR *)psRISubEntry->ai8ProcName, RI_PROC_BUF_SIZE, "%s", OSGetCurrentClientProcessNameKM());
	dllist_init (&(psRISubEntry->sProcListNode));

	/*
	 *	Now insert this MEMDESC into the proc list
	 */
	/* look-up pid in Hash Table */
	pid = psRISubEntry->pid;
	hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid);
	if (!hashData)
	{
		/*
		 * No allocations for this pid yet
		 */
		HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)&(psRISubEntry->sProcListNode));
		/* Increment number of entries in proc hash table */
		g_ui16ProcCount++;
	}
	else
	{
		/*
		 * Insert allocation into pid allocations linked list
		 */
		PDLLIST_NODE currentNode = (PDLLIST_NODE)hashData;

		/*
		 * Insert new entry
		 */
		dllist_add_to_tail(currentNode, (PDLLIST_NODE)&(psRISubEntry->sProcListNode));
	}
	*phRIHandle = (RI_HANDLE)psRISubEntry;
	/* Release RI Lock */
	_RIUnlock();

	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIUpdateMEMDESCAddrKM

 @Description
            Update a Resource Information entry.

 @input     hRIHandle - Handle of object whose reference info is to be updated
 @input     sVAddr - New address for the RI entry

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIUpdateMEMDESCAddrKM(RI_HANDLE hRIHandle,
								   IMG_DEV_VIRTADDR sVAddr)
{
	RI_SUBLIST_ENTRY *psRISubEntry;

	if (!hRIHandle)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}
	psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle;
	if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
	{
		/* Pointer does not point to valid structure */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* Acquire RI lock*/
	_RILock();

	psRISubEntry->sVAddr.uiAddr = sVAddr.uiAddr;

	/* Release RI lock */
	_RIUnlock();

	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIDeletePMREntryKM

 @Description
            Delete a Resource Information entry.

 @input     hRIHandle - Handle of object whose reference info is to be deleted

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDeletePMREntryKM(RI_HANDLE hRIHandle)
{
	RI_LIST_ENTRY *psRIEntry;
	PMR			*pPMRHashKey;
	PVRSRV_ERROR eResult = PVRSRV_OK;

	if (!hRIHandle)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}
	psRIEntry = (RI_LIST_ENTRY *)hRIHandle;

	if (psRIEntry->valid != _VALID_RI_LIST_ENTRY)
	{
		/* Pointer does not point to valid structure */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (psRIEntry->ui16SubListCount == 0)
	{
		/* Acquire RI lock*/
		_RILock();

		/* Remove the HASH table index entry */
		pPMRHashKey = psRIEntry->psPMR;
		HASH_Remove_Extended(g_pRIHashTable, (void *)&pPMRHashKey);

		psRIEntry->valid = _INVALID;

		/* Remove PMR entry from linked-list of PMR entries */
		dllist_remove_node((PDLLIST_NODE)&(psRIEntry->sListNode));

		if (psRIEntry->ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR)
		{
			dllist_remove_node((PDLLIST_NODE)&(psRIEntry->sSysAllocListNode));
			g_ui32SysAllocPMRCount--;
		}

		/* Now, free the memory used to store the RI entry */
		OSFreeMemNoStats(psRIEntry);
		psRIEntry = NULL;

		/*
		 * Decrement number of RI entries - if this is now zero,
		 * we can delete the RI hash table
		 */
		if (--g_ui16RICount == 0)
		{
			HASH_Delete(g_pRIHashTable);
			g_pRIHashTable = NULL;

			_RIUnlock();

			/* If deInit has been deferred, we can now destroy the RI Lock */
			if (bRIDeInitDeferred)
			{
				OSLockDestroy(g_hRILock);
			}
		}
		else
		{
			/* Release RI lock*/
			_RIUnlock();
		}
		/*
		 * Make the handle NULL once PMR RI entry is deleted
		 */
		hRIHandle = NULL;
	}
	else
	{
		eResult = PVRSRV_ERROR_DEVICEMEM_ALLOCATIONS_REMAIN_IN_HEAP;
	}

	return eResult;
}

/*!
*******************************************************************************

 @Function	RIDeleteMEMDESCEntryKM

 @Description
            Delete a Resource Information entry.
            Entry can be from RIEntry list or ProcList.

 @input     hRIHandle - Handle of object whose reference info is to be deleted

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDeleteMEMDESCEntryKM(RI_HANDLE hRIHandle)
{
	RI_LIST_ENTRY *psRIEntry = NULL;
	RI_SUBLIST_ENTRY *psRISubEntry;
	uintptr_t hashData;
	IMG_PID pid;

	if (!hRIHandle)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	psRISubEntry = (RI_SUBLIST_ENTRY *)hRIHandle;
	if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
	{
		/* Pointer does not point to valid structure */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	/* Acquire RI lock*/
	_RILock();

	/* For entries which do have a parent PMR remove the node from the sublist */
	if (psRISubEntry->psRI)
	{
		psRIEntry = (RI_LIST_ENTRY *)psRISubEntry->psRI;

		/* Now, remove entry from the sublist */
		dllist_remove_node(&(psRISubEntry->sListNode));
	}

	psRISubEntry->valid = _INVALID;

	/* Remove the entry from the proc allocations linked list */
	pid = psRISubEntry->pid;
	/* If this is the only allocation for this pid, just remove it from the hash table */
	if (dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL)
	{
		HASH_Remove_Extended(g_pProcHashTable, (void *)&pid);
		/* Decrement number of entries in proc hash table, and delete the hash table if there are now none */
		if (--g_ui16ProcCount == 0)
		{
			HASH_Delete(g_pProcHashTable);
			g_pProcHashTable = NULL;
		}
	}
	else
	{
		hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&pid);
		if ((PDLLIST_NODE)hashData == &(psRISubEntry->sProcListNode))
		{
			HASH_Remove_Extended(g_pProcHashTable, (void *)&pid);
			HASH_Insert_Extended (g_pProcHashTable, (void *)&pid, (uintptr_t)dllist_get_next_node(&(psRISubEntry->sProcListNode)));
		}
	}
	dllist_remove_node(&(psRISubEntry->sProcListNode));

	/* Now, free the memory used to store the sublist entry */
	OSFreeMemNoStats(psRISubEntry);
	psRISubEntry = NULL;

	/*
	 * Decrement number of entries in sublist if this MemDesc had a parent entry.
	 */
	if (psRIEntry)
	{
		psRIEntry->ui16SubListCount--;
	}

	/* Release RI lock*/
	_RIUnlock();

	/*
	 * Make the handle NULL once MEMDESC RI entry is deleted
	 */
	hRIHandle = NULL;

	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIDeleteListKM

 @Description
            Delete all Resource Information entries and free associated
            memory.

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDeleteListKM(void)
{
	PVRSRV_ERROR eResult = PVRSRV_OK;

	_RILock();

	if (g_pRIHashTable)
	{
		eResult = HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DeleteAllEntries);
		if (eResult == PVRSRV_ERROR_RESOURCE_UNAVAILABLE)
		{
			/*
			 * PVRSRV_ERROR_RESOURCE_UNAVAILABLE is used to stop the Hash iterator when
			 * the hash table gets deleted as a result of deleting the final PMR entry,
			 * so this is not a real error condition...
			 */
			eResult = PVRSRV_OK;
		}
	}

	/* After the run through the RIHashTable that holds the PMR entries there might be
	 * still entries left in the per-process hash table because they were added with
	 * RIWriteProcListEntryKM() and have no PMR parent associated.
	 */
	if (g_pProcHashTable)
	{
		eResult = HASH_Iterate(g_pProcHashTable, (HASH_pfnCallback) _DeleteAllProcEntries);
		if (eResult == PVRSRV_ERROR_RESOURCE_UNAVAILABLE)
		{
			/*
			 * PVRSRV_ERROR_RESOURCE_UNAVAILABLE is used to stop the Hash iterator when
			 * the hash table gets deleted as a result of deleting the final PMR entry,
			 * so this is not a real error condition...
			 */
			eResult = PVRSRV_OK;
		}
	}

	_RIUnlock();

	return eResult;
}

/*!
*******************************************************************************

 @Function	RIDumpListKM

 @Description
            Dumps out the contents of the RI List entry for the
            specified PMR, and all MEMDESC allocation entries
            in the associated sub linked list.
            At present, output is directed to Kernel log
            via PVR_DPF.

 @input     psPMR - PMR for which RI entry details are to be output

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDumpListKM(PMR *psPMR)
{
	PVRSRV_ERROR eError;

	/* Acquire RI lock*/
	_RILock();

	eError = _DumpList(psPMR,0);

	/* Release RI lock*/
	_RIUnlock();

	return eError;
}

/*!
*******************************************************************************

 @Function	RIGetListEntryKM

 @Description
            Returns pointer to a formatted string with details of the specified
            list entry. If no entry exists (e.g. it may have been deleted
            since the previous call), NULL is returned.

 @input     pid - pid for which RI entry details are to be output
 @input     ppHandle - handle to the entry, if NULL, the first entry will be
                     returned.
 @output    pszEntryString - string to be output for the entry
 @output    hEntry - hEntry will be returned pointing to the next entry
                     (or NULL if there is no next entry)

 @Return	PVRSRV_ERROR

******************************************************************************/
IMG_BOOL RIGetListEntryKM(IMG_PID pid,
						  IMG_HANDLE **ppHandle,
						  IMG_CHAR **ppszEntryString)
{
	RI_SUBLIST_ENTRY  *psRISubEntry = NULL;
	RI_LIST_ENTRY  *psRIEntry = NULL;
	uintptr_t     hashData = 0;
	IMG_PID       hashKey  = pid;

	static IMG_CHAR acStringBuffer[RI_FRMT_SIZE_MAX];

	static IMG_UINT64 ui64TotalMemdescAlloc;
	static IMG_UINT64 ui64TotalImport;
	static IMG_UINT64 ui64TotalPMRAlloc;
	static IMG_UINT64 ui64TotalPMRBacked;
	static enum {
		RI_GET_STATE_MEMDESCS_LIST_START,
		RI_GET_STATE_MEMDESCS_SUMMARY,
		RI_GET_STATE_PMR_LIST,
		RI_GET_STATE_PMR_SUMMARY,
		RI_GET_STATE_END,
		RI_GET_STATE_LAST
	} g_bNextGetState = RI_GET_STATE_MEMDESCS_LIST_START;

	static DLLIST_NODE *psNode;
	static DLLIST_NODE *psSysAllocNode;
	static IMG_CHAR szProcName[RI_PROC_BUF_SIZE];
	static IMG_UINT32 ui32ProcessedSysAllocPMRCount;

	acStringBuffer[0] = '\0';

	switch (g_bNextGetState)
	{
	case RI_GET_STATE_MEMDESCS_LIST_START:
		/* look-up pid in Hash Table, to obtain first entry for pid */
		hashData = HASH_Retrieve_Extended(g_pProcHashTable, (void *)&hashKey);
		if (hashData)
		{
			if (*ppHandle)
			{
				psRISubEntry = (RI_SUBLIST_ENTRY *)*ppHandle;
				if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
				{
					psRISubEntry = NULL;
				}
			}
			else
			{
				psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode);
				if (psRISubEntry->valid != _VALID_RI_SUBLIST_ENTRY)
				{
					psRISubEntry = NULL;
				}
			}
		}

		if (psRISubEntry)
		{
			PDLLIST_NODE psNextProcListNode = dllist_get_next_node(&psRISubEntry->sProcListNode);

			if (psRISubEntry->bIsImport)
			{
				ui64TotalImport += psRISubEntry->ui64Size;
			}
			else
			{
				ui64TotalMemdescAlloc += psRISubEntry->ui64Size;
			}

			_GenerateMEMDESCEntryString(psRISubEntry,
										IMG_TRUE,
										RI_MEMDESC_ENTRY_BUF_SIZE,
										acStringBuffer);

			/* If this MEMDESC has a parent PMR and if not an imported PMR, flag 'parent' PMR has having been listed in MEMDESCs */
			if (psRISubEntry->psRI && !psRISubEntry->bIsImport && !(psRISubEntry->psRI->ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR))
			{
				psRISubEntry->psRI->ui32RIPMRFlags |= RI_FLAG_PARSED_BY_DEBUGFS;
			}

			if (szProcName[0] == '\0')
			{
				OSStringCopy(szProcName, (pid == PVR_SYS_ALLOC_PID) ?
						PVRSRV_MODNAME : psRISubEntry->ai8ProcName);
			}


			*ppszEntryString = acStringBuffer;
			*ppHandle        = (IMG_HANDLE)IMG_CONTAINER_OF(psNextProcListNode, RI_SUBLIST_ENTRY, sProcListNode);

			if (psNextProcListNode == NULL ||
				psNextProcListNode == (PDLLIST_NODE)hashData)
			{
				g_bNextGetState = RI_GET_STATE_MEMDESCS_SUMMARY;
			}
			/* else continue to list MEMDESCs */
		}
		else
		{
			if (ui64TotalMemdescAlloc == 0)
			{
				acStringBuffer[0] = '\0';
				*ppszEntryString =acStringBuffer;
				g_bNextGetState = RI_GET_STATE_MEMDESCS_SUMMARY;
			}
			/* else continue to list MEMDESCs */
		}
		break;

	case RI_GET_STATE_MEMDESCS_SUMMARY:
		OSSNPrintf(acStringBuffer,
		           RI_MEMDESC_SUM_BUF_SIZE,
		           RI_MEMDESC_SUM_FRMT,
		           pid,
		           szProcName,
		           ui64TotalMemdescAlloc,
		           ui64TotalMemdescAlloc >> 10,
		           ui64TotalImport,
		           ui64TotalImport >> 10,
		           (ui64TotalMemdescAlloc + ui64TotalImport),
		           (ui64TotalMemdescAlloc + ui64TotalImport) >> 10);

		*ppszEntryString = acStringBuffer;
		ui64TotalMemdescAlloc = 0;
		ui64TotalImport = 0;
		szProcName[0] = '\0';

		g_bNextGetState = RI_GET_STATE_PMR_LIST;
		break;

	case RI_GET_STATE_PMR_LIST:
		if (pid == PVR_SYS_ALLOC_PID)
		{
			OSLockAcquire(g_hSysAllocPidListLock);
			acStringBuffer[0] = '\0';
			if (!psSysAllocNode)
			{
				psSysAllocNode = &g_sSysAllocPidListHead;
				ui32ProcessedSysAllocPMRCount = 0;
			}
			psSysAllocNode = dllist_get_next_node(psSysAllocNode);

			if (szProcName[0] == '\0')
			{
				OSStringCopy(szProcName, PVRSRV_MODNAME);
			}
			if (psSysAllocNode != NULL && psSysAllocNode != &g_sSysAllocPidListHead)
			{
				IMG_DEVMEM_SIZE_T uiPMRPhysicalBacking, uiPMRLogicalSize = 0;

				psRIEntry = IMG_CONTAINER_OF((PDLLIST_NODE)psSysAllocNode, RI_LIST_ENTRY, sSysAllocListNode);
				_GeneratePMREntryString(psRIEntry,
										IMG_TRUE,
										RI_PMR_ENTRY_BUF_SIZE,
										acStringBuffer);
				PMR_LogicalSize(psRIEntry->psPMR,
								&uiPMRLogicalSize);
				ui64TotalPMRAlloc += uiPMRLogicalSize;
				PMR_PhysicalSize(psRIEntry->psPMR, &uiPMRPhysicalBacking);
				ui64TotalPMRBacked += uiPMRPhysicalBacking;

				ui32ProcessedSysAllocPMRCount++;
				if (ui32ProcessedSysAllocPMRCount > g_ui32SysAllocPMRCount+1)
				{
					g_bNextGetState = RI_GET_STATE_PMR_SUMMARY;
				}
				/* else continue to list PMRs */
			}
			else
			{
				g_bNextGetState = RI_GET_STATE_PMR_SUMMARY;
			}
			*ppszEntryString = (IMG_CHAR *)acStringBuffer;
			OSLockRelease(g_hSysAllocPidListLock);
		}
		else
		{
			IMG_BOOL bPMRToDisplay = IMG_FALSE;

			/* Iterate through the 'touched' PMRs and display details */
			if (!psNode)
			{
				psNode = dllist_get_next_node(&sListFirst);
			}
			else
			{
				psNode = dllist_get_next_node(psNode);
			}

			while ((psNode != NULL && psNode != &sListFirst) &&
					!bPMRToDisplay)
			{
				psRIEntry =	IMG_CONTAINER_OF(psNode, RI_LIST_ENTRY, sListNode);
				if (psRIEntry->ui32RIPMRFlags & RI_FLAG_PARSED_BY_DEBUGFS)
				{
					IMG_DEVMEM_SIZE_T uiPMRPhysicalBacking, uiPMRLogicalSize = 0;

					/* This PMR was 'touched', so display details and unflag it*/
					_GeneratePMREntryString(psRIEntry,
											IMG_TRUE,
											RI_PMR_ENTRY_BUF_SIZE,
											acStringBuffer);
					psRIEntry->ui32RIPMRFlags &= ~RI_FLAG_PARSED_BY_DEBUGFS;
					PMR_LogicalSize(psRIEntry->psPMR, &uiPMRLogicalSize);
					ui64TotalPMRAlloc += uiPMRLogicalSize;
					PMR_PhysicalSize(psRIEntry->psPMR, &uiPMRPhysicalBacking);
					ui64TotalPMRBacked += uiPMRPhysicalBacking;

					/* Remember the name of the process for 1 PMR for the summary */
					if (szProcName[0] == '\0')
					{
						OSStringCopy(szProcName, psRIEntry->ai8ProcName);
					}
					bPMRToDisplay = IMG_TRUE;
				}
				else
				{
					psNode = dllist_get_next_node(psNode);
				}
			}

			if (psNode == NULL || (psNode == &sListFirst))
			{
				g_bNextGetState = RI_GET_STATE_PMR_SUMMARY;
			}
			/* else continue listing PMRs */
		}
		break;

	case RI_GET_STATE_PMR_SUMMARY:
		OSSNPrintf(acStringBuffer,
		           RI_PMR_SUM_BUF_SIZE,
		           RI_PMR_SUM_FRMT,
		           pid,
		           szProcName,
		           ui64TotalPMRAlloc,
		           ui64TotalPMRAlloc >> 10,
		           ui64TotalPMRBacked,
		           ui64TotalPMRBacked >> 10);

		*ppszEntryString = acStringBuffer;
		ui64TotalPMRAlloc = 0;
		ui64TotalPMRBacked = 0;
		szProcName[0] = '\0';
		psSysAllocNode = NULL;

		g_bNextGetState = RI_GET_STATE_END;
		break;

	default:
		PVR_DPF((PVR_DBG_ERROR, "%s: Bad %d)",__func__, g_bNextGetState));

		__fallthrough;
	case RI_GET_STATE_END:
		/* Reset state ready for the next gpu_mem_area file to display */
		*ppszEntryString = NULL;
		*ppHandle        = NULL;
		psNode = NULL;
		szProcName[0] = '\0';

		g_bNextGetState = RI_GET_STATE_MEMDESCS_LIST_START;
		return IMG_FALSE;
		break;
	}

	return IMG_TRUE;
}

/* Function used to produce string containing info for MEMDESC RI entries (used for both debugfs and kernel log output) */
static void _GenerateMEMDESCEntryString(RI_SUBLIST_ENTRY *psRISubEntry,
                                        IMG_BOOL bDebugFs,
                                        IMG_UINT16 ui16MaxStrLen,
                                        IMG_CHAR *pszEntryString)
{
	IMG_CHAR szProc[RI_MEMDESC_ENTRY_PROC_BUF_SIZE];
	IMG_CHAR szImport[RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE];
	IMG_CHAR szEntryFormat[RI_MEMDESC_ENTRY_FRMT_SIZE];
	const IMG_CHAR *pszAnnotationText;
	IMG_PID uiRIPid = 0;
	PMR* psRIPMR = NULL;
	IMG_UINT32 ui32RIPMRFlags = 0;

	if(psRISubEntry->psRI != NULL)
	{
		uiRIPid = psRISubEntry->psRI->pid;
		psRIPMR = psRISubEntry->psRI->psPMR;
		ui32RIPMRFlags = psRISubEntry->psRI->ui32RIPMRFlags;
	}

	OSSNPrintf(szEntryFormat,
			RI_MEMDESC_ENTRY_FRMT_SIZE,
			RI_MEMDESC_ENTRY_FRMT,
			DEVMEM_ANNOTATION_MAX_LEN);

	if (!bDebugFs)
	{
		/* we don't include process ID info for debugfs output */
		OSSNPrintf(szProc,
				RI_MEMDESC_ENTRY_PROC_BUF_SIZE,
				RI_MEMDESC_ENTRY_PROC_FRMT,
				psRISubEntry->pid,
				psRISubEntry->ai8ProcName);
	}

	if (psRISubEntry->bIsImport && psRIPMR)
	{
		OSSNPrintf((IMG_CHAR *)&szImport,
		           RI_MEMDESC_ENTRY_IMPORT_BUF_SIZE,
		           RI_MEMDESC_ENTRY_IMPORT_FRMT,
		           uiRIPid);
		/* Set pszAnnotationText to that of the 'parent' PMR RI entry */
		pszAnnotationText = PMR_GetAnnotation(psRIPMR);
	}
	else if (!psRISubEntry->bIsSuballoc && psRIPMR)
	{
		/* Set pszAnnotationText to that of the 'parent' PMR RI entry */
		pszAnnotationText = PMR_GetAnnotation(psRIPMR);
	}
	else
	{
		/* Set pszAnnotationText to that of the MEMDESC RI entry */
		pszAnnotationText = psRISubEntry->ai8TextB;
	}

	/* Don't print memdescs if they are local imports
	 * (i.e. imported PMRs allocated by this process)
	 */
	if (bDebugFs &&
		((psRISubEntry->sVAddr.uiAddr + psRISubEntry->ui64Offset) == 0) &&
		(psRISubEntry->bIsImport && ((psRISubEntry->pid == uiRIPid) || (uiRIPid == PVR_SYS_ALLOC_PID))))
	{
		/* Don't print this entry */
		pszEntryString[0] = '\0';
	}
	else
	{
		OSSNPrintf(pszEntryString,
				   ui16MaxStrLen,
				   szEntryFormat,
				   (bDebugFs ? "" : "   "),
				   psRISubEntry->pid,
				   (psRISubEntry->sVAddr.uiAddr + psRISubEntry->ui64Offset),
				   pszAnnotationText,
				   (bDebugFs ? "" : (char *)szProc),
				   psRISubEntry->ui64Size,
				   psRIPMR,
				   (psRISubEntry->bIsImport ? (char *)&szImport : ""),
				   (!psRISubEntry->bIsImport && (ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR) && (psRISubEntry->pid != PVR_SYS_ALLOC_PID)) ? g_szSysAllocImport : "",
				   (psRIPMR && PMR_IsUnpinned(psRIPMR)) ? RI_MEMDESC_ENTRY_UNPINNED_FRMT : "",
				   (bDebugFs ? '\n' : ' '));
	}
}

/* Function used to produce string containing info for PMR RI entries (used for debugfs and kernel log output) */
static void _GeneratePMREntryString(RI_LIST_ENTRY *psRIEntry,
                                    IMG_BOOL bDebugFs,
                                    IMG_UINT16 ui16MaxStrLen,
                                    IMG_CHAR *pszEntryString)
{
	const IMG_CHAR*   pszAnnotationText;
	IMG_DEVMEM_SIZE_T uiLogicalSize = 0;
	IMG_DEVMEM_SIZE_T uiPhysicalSize = 0;
	IMG_CHAR          szEntryFormat[RI_PMR_ENTRY_FRMT_SIZE];

	PMR_LogicalSize(psRIEntry->psPMR, &uiLogicalSize);

	PMR_PhysicalSize(psRIEntry->psPMR, &uiPhysicalSize);

	OSSNPrintf(szEntryFormat,
			RI_PMR_ENTRY_FRMT_SIZE,
			RI_PMR_ENTRY_FRMT,
			DEVMEM_ANNOTATION_MAX_LEN);

	/* Set pszAnnotationText to that PMR RI entry */
	pszAnnotationText = (IMG_PCHAR) PMR_GetAnnotation(psRIEntry->psPMR);

	OSSNPrintf(pszEntryString,
	           ui16MaxStrLen,
	           szEntryFormat,
	           (bDebugFs ? "" : "   "),
	           psRIEntry->pid,
	           (void*)psRIEntry->psPMR,
	           pszAnnotationText,
	           uiLogicalSize,
	           uiPhysicalSize,
	           (bDebugFs ? '\n' : ' '));
}

/*!
*******************************************************************************

 @Function	_DumpList

 @Description
            Dumps out RI List entries according to parameters passed.

 @input     psPMR - If not NULL, function will output the RI entries for
                   the specified PMR only
 @input     pid - If non-zero, the function will only output MEMDESC RI
  	  	  	  	  entries made by the process with ID pid.
                  If zero, all MEMDESC RI entries will be output.

 @Return	PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR _DumpList(PMR *psPMR, IMG_PID pid)
{
	RI_LIST_ENTRY *psRIEntry = NULL;
	RI_SUBLIST_ENTRY *psRISubEntry = NULL;
	IMG_UINT16 ui16SubEntriesParsed = 0;
	uintptr_t hashData = 0;
	IMG_PID hashKey;
	PMR *pPMRHashKey = psPMR;
	IMG_BOOL bDisplayedThisPMR = IMG_FALSE;
	IMG_UINT64 ui64LogicalSize = 0;

	if (!psPMR)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (g_pRIHashTable && g_pProcHashTable)
	{
		if (pid != 0)
		{
			/* look-up pid in Hash Table */
			hashKey = pid;
			hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&hashKey);
			if (hashData)
			{
				psRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode);
				if (psRISubEntry)
				{
					psRIEntry = psRISubEntry->psRI;
				}
			}
		}
		else
		{
			/* Look-up psPMR in Hash Table */
			hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey);
			psRIEntry = (RI_LIST_ENTRY *)hashData;
		}
		if (!psRIEntry)
		{
			/* No entry found in hash table */
			return PVRSRV_ERROR_NOT_FOUND;
		}
		while (psRIEntry)
		{
			bDisplayedThisPMR = IMG_FALSE;
			/* Output details for RI entry */
			if (!pid)
			{
				PMR_LogicalSize(psPMR, (IMG_DEVMEM_SIZE_T*)&ui64LogicalSize);

				_RIOutput (("%s <%p> suballocs:%d size:0x%010" IMG_UINT64_FMTSPECx,
				            PMR_GetAnnotation(psRIEntry->psPMR),
				            psRIEntry->psPMR,
				            (IMG_UINT)psRIEntry->ui16SubListCount,
				            ui64LogicalSize));
				bDisplayedThisPMR = IMG_TRUE;
			}
			ui16SubEntriesParsed = 0;
			if (psRIEntry->ui16SubListCount)
			{
#if _DUMP_LINKEDLIST_INFO
				_RIOutput (("RI LIST: {sSubListFirst.psNextNode:0x%p}\n",
				            psRIEntry->sSubListFirst.psNextNode));
#endif /* _DUMP_LINKEDLIST_INFO */
				if (!pid)
				{
					psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)),
					                                RI_SUBLIST_ENTRY, sListNode);
				}
				/* Traverse RI sublist and output details for each entry */
				while (psRISubEntry)
				{
					if(psRIEntry)
					{
						if((ui16SubEntriesParsed >= psRIEntry->ui16SubListCount))
						{
							break;
						}
						if (!bDisplayedThisPMR)
						{
							PMR_LogicalSize(psPMR, (IMG_DEVMEM_SIZE_T*)&ui64LogicalSize);

							_RIOutput (("%s <%p> suballocs:%d size:0x%010" IMG_UINT64_FMTSPECx,
								    PMR_GetAnnotation(psRIEntry->psPMR),
								    psRIEntry->psPMR,
								    (IMG_UINT)psRIEntry->ui16SubListCount,
								    ui64LogicalSize));
							bDisplayedThisPMR = IMG_TRUE;
						}
					}
#if _DUMP_LINKEDLIST_INFO
					_RIOutput (("RI LIST:    [this subentry:0x%p]\n",psRISubEntry));
					_RIOutput (("RI LIST:     psRI:0x%p\n",psRISubEntry->psRI));
#endif /* _DUMP_LINKEDLIST_INFO */

					{
						IMG_CHAR szEntryString[RI_MEMDESC_ENTRY_BUF_SIZE];

						_GenerateMEMDESCEntryString(psRISubEntry,
						                            IMG_FALSE,
						                            RI_MEMDESC_ENTRY_BUF_SIZE,
						                            szEntryString);
						_RIOutput (("%s",szEntryString));
					}

					if (pid)
					{
						if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) ||
							(dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData))
						{
							psRISubEntry = NULL;
						}
						else
						{
							psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)),
							                                RI_SUBLIST_ENTRY, sProcListNode);
							if (psRISubEntry)
							{
								if (psRIEntry != psRISubEntry->psRI)
								{
									/*
									 * The next MEMDESC in the process linked list is in a different PMR
									 */
									psRIEntry = psRISubEntry->psRI;
									bDisplayedThisPMR = IMG_FALSE;
								}
							}
						}
					}
					else
					{
						ui16SubEntriesParsed++;
						psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sListNode)),
						                                RI_SUBLIST_ENTRY, sListNode);
					}
				}
			}
			if (!pid && psRIEntry)
			{
				if (ui16SubEntriesParsed != psRIEntry->ui16SubListCount)
				{
					/*
					 * Output error message as sublist does not contain the
					 * number of entries indicated by sublist count
					 */
					_RIOutput (("RI ERROR: RI sublist contains %d entries, not %d entries\n",
					            ui16SubEntriesParsed,psRIEntry->ui16SubListCount));
				}
				else if (psRIEntry->ui16SubListCount && !dllist_get_next_node(&(psRIEntry->sSubListFirst)))
				{
					/*
					 * Output error message as sublist is empty but sublist count
					 * is not zero
					 */
					_RIOutput (("RI ERROR: ui16SubListCount=%d for empty RI sublist\n",
					            psRIEntry->ui16SubListCount));
				}
			}
			psRIEntry = NULL;
		}
	}
	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIDumpAllKM

 @Description
            Dumps out the contents of all RI List entries (i.e. for all
            MEMDESC allocations for each PMR).
            At present, output is directed to Kernel log
            via PVR_DPF.

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDumpAllKM(void)
{
	if (g_pRIHashTable)
	{
		return HASH_Iterate(g_pRIHashTable, (HASH_pfnCallback)_DumpAllEntries);
	}
	return PVRSRV_OK;
}

/*!
*******************************************************************************

 @Function	RIDumpProcessKM

 @Description
            Dumps out the contents of all MEMDESC RI List entries (for every
            PMR) which have been allocate by the specified process only.
            At present, output is directed to Kernel log
            via PVR_DPF.

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDumpProcessKM(IMG_PID pid)
{
	PVRSRV_ERROR eError;
	IMG_UINT32 dummyPMR;

	if (!g_pProcHashTable)
	{
		return PVRSRV_OK;
	}

	/* Acquire RI lock*/
	_RILock();

	eError = _DumpList((PMR *)&dummyPMR,pid);

	/* Release RI lock*/
	_RIUnlock();

	return eError;
}

/*!
*******************************************************************************

 @Function	_TotalAllocsForProcess

 @Description
            Totals all PMR physical backing for given process.

 @input     pid - ID of process.

 @input     ePhysHeapType - type of Physical Heap for which to total allocs

 @Return	Size of all physical backing for PID's PMRs allocated from the
            specified heap type (in bytes).

******************************************************************************/
static IMG_INT32 _TotalAllocsForProcess(IMG_PID pid, PHYS_HEAP_TYPE ePhysHeapType)
{
	RI_LIST_ENTRY *psRIEntry = NULL;
	RI_SUBLIST_ENTRY *psInitialRISubEntry = NULL;
	RI_SUBLIST_ENTRY *psRISubEntry = NULL;
	uintptr_t hashData = 0;
	IMG_PID hashKey;
	IMG_INT32 i32TotalPhysical = 0;

	if (g_pRIHashTable && g_pProcHashTable)
	{
		if (pid == PVR_SYS_ALLOC_PID)
		{
			IMG_UINT32 ui32ProcessedSysAllocPMRCount = 0;
			DLLIST_NODE *psSysAllocNode = NULL;

			OSLockAcquire(g_hSysAllocPidListLock);
			psSysAllocNode = dllist_get_next_node(&g_sSysAllocPidListHead);
			while (psSysAllocNode && psSysAllocNode != &g_sSysAllocPidListHead)
			{
				psRIEntry = IMG_CONTAINER_OF((PDLLIST_NODE)psSysAllocNode, RI_LIST_ENTRY, sSysAllocListNode);
				ui32ProcessedSysAllocPMRCount++;
				if (PhysHeapGetType(PMR_PhysHeap(psRIEntry->psPMR)) == ePhysHeapType)
				{
					IMG_UINT64 ui64PhysicalSize;

					PMR_PhysicalSize(psRIEntry->psPMR, (IMG_DEVMEM_SIZE_T*)&ui64PhysicalSize);
					if (((IMG_UINT64)i32TotalPhysical + ui64PhysicalSize > 0x7fffffff))
					{
						PVR_DPF((PVR_DBG_WARNING, "%s: i32TotalPhysical exceeding size for i32",__func__));
					}
					i32TotalPhysical += (IMG_INT32)(ui64PhysicalSize & 0x00000000ffffffff);
				}
				psSysAllocNode = dllist_get_next_node(psSysAllocNode);
			}
			OSLockRelease(g_hSysAllocPidListLock);
		}
		else
		{
			if (pid != 0)
			{
				/* look-up pid in Hash Table */
				hashKey = pid;
				hashData = HASH_Retrieve_Extended (g_pProcHashTable, (void *)&hashKey);
				if (hashData)
				{
					psInitialRISubEntry = IMG_CONTAINER_OF((PDLLIST_NODE)hashData, RI_SUBLIST_ENTRY, sProcListNode);
					psRISubEntry = psInitialRISubEntry;
					if (psRISubEntry)
					{
						psRIEntry = psRISubEntry->psRI;
					}
				}
			}

			while (psRISubEntry && psRIEntry)
			{
				if (!psRISubEntry->bIsImport && !(psRIEntry->ui32RIPMRFlags & RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS) &&
					(pid == PVR_SYS_ALLOC_PID || !(psRIEntry->ui32RIPMRFlags & RI_FLAG_SYSALLOC_PMR)) &&
					(PhysHeapGetType(PMR_PhysHeap(psRIEntry->psPMR)) == ePhysHeapType))
				{
					IMG_UINT64 ui64PhysicalSize;


					PMR_PhysicalSize(psRIEntry->psPMR, (IMG_DEVMEM_SIZE_T*)&ui64PhysicalSize);
					if (((IMG_UINT64)i32TotalPhysical + ui64PhysicalSize > 0x7fffffff))
					{
						PVR_DPF((PVR_DBG_WARNING, "%s: i32TotalPhysical exceeding size for i32",__func__));
					}
					i32TotalPhysical += (IMG_INT32)(ui64PhysicalSize & 0x00000000ffffffff);
					psRIEntry->ui32RIPMRFlags |= RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS;
				}
				if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) ||
					(dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData))
				{
					psRISubEntry = NULL;
					psRIEntry = NULL;
				}
				else
				{
					psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)),
					                                RI_SUBLIST_ENTRY, sProcListNode);
					if (psRISubEntry)
					{
						psRIEntry = psRISubEntry->psRI;
					}
				}
			}
			psRISubEntry = psInitialRISubEntry;
			if (psRISubEntry)
			{
				psRIEntry = psRISubEntry->psRI;
			}
			while (psRISubEntry && psRIEntry)
			{
				psRIEntry->ui32RIPMRFlags &= ~RI_FLAG_PMR_PHYS_COUNTED_BY_DEBUGFS;
				if ((dllist_get_next_node(&(psRISubEntry->sProcListNode)) == NULL) ||
					(dllist_get_next_node(&(psRISubEntry->sProcListNode)) == (PDLLIST_NODE)hashData))
				{
					psRISubEntry = NULL;
					psRIEntry = NULL;
				}
				else
				{
					psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sProcListNode)),
					                                RI_SUBLIST_ENTRY, sProcListNode);
					if (psRISubEntry)
					{
						psRIEntry = psRISubEntry->psRI;
					}
				}
			}
		}
	}
	return i32TotalPhysical;
}

/*!
*******************************************************************************

 @Function	RITotalAllocProcessKM

 @Description
            Returns the total of allocated GPU memory (backing for PMRs)
            which has been allocated from the specific heap by the specified
            process only.

 @Return	Amount of physical backing allocated (in bytes)

******************************************************************************/
IMG_INT32 RITotalAllocProcessKM(IMG_PID pid, PHYS_HEAP_TYPE ePhysHeapType)
{
	IMG_INT32 i32BackingTotal = 0;

	if (g_pProcHashTable)
	{
		/* Acquire RI lock*/
		_RILock();

		i32BackingTotal = _TotalAllocsForProcess(pid, ePhysHeapType);

		/* Release RI lock*/
		_RIUnlock();
	}
	return i32BackingTotal;
}

#if defined(DEBUG)
/*!
*******************************************************************************

 @Function	_DumpProcessList

 @Description
            Dumps out RI List entries according to parameters passed.

 @input     psPMR - If not NULL, function will output the RI entries for
                   the specified PMR only
 @input     pid - If non-zero, the function will only output MEMDESC RI
  	  	  	  	  entries made by the process with ID pid.
                  If zero, all MEMDESC RI entries will be output.

 @Return	PVRSRV_ERROR

******************************************************************************/
static PVRSRV_ERROR _DumpProcessList(PMR *psPMR,
									 IMG_PID pid,
									 IMG_UINT64 ui64Offset,
									 IMG_DEV_VIRTADDR *psDevVAddr)
{
	RI_LIST_ENTRY *psRIEntry = NULL;
	RI_SUBLIST_ENTRY *psRISubEntry = NULL;
	IMG_UINT16 ui16SubEntriesParsed = 0;
	uintptr_t hashData = 0;
	PMR *pPMRHashKey = psPMR;

	psDevVAddr->uiAddr = 0;

	if (!psPMR)
	{
		/* NULL handle provided */
		return PVRSRV_ERROR_INVALID_PARAMS;
	}

	if (g_pRIHashTable && g_pProcHashTable)
	{
		PVR_ASSERT(psPMR && pid);

		/* Look-up psPMR in Hash Table */
		hashData = HASH_Retrieve_Extended (g_pRIHashTable, (void *)&pPMRHashKey);
		psRIEntry = (RI_LIST_ENTRY *)hashData;

		if (!psRIEntry)
		{
			/* No entry found in hash table */
			return PVRSRV_ERROR_NOT_FOUND;
		}

		if (psRIEntry->ui16SubListCount)
		{
			psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)),
											RI_SUBLIST_ENTRY, sListNode);

			/* Traverse RI sublist and output details for each entry */
			while (psRISubEntry && (ui16SubEntriesParsed < psRIEntry->ui16SubListCount))
			{
				if (pid == psRISubEntry->pid)
				{
					IMG_UINT64 ui64StartOffset = psRISubEntry->ui64Offset;
					IMG_UINT64 ui64EndOffset = psRISubEntry->ui64Offset + psRISubEntry->ui64Size;

					if (ui64Offset >= ui64StartOffset && ui64Offset < ui64EndOffset)
					{
						psDevVAddr->uiAddr = psRISubEntry->sVAddr.uiAddr;
						return PVRSRV_OK;
					}
				}

				ui16SubEntriesParsed++;
				psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRISubEntry->sListNode)),
												RI_SUBLIST_ENTRY, sListNode);
			}
		}
	}

	return PVRSRV_ERROR_INVALID_PARAMS;
}

/*!
*******************************************************************************

 @Function	RIDumpProcessListKM

 @Description
            Dumps out selected contents of all MEMDESC RI List entries (for a
            PMR) which have been allocate by the specified process only.

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR RIDumpProcessListKM(PMR *psPMR,
								 IMG_PID pid,
								 IMG_UINT64 ui64Offset,
								 IMG_DEV_VIRTADDR *psDevVAddr)
{
	PVRSRV_ERROR eError;

	if (!g_pProcHashTable)
	{
		return PVRSRV_OK;
	}

	/* Acquire RI lock*/
	_RILock();

	eError = _DumpProcessList(psPMR,
							  pid,
							  ui64Offset,
							  psDevVAddr);

	/* Release RI lock*/
	_RIUnlock();

	return eError;
}
#endif

static PVRSRV_ERROR _DumpAllEntries (uintptr_t k, uintptr_t v)
{
	RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v;

	PVR_UNREFERENCED_PARAMETER (k);

	return RIDumpListKM(psRIEntry->psPMR);
}

static PVRSRV_ERROR _DeleteAllEntries (uintptr_t k, uintptr_t v)
{
	RI_LIST_ENTRY *psRIEntry = (RI_LIST_ENTRY *)v;
	RI_SUBLIST_ENTRY *psRISubEntry;
	PVRSRV_ERROR eResult = PVRSRV_OK;

	PVR_UNREFERENCED_PARAMETER (k);

	while ((eResult == PVRSRV_OK) && (psRIEntry->ui16SubListCount > 0))
	{
		psRISubEntry = IMG_CONTAINER_OF(dllist_get_next_node(&(psRIEntry->sSubListFirst)), RI_SUBLIST_ENTRY, sListNode);
		eResult = RIDeleteMEMDESCEntryKM((RI_HANDLE)psRISubEntry);
	}
	if (eResult == PVRSRV_OK)
	{
		eResult = RIDeletePMREntryKM((RI_HANDLE)psRIEntry);
		/*
		 * If we've deleted the Hash table, return
		 * an error to stop the iterator...
		 */
		if (!g_pRIHashTable)
		{
			eResult = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
		}
	}
	return eResult;
}

static PVRSRV_ERROR _DeleteAllProcEntries (uintptr_t k, uintptr_t v)
{
	RI_SUBLIST_ENTRY *psRISubEntry = (RI_SUBLIST_ENTRY *)v;
	PVRSRV_ERROR eResult;

	PVR_UNREFERENCED_PARAMETER (k);

	eResult = RIDeleteMEMDESCEntryKM((RI_HANDLE) psRISubEntry);
	if (eResult == PVRSRV_OK && !g_pProcHashTable)
	{
		/*
		 * If we've deleted the Hash table, return
		 * an error to stop the iterator...
		 */
		eResult = PVRSRV_ERROR_RESOURCE_UNAVAILABLE;
	}

	return eResult;
}

#endif /* if defined(PVRSRV_ENABLE_GPU_MEMORY_INFO) */
