summaryrefslogtreecommitdiff
path: root/drivers/staging/imgtec/rogue/pvr_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/imgtec/rogue/pvr_debugfs.c')
-rw-r--r--drivers/staging/imgtec/rogue/pvr_debugfs.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/drivers/staging/imgtec/rogue/pvr_debugfs.c b/drivers/staging/imgtec/rogue/pvr_debugfs.c
index fd41407a59e4..cba6d6c0997e 100644
--- a/drivers/staging/imgtec/rogue/pvr_debugfs.c
+++ b/drivers/staging/imgtec/rogue/pvr_debugfs.c
@@ -98,6 +98,8 @@ typedef struct _PVR_DEBUGFS_PRIV_DATA_
struct seq_operations *psReadOps;
PVRSRV_ENTRY_WRITE_FUNC *pfnWrite;
void *pvData;
+ PVRSRV_INC_FSENTRY_PVDATA_REFCNT_FN *pfIncPvDataRefCnt;
+ PVRSRV_DEC_FSENTRY_PVDATA_REFCNT_FN *pfDecPvDataRefCnt;
IMG_BOOL bValid;
PVR_DEBUGFS_ENTRY_DATA *psDebugFSEntry;
} PVR_DEBUGFS_PRIV_DATA;
@@ -127,18 +129,13 @@ static void *_DebugFSStatisticSeqStart(struct seq_file *psSeqFile, loff_t *puiPo
if (psStatData)
{
- if (psStatData->pvData)
- {
- /* take reference on psStatData (for duration of stat iteration) */
- if (!_RefStatEntry((void*)psStatData))
- {
- PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called for '%s' but failed to take ref on stat entry, returning -EIO(%d)", __FUNCTION__, psStatData->pvDebugFSEntry->psEntry->d_iname, -EIO));
- return NULL;
- }
- }
- else
+ /* take reference on psStatData (for duration of stat iteration) */
+ if (!_RefStatEntry(psStatData))
{
- /* NB This is valid if the stat has no structure associated with it (eg. driver_stats, which prints totals stored in a number of global vars) */
+ PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called for '%s' but failed"
+ " to take ref on stat entry, returning -EIO(%d)", __func__,
+ psStatData->pvDebugFSEntry->psEntry->d_iname, -EIO));
+ return NULL;
}
if (*puiPosition == 0)
@@ -162,24 +159,11 @@ static void _DebugFSStatisticSeqStop(struct seq_file *psSeqFile, void *pvData)
if (psStatData)
{
/* drop ref taken on stat memory, and if it is now zero, be sure we don't try to read it again */
- if ((psStatData->ui32RefCount > 0) && (psStatData->pvData))
+ if (psStatData->ui32RefCount > 0)
{
/* drop reference on psStatData (held for duration of stat iteration) */
_UnrefAndMaybeDestroyStatEntry((void*)psStatData);
}
- else
- {
- if (psStatData->ui32RefCount > 0)
- {
- /* psStatData->pvData is NULL */
- /* NB This is valid if the stat has no structure associated with it (eg. driver_stats, which prints totals stored in a number of global vars) */
- }
- if (psStatData->pvData)
- {
- /* psStatData->ui32RefCount is zero */
- PVR_DPF((PVR_DEBUGFS_PVR_DPF_LEVEL, "%s: Called when psStatData->ui32RefCount is %d", __FUNCTION__, psStatData->ui32RefCount));
- }
- }
}
else
{
@@ -271,12 +255,16 @@ static int _DebugFSFileOpen(struct inode *psINode, struct file *psFile)
psDebugFSEntry = psPrivData->psDebugFSEntry;
/* Take ref on stat entry before opening seq file - this ref will be dropped if we
- * fail to open the seq file or when we close it
- */
+ * fail to open the seq file or when we close it
+ */
if (psDebugFSEntry)
{
bRefRet = _RefDebugFSEntryNoLock(psDebugFSEntry);
mutex_unlock(&gDebugFSLock);
+ if (psPrivData->pfIncPvDataRefCnt)
+ {
+ psPrivData->pfIncPvDataRefCnt(psPrivData->pvData);
+ }
if (bRefRet)
{
iResult = seq_open(psFile, psPrivData->psReadOps);
@@ -288,6 +276,10 @@ static int _DebugFSFileOpen(struct inode *psINode, struct file *psFile)
}
else
{
+ if (psPrivData->pfDecPvDataRefCnt)
+ {
+ psPrivData->pfDecPvDataRefCnt(psPrivData->pvData);
+ }
/* Drop ref if we failed to open seq file */
_UnrefAndMaybeDestroyDebugFSEntry(&psPrivData->psDebugFSEntry);
PVR_DPF((PVR_DBG_ERROR, "%s: Failed to seq_open psFile, returning %d", __FUNCTION__, iResult));
@@ -327,6 +319,10 @@ static int _DebugFSFileClose(struct inode *psINode, struct file *psFile)
{
_UnrefAndMaybeDestroyDebugFSEntry(&psPrivData->psDebugFSEntry);
}
+ if (psPrivData->pfDecPvDataRefCnt)
+ {
+ psPrivData->pfDecPvDataRefCnt(psPrivData->pvData);
+ }
return iResult;
}
@@ -510,6 +506,8 @@ int PVRDebugFSCreateEntry(const char *pszName,
PVR_DEBUGFS_DIR_DATA *psParentDir,
struct seq_operations *psReadOps,
PVRSRV_ENTRY_WRITE_FUNC *pfnWrite,
+ PVRSRV_INC_FSENTRY_PVDATA_REFCNT_FN *pfnIncPvDataRefCnt,
+ PVRSRV_DEC_FSENTRY_PVDATA_REFCNT_FN *pfnDecPvDataRefCnt,
void *pvData,
PVR_DEBUGFS_ENTRY_DATA **ppsNewEntry)
{
@@ -519,6 +517,8 @@ int PVRDebugFSCreateEntry(const char *pszName,
umode_t uiMode;
PVR_ASSERT(gpsPVRDebugFSEntryDir != NULL);
+ PVR_ASSERT(!((pfnIncPvDataRefCnt != NULL && pfnDecPvDataRefCnt == NULL) ||
+ (pfnIncPvDataRefCnt == NULL && pfnDecPvDataRefCnt != NULL)));
psPrivData = OSAllocMemNoStats(sizeof(*psPrivData));
if (psPrivData == NULL)
@@ -535,6 +535,8 @@ int PVRDebugFSCreateEntry(const char *pszName,
psPrivData->psReadOps = psReadOps;
psPrivData->pfnWrite = pfnWrite;
psPrivData->pvData = (void*)pvData;
+ psPrivData->pfIncPvDataRefCnt = pfnIncPvDataRefCnt;
+ psPrivData->pfDecPvDataRefCnt = pfnDecPvDataRefCnt;
psPrivData->bValid = IMG_TRUE;
/* Store ptr to debugFSEntry in psPrivData, so a ref can be taken on it
* when the client opens a file */
@@ -660,6 +662,8 @@ PVR_DEBUGFS_DRIVER_STAT *PVRDebugFSCreateStatisticEntry(const char *pszName,
psDir,
&gsDebugFSStatisticReadOps,
NULL,
+ (PVRSRV_INC_FSENTRY_PVDATA_REFCNT_FN *) _RefStatEntry,
+ (PVRSRV_DEC_FSENTRY_PVDATA_REFCNT_FN *) _UnrefAndMaybeDestroyStatEntry,
psStatData,
&psDebugFSEntry);
if (iResult != 0)
@@ -690,6 +694,7 @@ PVR_DEBUGFS_DRIVER_STAT *PVRDebugFSCreateStatisticEntry(const char *pszName,
*/ /**************************************************************************/
void PVRDebugFSRemoveStatisticEntry(PVR_DEBUGFS_DRIVER_STAT *psStatEntry)
{
+ PVR_ASSERT(psStatEntry != NULL);
/* drop reference on pvStatEntry*/
_UnrefAndMaybeDestroyStatEntry(psStatEntry);
}