summaryrefslogtreecommitdiff
path: root/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/services4/srvkm/env/linux/proc.c')
-rwxr-xr-x[-rw-r--r--]drivers/gpu/pvr/services4/srvkm/env/linux/proc.c896
1 files changed, 213 insertions, 683 deletions
diff --git a/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c b/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c
index 4a6e2fedc42..788757ba2a4 100644..100755
--- a/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c
+++ b/drivers/gpu/pvr/services4/srvkm/env/linux/proc.c
@@ -52,11 +52,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/sched.h>
#include "services_headers.h"
@@ -72,16 +70,25 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "lists.h"
+struct pvr_proc_dir_entry {
+ struct proc_dir_entry *pde;
+
+ pvr_next_proc_seq_t *next;
+ pvr_show_proc_seq_t *show;
+ pvr_off2element_proc_seq_t *off2element;
+ pvr_startstop_proc_seq_t *startstop;
+
+ pvr_proc_write_t *write;
+
+ IMG_VOID *data;
+};
+
// The proc entry for our /proc/pvr directory
static struct proc_dir_entry * dir;
static const IMG_CHAR PVRProcDirRoot[] = "pvr";
static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
-static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
-static void pvr_proc_seq_stop (struct seq_file *m, void *v);
-static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
-static int pvr_proc_seq_show (struct seq_file *m, void *v);
static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
static struct file_operations pvr_proc_operations =
@@ -93,17 +100,10 @@ static struct file_operations pvr_proc_operations =
.release = seq_release,
};
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
-static ssize_t pvr_proc_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos);
-static struct file_operations pvr_read_proc_operations =
-{
- .open = pvr_proc_open,
- .read = pvr_proc_read,
- .write = pvr_proc_write,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-#endif
+static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
+static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
+static void pvr_proc_seq_stop (struct seq_file *m, void *v);
+static int pvr_proc_seq_show (struct seq_file *m, void *v);
static struct seq_operations pvr_proc_seq_operations =
{
@@ -113,16 +113,18 @@ static struct seq_operations pvr_proc_seq_operations =
.show = pvr_proc_seq_show,
};
-static struct proc_dir_entry* g_pProcQueue;
-static struct proc_dir_entry* g_pProcVersion;
-static struct proc_dir_entry* g_pProcSysNodes;
+#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
+static struct pvr_proc_dir_entry* g_pProcQueue;
+#endif
+static struct pvr_proc_dir_entry* g_pProcVersion;
+static struct pvr_proc_dir_entry* g_pProcSysNodes;
#ifdef DEBUG
-static struct proc_dir_entry* g_pProcDebugLevel;
+static struct pvr_proc_dir_entry* g_pProcDebugLevel;
#endif
#ifdef PVR_MANUAL_POWER_CONTROL
-static struct proc_dir_entry* g_pProcPowerLevel;
+static struct pvr_proc_dir_entry* g_pProcPowerLevel;
#endif
@@ -131,55 +133,12 @@ static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
-/*!
-******************************************************************************
-
- @Function : printAppend
-
- @Description
-
- Print into the supplied buffer at the specified offset remaining within
- the specified total buffer size.
- @Input size : the total size of the buffer
-
- @Input off : the offset into the buffer to start printing
-
- @Input format : the printf format string
-
- @Input ... : format args
-
- @Return : The number of chars now in the buffer (original value of 'off'
- plus number of chars added); 'size' if full.
-
-*****************************************************************************/
-off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
-{
- IMG_INT n;
- size_t space = size - (size_t)off;
- va_list ap;
-
- va_start (ap, format);
-
- n = vsnprintf (buffer+off, space, format, ap);
-
- va_end (ap);
- /* According to POSIX, n is greater than or equal to the size available if
- * the print would have overflowed the buffer. Other platforms may
- * return -1 if printing was truncated.
- */
- if (n >= (IMG_INT)space || n < 0)
- {
- /* Ensure final string is terminated */
- buffer[size - 1] = 0;
- return (off_t)(size - 1);
- }
- else
- {
- return (off + (off_t)n);
- }
-}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+#define PDE_DATA(x) PDE(x)->data;
+#endif
+#ifdef DEBUG
/*!
******************************************************************************
@@ -198,7 +157,7 @@ off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * fo
@Return : Pointer to element to be shown.
*****************************************************************************/
-void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
+static void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
{
PVR_UNREFERENCED_PARAMETER(sfile);
// Return anything that is not PVR_RPOC_SEQ_START_TOKEN and NULL
@@ -207,6 +166,7 @@ void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
return NULL;
}
+#endif
/*!
******************************************************************************
@@ -225,7 +185,7 @@ void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
@Return : Pointer to element to be shown.
*****************************************************************************/
-void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
+static void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
{
PVR_UNREFERENCED_PARAMETER(sfile);
@@ -263,15 +223,10 @@ static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
struct seq_file *seq = (struct seq_file*)file->private_data;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- struct proc_dir_entry* pvr_proc_entry = PDE(inode);
+ struct pvr_proc_dir_entry* ppde = PDE_DATA(inode);
/* Add pointer to handlers to seq_file structure */
- seq->private = pvr_proc_entry->data;
-#else
- PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *)PDE_DATA(inode);
- seq->private = data;
-#endif
+ seq->private = ppde;
return ret;
}
@@ -290,23 +245,15 @@ static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct inode *inode = file->f_path.dentry->d_inode;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- struct proc_dir_entry * dp;
+ struct pvr_proc_dir_entry * ppde;
PVR_UNREFERENCED_PARAMETER(ppos);
- dp = PDE(inode);
+ ppde = PDE_DATA(inode);
- if (!dp->write_proc)
+ if (!ppde->write)
return -EIO;
- return dp->write_proc(file, buffer, count, dp->data);
-#else
- PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *)PDE_DATA(inode);
- PVR_UNREFERENCED_PARAMETER(ppos);
- if (!data->write_proc)
- return -EIO;
- return data->write_proc(file, buffer, count, data);
-#endif
+ return ppde->write(file, buffer, count, ppde->data);
}
@@ -329,10 +276,10 @@ static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
*****************************************************************************/
static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
{
- PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
- if(handlers->startstop != NULL)
- handlers->startstop(proc_seq_file, IMG_TRUE);
- return handlers->off2element(proc_seq_file, *pos);
+ struct pvr_proc_dir_entry *ppde = (struct pvr_proc_dir_entry*)proc_seq_file->private;
+ if(ppde->startstop != NULL)
+ ppde->startstop(proc_seq_file, IMG_TRUE);
+ return ppde->off2element(proc_seq_file, *pos);
}
/*!
@@ -351,11 +298,11 @@ static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
*****************************************************************************/
static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
{
- PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ struct pvr_proc_dir_entry *ppde = (struct pvr_proc_dir_entry*)proc_seq_file->private;
PVR_UNREFERENCED_PARAMETER(v);
- if(handlers->startstop != NULL)
- handlers->startstop(proc_seq_file, IMG_FALSE);
+ if(ppde->startstop != NULL)
+ ppde->startstop(proc_seq_file, IMG_FALSE);
}
/*!
@@ -379,11 +326,11 @@ static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
*****************************************************************************/
static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
{
- PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
+ struct pvr_proc_dir_entry *ppde = (struct pvr_proc_dir_entry*)proc_seq_file->private;
(*pos)++;
- if( handlers->next != NULL)
- return handlers->next( proc_seq_file, v, *pos );
- return handlers->off2element(proc_seq_file, *pos);
+ if(ppde->next != NULL)
+ return ppde->next( proc_seq_file, v, *pos );
+ return ppde->off2element(proc_seq_file, *pos);
}
/*!
@@ -405,9 +352,9 @@ static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t
*****************************************************************************/
static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
{
- PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
- handlers->show( proc_seq_file,v );
- return 0;
+ struct pvr_proc_dir_entry *ppde = (struct pvr_proc_dir_entry*)proc_seq_file->private;
+ ppde->show( proc_seq_file,v );
+ return 0;
}
@@ -444,90 +391,60 @@ static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
*****************************************************************************/
-static struct proc_dir_entry* CreateProcEntryInDirSeq(
- struct proc_dir_entry *pdir,
- const IMG_CHAR * name,
- IMG_VOID* data,
- pvr_next_proc_seq_t next_handler,
- pvr_show_proc_seq_t show_handler,
- pvr_off2element_proc_seq_t off2element_handler,
- pvr_startstop_proc_seq_t startstop_handler,
- write_proc_t whandler
- )
+static struct pvr_proc_dir_entry* CreateProcEntryInDirSeq(struct proc_dir_entry *pdir,
+ const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ pvr_proc_write_t whandler)
{
- struct proc_dir_entry * file;
+ struct pvr_proc_dir_entry * ppde;
mode_t mode;
- if (!dir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
- return NULL;
- }
+ if (!dir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
+ return NULL;
+ }
mode = S_IFREG;
- if (show_handler)
- {
+ if (show_handler)
+ {
mode |= S_IRUGO;
- }
+ }
- if (whandler)
- {
+ if (whandler)
+ {
mode |= S_IWUSR;
- }
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- file=create_proc_entry(name, mode, pdir);
-
- if (file)
- {
- PVR_PROC_SEQ_HANDLERS *seq_handlers;
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
- file->owner = THIS_MODULE;
-#endif
+ }
- file->proc_fops = &pvr_proc_operations;
- file->write_proc = whandler;
+ ppde = kmalloc(sizeof(struct pvr_proc_dir_entry), GFP_KERNEL);
+ if (!ppde)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
+ return NULL;
+ }
+
+ ppde->next = next_handler;
+ ppde->show = show_handler;
+ ppde->off2element = off2element_handler;
+ ppde->startstop = startstop_handler;
+ ppde->write = whandler;
+ ppde->data = data;
- /* Pass the handlers */
- file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
- if(file->data)
- {
- seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
- seq_handlers->next = next_handler;
- seq_handlers->show = show_handler;
- seq_handlers->off2element = off2element_handler;
- seq_handlers->startstop = startstop_handler;
- seq_handlers->data = data;
+ ppde->pde=proc_create_data(name, mode, pdir, &pvr_proc_operations, ppde);
- return file;
- }
- }
-#else
- /* Pass the handlers */
+ if (!ppde->pde)
{
- PVR_PROC_SEQ_HANDLERS *seq_handlers;
- seq_handlers = (PVR_PROC_SEQ_HANDLERS *)kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
- if (seq_handlers)
- {
- seq_handlers->next = next_handler;
- seq_handlers->show = show_handler;
- seq_handlers->off2element = off2element_handler;
- seq_handlers->startstop = startstop_handler;
- seq_handlers->data = data;
- seq_handlers->write_proc = whandler;
- file = proc_create_data(name, mode, pdir, &pvr_proc_operations,seq_handlers);
- if (file)
- return file;
- kfree(seq_handlers);
- }
+ PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: proc_create_data failed", PVRProcDirRoot, name));
+ kfree(ppde);
+ return NULL;
}
-#endif
-
- PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
- return NULL;
+ return ppde;
}
@@ -560,22 +477,20 @@ static struct proc_dir_entry* CreateProcEntryInDirSeq(
@Return Ptr to proc entry , 0 for failure
*****************************************************************************/
-struct proc_dir_entry* CreateProcReadEntrySeq (
- const IMG_CHAR * name,
- IMG_VOID* data,
- pvr_next_proc_seq_t next_handler,
- pvr_show_proc_seq_t show_handler,
- pvr_off2element_proc_seq_t off2element_handler,
- pvr_startstop_proc_seq_t startstop_handler
- )
+struct pvr_proc_dir_entry* CreateProcReadEntrySeq (const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler)
{
return CreateProcEntrySeq(name,
- data,
- next_handler,
- show_handler,
- off2element_handler,
- startstop_handler,
- NULL);
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ NULL);
}
/*!
@@ -612,26 +527,22 @@ struct proc_dir_entry* CreateProcReadEntrySeq (
@Return Ptr to proc entry , 0 for failure
*****************************************************************************/
-struct proc_dir_entry* CreateProcEntrySeq (
- const IMG_CHAR * name,
- IMG_VOID* data,
- pvr_next_proc_seq_t next_handler,
- pvr_show_proc_seq_t show_handler,
- pvr_off2element_proc_seq_t off2element_handler,
- pvr_startstop_proc_seq_t startstop_handler,
- write_proc_t whandler
- )
+struct pvr_proc_dir_entry* CreateProcEntrySeq (const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ pvr_proc_write_t whandler)
{
- return CreateProcEntryInDirSeq(
- dir,
- name,
- data,
- next_handler,
- show_handler,
- off2element_handler,
- startstop_handler,
- whandler
- );
+ return CreateProcEntryInDirSeq(dir,
+ name,
+ data,
+ next_handler,
+ show_handler,
+ off2element_handler,
+ startstop_handler,
+ whandler);
}
@@ -667,15 +578,13 @@ struct proc_dir_entry* CreateProcEntrySeq (
@Return Ptr to proc entry , 0 for failure
*****************************************************************************/
-struct proc_dir_entry* CreatePerProcessProcEntrySeq (
- const IMG_CHAR * name,
- IMG_VOID* data,
- pvr_next_proc_seq_t next_handler,
- pvr_show_proc_seq_t show_handler,
- pvr_off2element_proc_seq_t off2element_handler,
- pvr_startstop_proc_seq_t startstop_handler,
- write_proc_t whandler
- )
+struct pvr_proc_dir_entry* CreatePerProcessProcEntrySeq (const IMG_CHAR * name,
+ IMG_VOID* data,
+ pvr_next_proc_seq_t next_handler,
+ pvr_show_proc_seq_t show_handler,
+ pvr_off2element_proc_seq_t off2element_handler,
+ pvr_startstop_proc_seq_t startstop_handler,
+ pvr_proc_write_t whandler)
{
PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
IMG_UINT32 ui32PID;
@@ -692,444 +601,35 @@ struct proc_dir_entry* CreatePerProcessProcEntrySeq (
if (!psPerProc)
{
PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
-
return NULL;
}
if (!psPerProc->psProcDir)
{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- IMG_CHAR dirname_buffer[256];
- IMG_CHAR dirname[256];
- IMG_INT ret;
- const IMG_CHAR *proc_basename = dirname_buffer;
- dirname_buffer[255] = dirname[255] = '\0';
-
- OSGetProcCmdline(ui32PID, dirname_buffer, sizeof(dirname_buffer));
- PVR_DPF((PVR_DBG_MESSAGE, "Command Line of the process with ID %u is %s", ui32PID, dirname_buffer));
-
- proc_basename = OSGetPathBaseName(dirname_buffer, sizeof(dirname_buffer));
- PVR_DPF((PVR_DBG_MESSAGE, "Base Name of the process with ID %u is %s\n", ui32PID, proc_basename));
-
- ret = snprintf(dirname, sizeof(dirname), "%u-%s", ui32PID, proc_basename);
- PVR_DPF((PVR_DBG_MESSAGE, "Creating a new process entry for %s with ID %u\n", proc_basename, ui32PID));
-#else
IMG_CHAR dirname[16];
IMG_INT ret;
ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
-#endif
-
- if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
- return NULL;
- }
- else
- {
- psPerProc->psProcDir = proc_mkdir(dirname, dir);
- if (!psPerProc->psProcDir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
- PVRProcDirRoot, ui32PID));
- return NULL;
- }
- }
- }
-
- return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
- show_handler,off2element_handler,startstop_handler,whandler);
-}
-
-
-/*!
-******************************************************************************
-
- @Function : RemoveProcEntrySeq
-
- @Description
-
- Remove a single node (created using *Seq function) under /proc/pvr.
-
- @Input proc_entry : structure returned by Create function.
- @Return nothing
-
-*****************************************************************************/
-IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
-{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- if (dir)
- {
- void* data = proc_entry->data ;
- PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
-
- remove_proc_entry(proc_entry->name, dir);
- if( data)
- kfree( data );
-
- }
-#endif
-}
-
-/*!
-******************************************************************************
-
- @Function : RemovePerProcessProcEntry Seq
-
- @Description
-
- Remove a single node under the per process proc directory (created by *Seq function).
-
- Remove a single node (created using *Seq function) under /proc/pvr.
-
- @Input proc_entry : structure returned by Create function.
-
- @Return nothing
-
-*****************************************************************************/
-IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
-{
- PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
-
- psPerProc = LinuxTerminatingProcessPrivateData();
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- if (!psPerProc)
- {
- psPerProc = PVRSRVFindPerProcessPrivateData();
- if (!psPerProc)
+ if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
{
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
- "remove %s, no per process data", proc_entry->name));
- return;
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
+ return NULL;
}
- }
-
- if (psPerProc->psProcDir)
- {
- void* data = proc_entry->data ;
- PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
-
- remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
- if(data)
- kfree( data );
- }
-#endif
-}
-
-/*!
-******************************************************************************
-
- @Function : pvr_read_proc_vm
-
- @Description
-
- When the user accesses the proc filesystem entry for the device, we are
- called here to create the content for the 'file'. We can print anything we
- want here. If the info we want to return is too big for one page ('count'
- chars), we return successive chunks on each call. For a number of ways of
- achieving this, refer to proc_file_read() in linux/fs/proc/generic.c.
-
- Here, as we are accessing lists of information, we output '1' in '*start' to
- instruct proc to advance 'off' by 1 on each call. The number of chars placed
- in the buffer is returned. Multiple calls are made here by the proc
- filesystem until we set *eof. We can return zero without setting eof to
- instruct proc to flush 'page' (causing it to be printed) if there is not
- enough space left (eg for a complete line).
-
- @Input page : where to write the output
-
- @Input start : memory location into which should be written next offset
- to read from.
-
- @Input off : the offset into the /proc file being read
-
- @Input count : the size of the buffer 'page'
-
- @Input eof : memory location into which 1 should be written when at EOF
-
- @Input data : data specific to this /proc file entry
-
- @Return : length of string written to page
-
-*****************************************************************************/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
-static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
- IMG_INT count, IMG_INT *eof, IMG_VOID *data)
-{
- /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */
- pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
-
- off_t len = pprn (page, (size_t)count, off);
-
- if (len == END_OF_FILE)
- {
- len = 0;
- *eof = 1;
- }
- else if (!len) /* not enough space in the buffer */
- {
- *start = (IMG_CHAR *) 0; /* don't advance the offset */
- }
- else
- {
- *start = (IMG_CHAR *) 1;
- }
-
- return len;
-}
-#else
-static ssize_t pvr_proc_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- PVR_PROC_SEQ_HANDLERS *data = (PVR_PROC_SEQ_HANDLERS *)PDE_DATA(inode);
- PVR_UNREFERENCED_PARAMETER(ppos);
- if (!data->read_proc)
- return -EIO;
- return -EIO;
-
-}
-#endif
-
-
-/*!
-******************************************************************************
-
- @Function : CreateProcEntryInDir
-
- @Description
-
- Create a file under the given directory. These dynamic files can be used at
- runtime to get or set information about the device.
-
- @Input pdir : parent directory
-
- @Input name : the name of the file to create
-
- @Input rhandler : the function to supply the content
-
- @Input whandler : the function to interpret writes from the user
-
- @Return success code : 0 or -errno.
-
-*****************************************************************************/
-static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
-{
- struct proc_dir_entry * file;
- mode_t mode;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
- PVR_PROC_SEQ_HANDLERS *handlers;
-#endif
-
- if (!pdir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
-
- return -ENOMEM;
- }
-
- mode = S_IFREG;
-
- if (rhandler)
- {
- mode |= S_IRUGO;
- }
-
- if (whandler)
- {
- mode |= S_IWUSR;
- }
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- file = create_proc_entry(name, mode, pdir);
-
- if (file)
- {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
- file->owner = THIS_MODULE;
-#endif
- file->read_proc = rhandler;
- file->write_proc = whandler;
- file->data = data;
-
- PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
-
- return 0;
- }
-
- PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
-#else
- handlers = (PVR_PROC_SEQ_HANDLERS *)kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
- if (handlers)
- {
- handlers->data = data;
- handlers->read_proc = rhandler;
- handlers->write_proc = whandler;
- file = proc_create_data(name, mode, pdir, &pvr_read_proc_operations, handlers);
- if (file)
- {
- PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, "?" /*pdir->name*/));
- return 0;
- }
- kfree (handlers);
+ else
+ {
+ psPerProc->psProcDir = proc_mkdir(dirname, dir);
+ if (!psPerProc->psProcDir)
+ {
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
+ PVRProcDirRoot, ui32PID));
+ return NULL;
+ }
}
- PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, "?" /*pdir->name*/));
-#endif
-
- return -ENOMEM;
-}
-
-
-/*!
-******************************************************************************
-
- @Function : CreateProcEntry
-
- @Description
-
- Create a file under /proc/pvr. These dynamic files can be used at runtime
- to get or set information about the device.
-
- This interface is fuller than CreateProcReadEntry, and supports write access;
- it is really just a wrapper for the native linux functions.
-
- @Input name : the name of the file to create under /proc/pvr
-
- @Input rhandler : the function to supply the content
-
- @Input whandler : the function to interpret writes from the user
-
- @Return success code : 0 or -errno.
-
-*****************************************************************************/
-IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
-{
- return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
-}
-
-
-/*!
-******************************************************************************
-
- @Function : CreatePerProcessProcEntry
-
- @Description
-
- Create a file under /proc/pvr/<current process ID>. Apart from the
- directory where the file is created, this works the same way as
- CreateProcEntry.
-
- @Input name : the name of the file to create under the per process /proc directory
-
- @Input rhandler : the function to supply the content
-
- @Input whandler : the function to interpret writes from the user
-
- @Return success code : 0 or -errno.
-
-*****************************************************************************/
-IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
-{
- PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
- IMG_UINT32 ui32PID;
-
- if (!dir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
-
- return -ENOMEM;
- }
-
- ui32PID = OSGetCurrentProcessIDKM();
-
- psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
- if (!psPerProc)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
-
- return -ENOMEM;
- }
-
- if (!psPerProc->psProcDir)
- {
- IMG_CHAR dirname[16];
- IMG_INT ret;
-
- ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
-
- if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
-
- return -ENOMEM;
- }
- else
- {
- psPerProc->psProcDir = proc_mkdir(dirname, dir);
- if (!psPerProc->psProcDir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
-
- return -ENOMEM;
- }
- }
- }
-
- return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
-}
-
-
-/*!
-******************************************************************************
-
- @Function : CreateProcReadEntry
-
- @Description
-
- Create a file under /proc/pvr. These dynamic files can be used at runtime
- to get information about the device. Creation WILL fail if proc support is
- not compiled into the kernel. That said, the Linux kernel is not even happy
- to build without /proc support these days.
-
- @Input name : the name of the file to create
-
- @Input handler : the function to call to provide the content
-
- @Return 0 for success, -errno for failure
-
-*****************************************************************************/
-IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
-{
- struct proc_dir_entry * file;
-
- if (!dir)
- {
- PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
-
- return -ENOMEM;
}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- /* PRQA S 0307 1 */ /* ignore warning about casting to different pointer type */
- file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
-
- if (file)
- {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
- file->owner = THIS_MODULE;
-#endif
- return 0;
- }
-#else
- /* use file_ops pointing to pvr_read_proc */
- file = proc_create_data(name, S_IFREG | S_IRUGO, dir, &pvr_read_proc_operations, handler);
- if (file)
- return 0;
-#endif
-
- PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
-
- return -ENOMEM;
+ return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
+ show_handler,off2element_handler,startstop_handler,whandler);
}
@@ -1161,11 +661,17 @@ IMG_INT CreateProcEntries(IMG_VOID)
return -ENOMEM;
}
+#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
+#endif
g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
- if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
+ if(!g_pProcVersion || !g_pProcSysNodes
+#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
+ || !g_pProcQueue
+#endif
+ )
{
PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
@@ -1207,44 +713,45 @@ IMG_INT CreateProcEntries(IMG_VOID)
/*!
******************************************************************************
- @Function : RemoveProcEntry
+ @Function : RemoveProcEntrySeq
@Description
- Remove a single node under /proc/pvr.
+ Remove a single node (created using *Seq function) under /proc/pvr.
- @Input name : the name of the node to remove
+ @Input proc_entry : structure returned by Create function.
@Return nothing
*****************************************************************************/
-IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
+IMG_VOID RemoveProcEntrySeq(struct pvr_proc_dir_entry* ppde)
{
- if (dir)
- {
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- remove_proc_entry(name, dir);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+ remove_proc_entry(ppde->pde->name, dir);
+#else
+ proc_remove(ppde->pde);
#endif
- PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
- }
+ kfree(ppde);
}
/*!
******************************************************************************
- @Function : RemovePerProcessProcEntry
+ @Function : RemovePerProcessProcEntrySeq
@Description
- Remove a single node under the per process proc directory.
+ Remove a single node under the per process proc directory (created by *Seq function).
- @Input name : the name of the node to remove
+ Remove a single node (created using *Seq function) under /proc/pvr.
+
+ @Input proc_entry : structure returned by Create function.
@Return nothing
*****************************************************************************/
-IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
+IMG_VOID RemovePerProcessProcEntrySeq(struct pvr_proc_dir_entry* ppde)
{
PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
@@ -1254,19 +761,44 @@ IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
psPerProc = PVRSRVFindPerProcessPrivateData();
if (!psPerProc)
{
- PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
- "remove %s, no per process data", name));
+ PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't remove proc entry, no per process data"));
return;
}
}
if (psPerProc->psProcDir)
{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
- remove_proc_entry(name, psPerProc->psProcDir);
-
- PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing per-process proc entry"));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+ remove_proc_entry(ppde->pde->name, psPerProc->psProcDir);
+#else
+ proc_remove(ppde->pde);
#endif
+ kfree(ppde);
+ }
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
+/*!
+******************************************************************************
+
+ @Function : RemoveProcEntry
+
+ @Description
+
+ Remove a single node under /proc/pvr.
+
+ @Input name : the name of the node to remove
+
+ @Return nothing
+
+*****************************************************************************/
+static IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
+{
+ if (dir)
+ {
+ remove_proc_entry(name, dir);
+ PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
}
}
@@ -1289,7 +821,6 @@ IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
{
if (psPerProc->psProcDir)
{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
while (psPerProc->psProcDir->subdir)
{
PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
@@ -1297,10 +828,14 @@ IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
RemoveProcEntry(psPerProc->psProcDir->subdir->name);
}
RemoveProcEntry(psPerProc->psProcDir->name);
-#endif
}
}
-
+#else
+IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
+{
+ proc_remove(psPerProc->psProcDir);
+}
+#endif
/*!
******************************************************************************
@@ -1318,7 +853,6 @@ IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
*****************************************************************************/
IMG_VOID RemoveProcEntries(IMG_VOID)
{
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0))
#ifdef DEBUG
RemoveProcEntrySeq( g_pProcDebugLevel );
#ifdef PVR_MANUAL_POWER_CONTROL
@@ -1326,21 +860,35 @@ IMG_VOID RemoveProcEntries(IMG_VOID)
#endif /* PVR_MANUAL_POWER_CONTROL */
#endif
+#if defined(SUPPORT_PVRSRV_DEVICE_CLASS)
RemoveProcEntrySeq(g_pProcQueue);
+#endif
RemoveProcEntrySeq(g_pProcVersion);
RemoveProcEntrySeq(g_pProcSysNodes);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
while (dir->subdir)
{
PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
RemoveProcEntry(dir->subdir->name);
}
-
remove_proc_entry(PVRProcDirRoot, NULL);
#else
proc_remove(dir);
#endif
+
+}
+
+/*************************************************************************/ /*!
+@Function PVRProcGetData
+@Description Extract data from PVR proc object.
+@Input pointer to pvr_proc_dir_entr object
+@Return pointer to data object passed in to Proc create function.
+*/ /**************************************************************************/
+void *PVRProcGetData(struct pvr_proc_dir_entry *ppde)
+{
+ return ppde->data;
}
/*****************************************************************************
@@ -1351,7 +899,7 @@ IMG_VOID RemoveProcEntries(IMG_VOID)
PARAMETERS : sfile - /proc seq_file
el - Element to print
*****************************************************************************/
-static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
+static void ProcSeqShowVersion(struct seq_file *sfile, void* el)
{
SYS_DATA *psSysData;
IMG_CHAR *pszSystemVersionString = "None";
@@ -1374,24 +922,6 @@ static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
}
-/*!
-******************************************************************************
-
- @Function procDumpSysNodes (plus deviceTypeToString and deviceClassToString)
-
- @Description
-
- Format the contents of /proc/pvr/nodes
-
- @Input buf : where to place format contents data.
-
- @Input size : the size of the buffer into which to place data
-
- @Input off : how far into the file we are.
-
- @Return amount of data placed in buffer, 0, or END_OF_FILE :
-
-******************************************************************************/
static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
{
switch (deviceType)