aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/pvr/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/proc.c')
-rw-r--r--drivers/gpu/pvr/proc.c833
1 files changed, 833 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/proc.c b/drivers/gpu/pvr/proc.c
new file mode 100644
index 00000000000..74f313262b8
--- /dev/null
+++ b/drivers/gpu/pvr/proc.c
@@ -0,0 +1,833 @@
1/**********************************************************************
2 *
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful but, except
10 * as otherwise stated in writing, without any warranty; without even the
11 * implied warranty of merchantability or fitness for a particular purpose.
12 * See the GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
24 *
25 ******************************************************************************/
26
27#ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
29#endif
30
31#include <linux/init.h>
32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/fs.h>
35#include <linux/proc_fs.h>
36#include <linux/seq_file.h>
37
38#include "services_headers.h"
39
40#include "queue.h"
41#include "resman.h"
42#include "pvrmmap.h"
43#include "pvr_debug.h"
44#include "pvrversion.h"
45#include "proc.h"
46#include "perproc.h"
47#include "env_perproc.h"
48#include "linkage.h"
49
50#include "lists.h"
51
52static struct proc_dir_entry * dir;
53
54static const IMG_CHAR PVRProcDirRoot[] = "pvr";
55
56static IMG_INT pvr_proc_open(struct inode *inode,struct file *file);
57static void *pvr_proc_seq_start (struct seq_file *m, loff_t *pos);
58static void pvr_proc_seq_stop (struct seq_file *m, void *v);
59static void *pvr_proc_seq_next (struct seq_file *m, void *v, loff_t *pos);
60static int pvr_proc_seq_show (struct seq_file *m, void *v);
61static ssize_t pvr_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos);
62
63static struct file_operations pvr_proc_operations =
64{
65 .open = pvr_proc_open,
66 .read = seq_read,
67 .write = pvr_proc_write,
68 .llseek = seq_lseek,
69 .release = seq_release,
70};
71
72static struct seq_operations pvr_proc_seq_operations =
73{
74 .start = pvr_proc_seq_start,
75 .next = pvr_proc_seq_next,
76 .stop = pvr_proc_seq_stop,
77 .show = pvr_proc_seq_show,
78};
79
80static struct proc_dir_entry* g_pProcQueue;
81static struct proc_dir_entry* g_pProcVersion;
82static struct proc_dir_entry* g_pProcSysNodes;
83
84#ifdef DEBUG
85static struct proc_dir_entry* g_pProcDebugLevel;
86#endif
87
88#ifdef PVR_MANUAL_POWER_CONTROL
89static struct proc_dir_entry* g_pProcPowerLevel;
90#endif
91
92
93static void ProcSeqShowVersion(struct seq_file *sfile,void* el);
94
95static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el);
96static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off);
97
98off_t printAppend(IMG_CHAR * buffer, size_t size, off_t off, const IMG_CHAR * format, ...)
99{
100 IMG_INT n;
101 size_t space = size - (size_t)off;
102 va_list ap;
103
104 va_start (ap, format);
105
106 n = vsnprintf (buffer+off, space, format, ap);
107
108 va_end (ap);
109
110 if (n >= (IMG_INT)space || n < 0)
111 {
112
113 buffer[size - 1] = 0;
114 return (off_t)(size - 1);
115 }
116 else
117 {
118 return (off + (off_t)n);
119 }
120}
121
122
123void* ProcSeq1ElementOff2Element(struct seq_file *sfile, loff_t off)
124{
125 PVR_UNREFERENCED_PARAMETER(sfile);
126
127 if(!off)
128 return (void*)2;
129 return NULL;
130}
131
132
133void* ProcSeq1ElementHeaderOff2Element(struct seq_file *sfile, loff_t off)
134{
135 PVR_UNREFERENCED_PARAMETER(sfile);
136
137 if(!off)
138 {
139 return PVR_PROC_SEQ_START_TOKEN;
140 }
141
142
143 if(off == 1)
144 return (void*)2;
145
146 return NULL;
147}
148
149
150static IMG_INT pvr_proc_open(struct inode *inode,struct file *file)
151{
152 IMG_INT ret = seq_open(file, &pvr_proc_seq_operations);
153
154 struct seq_file *seq = (struct seq_file*)file->private_data;
155 struct proc_dir_entry* pvr_proc_entry = PDE(inode);
156
157
158 seq->private = pvr_proc_entry->data;
159 return ret;
160}
161
162static ssize_t pvr_proc_write(struct file *file, const char __user *buffer,
163 size_t count, loff_t *ppos)
164{
165 struct inode *inode = file->f_path.dentry->d_inode;
166 struct proc_dir_entry * dp;
167
168 PVR_UNREFERENCED_PARAMETER(ppos);
169 dp = PDE(inode);
170
171 if (!dp->write_proc)
172 return -EIO;
173
174 return dp->write_proc(file, buffer, count, dp->data);
175}
176
177
178static void *pvr_proc_seq_start (struct seq_file *proc_seq_file, loff_t *pos)
179{
180 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
181 if(handlers->startstop != NULL)
182 handlers->startstop(proc_seq_file, IMG_TRUE);
183 return handlers->off2element(proc_seq_file, *pos);
184}
185
186static void pvr_proc_seq_stop (struct seq_file *proc_seq_file, void *v)
187{
188 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
189 PVR_UNREFERENCED_PARAMETER(v);
190
191 if(handlers->startstop != NULL)
192 handlers->startstop(proc_seq_file, IMG_FALSE);
193}
194
195static void *pvr_proc_seq_next (struct seq_file *proc_seq_file, void *v, loff_t *pos)
196{
197 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
198 (*pos)++;
199 if( handlers->next != NULL)
200 return handlers->next( proc_seq_file, v, *pos );
201 return handlers->off2element(proc_seq_file, *pos);
202}
203
204static int pvr_proc_seq_show (struct seq_file *proc_seq_file, void *v)
205{
206 PVR_PROC_SEQ_HANDLERS *handlers = (PVR_PROC_SEQ_HANDLERS*)proc_seq_file->private;
207 handlers->show( proc_seq_file,v );
208 return 0;
209}
210
211
212
213static struct proc_dir_entry* CreateProcEntryInDirSeq(
214 struct proc_dir_entry *pdir,
215 const IMG_CHAR * name,
216 IMG_VOID* data,
217 pvr_next_proc_seq_t next_handler,
218 pvr_show_proc_seq_t show_handler,
219 pvr_off2element_proc_seq_t off2element_handler,
220 pvr_startstop_proc_seq_t startstop_handler,
221 write_proc_t whandler
222 )
223{
224
225 struct proc_dir_entry * file;
226 mode_t mode;
227
228 if (!dir)
229 {
230 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
231 return NULL;
232 }
233
234 mode = S_IFREG;
235
236 if (show_handler)
237 {
238 mode |= S_IRUGO;
239 }
240
241 if (whandler)
242 {
243 mode |= S_IWUSR;
244 }
245
246 file=create_proc_entry(name, mode, pdir);
247
248 if (file)
249 {
250 PVR_PROC_SEQ_HANDLERS *seq_handlers;
251
252#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
253 file->owner = THIS_MODULE;
254#endif
255
256 file->proc_fops = &pvr_proc_operations;
257 file->write_proc = whandler;
258
259
260 file->data = kmalloc(sizeof(PVR_PROC_SEQ_HANDLERS), GFP_KERNEL);
261 if(file->data)
262 {
263 seq_handlers = (PVR_PROC_SEQ_HANDLERS*)file->data;
264 seq_handlers->next = next_handler;
265 seq_handlers->show = show_handler;
266 seq_handlers->off2element = off2element_handler;
267 seq_handlers->startstop = startstop_handler;
268 seq_handlers->data = data;
269
270 return file;
271 }
272 }
273
274 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDirSeq: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
275 return NULL;
276}
277
278
279struct proc_dir_entry* CreateProcReadEntrySeq (
280 const IMG_CHAR * name,
281 IMG_VOID* data,
282 pvr_next_proc_seq_t next_handler,
283 pvr_show_proc_seq_t show_handler,
284 pvr_off2element_proc_seq_t off2element_handler,
285 pvr_startstop_proc_seq_t startstop_handler
286 )
287{
288 return CreateProcEntrySeq(name,
289 data,
290 next_handler,
291 show_handler,
292 off2element_handler,
293 startstop_handler,
294 NULL);
295}
296
297struct proc_dir_entry* CreateProcEntrySeq (
298 const IMG_CHAR * name,
299 IMG_VOID* data,
300 pvr_next_proc_seq_t next_handler,
301 pvr_show_proc_seq_t show_handler,
302 pvr_off2element_proc_seq_t off2element_handler,
303 pvr_startstop_proc_seq_t startstop_handler,
304 write_proc_t whandler
305 )
306{
307 return CreateProcEntryInDirSeq(
308 dir,
309 name,
310 data,
311 next_handler,
312 show_handler,
313 off2element_handler,
314 startstop_handler,
315 whandler
316 );
317}
318
319
320
321struct proc_dir_entry* CreatePerProcessProcEntrySeq (
322 const IMG_CHAR * name,
323 IMG_VOID* data,
324 pvr_next_proc_seq_t next_handler,
325 pvr_show_proc_seq_t show_handler,
326 pvr_off2element_proc_seq_t off2element_handler,
327 pvr_startstop_proc_seq_t startstop_handler,
328 write_proc_t whandler
329 )
330{
331 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
332 IMG_UINT32 ui32PID;
333
334 if (!dir)
335 {
336 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: /proc/%s doesn't exist", PVRProcDirRoot));
337 return NULL;
338 }
339
340 ui32PID = OSGetCurrentProcessIDKM();
341
342 psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
343 if (!psPerProc)
344 {
345 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntrySeq: no per process data"));
346
347 return NULL;
348 }
349
350 if (!psPerProc->psProcDir)
351 {
352 IMG_CHAR dirname[16];
353 IMG_INT ret;
354
355 ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
356
357 if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
358 {
359 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
360 return NULL;
361 }
362 else
363 {
364 psPerProc->psProcDir = proc_mkdir(dirname, dir);
365 if (!psPerProc->psProcDir)
366 {
367 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u",
368 PVRProcDirRoot, ui32PID));
369 return NULL;
370 }
371 }
372 }
373
374 return CreateProcEntryInDirSeq(psPerProc->psProcDir, name, data, next_handler,
375 show_handler,off2element_handler,startstop_handler,whandler);
376}
377
378
379IMG_VOID RemoveProcEntrySeq( struct proc_dir_entry* proc_entry )
380{
381 if (dir)
382 {
383 void* data = proc_entry->data ;
384 PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, proc_entry->name));
385
386 remove_proc_entry(proc_entry->name, dir);
387 if( data)
388 kfree( data );
389
390 }
391}
392
393IMG_VOID RemovePerProcessProcEntrySeq(struct proc_dir_entry* proc_entry)
394{
395 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
396
397 psPerProc = LinuxTerminatingProcessPrivateData();
398 if (!psPerProc)
399 {
400 psPerProc = PVRSRVFindPerProcessPrivateData();
401 if (!psPerProc)
402 {
403 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
404 "remove %s, no per process data", proc_entry->name));
405 return;
406 }
407 }
408
409 if (psPerProc->psProcDir)
410 {
411 void* data = proc_entry->data ;
412 PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", proc_entry->name, psPerProc->psProcDir->name));
413
414 remove_proc_entry(proc_entry->name, psPerProc->psProcDir);
415 if(data)
416 kfree( data );
417 }
418}
419
420static IMG_INT pvr_read_proc(IMG_CHAR *page, IMG_CHAR **start, off_t off,
421 IMG_INT count, IMG_INT *eof, IMG_VOID *data)
422{
423
424 pvr_read_proc_t *pprn = (pvr_read_proc_t *)data;
425
426 off_t len = pprn (page, (size_t)count, off);
427
428 if (len == END_OF_FILE)
429 {
430 len = 0;
431 *eof = 1;
432 }
433 else if (!len)
434 {
435 *start = (IMG_CHAR *) 0;
436 }
437 else
438 {
439 *start = (IMG_CHAR *) 1;
440 }
441
442 return len;
443}
444
445
446static IMG_INT CreateProcEntryInDir(struct proc_dir_entry *pdir, const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
447{
448 struct proc_dir_entry * file;
449 mode_t mode;
450
451 if (!pdir)
452 {
453 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntryInDir: parent directory doesn't exist"));
454
455 return -ENOMEM;
456 }
457
458 mode = S_IFREG;
459
460 if (rhandler)
461 {
462 mode |= S_IRUGO;
463 }
464
465 if (whandler)
466 {
467 mode |= S_IWUSR;
468 }
469
470 file = create_proc_entry(name, mode, pdir);
471
472 if (file)
473 {
474#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
475 file->owner = THIS_MODULE;
476#endif
477 file->read_proc = rhandler;
478 file->write_proc = whandler;
479 file->data = data;
480
481 PVR_DPF((PVR_DBG_MESSAGE, "Created proc entry %s in %s", name, pdir->name));
482
483 return 0;
484 }
485
486 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntry: cannot create proc entry %s in %s", name, pdir->name));
487
488 return -ENOMEM;
489}
490
491
492IMG_INT CreateProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
493{
494 return CreateProcEntryInDir(dir, name, rhandler, whandler, data);
495}
496
497
498IMG_INT CreatePerProcessProcEntry(const IMG_CHAR * name, read_proc_t rhandler, write_proc_t whandler, IMG_VOID *data)
499{
500 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
501 IMG_UINT32 ui32PID;
502
503 if (!dir)
504 {
505 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: /proc/%s doesn't exist", PVRProcDirRoot));
506
507 return -ENOMEM;
508 }
509
510 ui32PID = OSGetCurrentProcessIDKM();
511
512 psPerProc = PVRSRVPerProcessPrivateData(ui32PID);
513 if (!psPerProc)
514 {
515 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: no per process data"));
516
517 return -ENOMEM;
518 }
519
520 if (!psPerProc->psProcDir)
521 {
522 IMG_CHAR dirname[16];
523 IMG_INT ret;
524
525 ret = snprintf(dirname, sizeof(dirname), "%u", ui32PID);
526
527 if (ret <=0 || ret >= (IMG_INT)sizeof(dirname))
528 {
529 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't generate per process proc directory name \"%u\"", ui32PID));
530
531 return -ENOMEM;
532 }
533 else
534 {
535 psPerProc->psProcDir = proc_mkdir(dirname, dir);
536 if (!psPerProc->psProcDir)
537 {
538 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: couldn't create per process proc directory /proc/%s/%u", PVRProcDirRoot, ui32PID));
539
540 return -ENOMEM;
541 }
542 }
543 }
544
545 return CreateProcEntryInDir(psPerProc->psProcDir, name, rhandler, whandler, data);
546}
547
548
549IMG_INT CreateProcReadEntry(const IMG_CHAR * name, pvr_read_proc_t handler)
550{
551 struct proc_dir_entry * file;
552
553 if (!dir)
554 {
555 PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no parent", PVRProcDirRoot, name));
556
557 return -ENOMEM;
558 }
559
560
561 file = create_proc_read_entry (name, S_IFREG | S_IRUGO, dir, pvr_read_proc, (IMG_VOID *)handler);
562
563 if (file)
564 {
565#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30))
566 file->owner = THIS_MODULE;
567#endif
568 return 0;
569 }
570
571 PVR_DPF((PVR_DBG_ERROR, "CreateProcReadEntry: cannot make proc entry /proc/%s/%s: no memory", PVRProcDirRoot, name));
572
573 return -ENOMEM;
574}
575
576
577IMG_INT CreateProcEntries(IMG_VOID)
578{
579 dir = proc_mkdir (PVRProcDirRoot, NULL);
580
581 if (!dir)
582 {
583 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: cannot make /proc/%s directory", PVRProcDirRoot));
584
585 return -ENOMEM;
586 }
587
588 g_pProcQueue = CreateProcReadEntrySeq("queue", NULL, NULL, ProcSeqShowQueue, ProcSeqOff2ElementQueue, NULL);
589 g_pProcVersion = CreateProcReadEntrySeq("version", NULL, NULL, ProcSeqShowVersion, ProcSeq1ElementHeaderOff2Element, NULL);
590 g_pProcSysNodes = CreateProcReadEntrySeq("nodes", NULL, NULL, ProcSeqShowSysNodes, ProcSeqOff2ElementSysNodes, NULL);
591
592 if(!g_pProcQueue || !g_pProcVersion || !g_pProcSysNodes)
593 {
594 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s files", PVRProcDirRoot));
595
596 return -ENOMEM;
597 }
598
599
600#ifdef DEBUG
601
602 g_pProcDebugLevel = CreateProcEntrySeq("debug_level", NULL, NULL,
603 ProcSeqShowDebugLevel,
604 ProcSeq1ElementOff2Element, NULL,
605 (IMG_VOID*)PVRDebugProcSetLevel);
606 if(!g_pProcDebugLevel)
607 {
608 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/debug_level", PVRProcDirRoot));
609
610 return -ENOMEM;
611 }
612
613#ifdef PVR_MANUAL_POWER_CONTROL
614 g_pProcPowerLevel = CreateProcEntrySeq("power_control", NULL, NULL,
615 ProcSeqShowPowerLevel,
616 ProcSeq1ElementOff2Element, NULL,
617 PVRProcSetPowerLevel);
618 if(!g_pProcPowerLevel)
619 {
620 PVR_DPF((PVR_DBG_ERROR, "CreateProcEntries: couldn't make /proc/%s/power_control", PVRProcDirRoot));
621
622 return -ENOMEM;
623 }
624#endif
625#endif
626
627 return 0;
628}
629
630
631IMG_VOID RemoveProcEntry(const IMG_CHAR * name)
632{
633 if (dir)
634 {
635 remove_proc_entry(name, dir);
636 PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/%s/%s", PVRProcDirRoot, name));
637 }
638}
639
640
641IMG_VOID RemovePerProcessProcEntry(const IMG_CHAR *name)
642{
643 PVRSRV_ENV_PER_PROCESS_DATA *psPerProc;
644
645 psPerProc = LinuxTerminatingProcessPrivateData();
646 if (!psPerProc)
647 {
648 psPerProc = PVRSRVFindPerProcessPrivateData();
649 if (!psPerProc)
650 {
651 PVR_DPF((PVR_DBG_ERROR, "CreatePerProcessProcEntries: can't "
652 "remove %s, no per process data", name));
653 return;
654 }
655 }
656
657 if (psPerProc->psProcDir)
658 {
659 remove_proc_entry(name, psPerProc->psProcDir);
660
661 PVR_DPF((PVR_DBG_MESSAGE, "Removing proc entry %s from %s", name, psPerProc->psProcDir->name));
662 }
663}
664
665
666IMG_VOID RemovePerProcessProcDir(PVRSRV_ENV_PER_PROCESS_DATA *psPerProc)
667{
668 if (psPerProc->psProcDir)
669 {
670 while (psPerProc->psProcDir->subdir)
671 {
672 PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s/%s", PVRProcDirRoot, psPerProc->psProcDir->name, psPerProc->psProcDir->subdir->name));
673
674 RemoveProcEntry(psPerProc->psProcDir->subdir->name);
675 }
676 RemoveProcEntry(psPerProc->psProcDir->name);
677 }
678}
679
680IMG_VOID RemoveProcEntries(IMG_VOID)
681{
682#ifdef DEBUG
683 RemoveProcEntrySeq( g_pProcDebugLevel );
684#ifdef PVR_MANUAL_POWER_CONTROL
685 RemoveProcEntrySeq( g_pProcPowerLevel );
686#endif
687#endif
688
689 RemoveProcEntrySeq(g_pProcQueue);
690 RemoveProcEntrySeq(g_pProcVersion);
691 RemoveProcEntrySeq(g_pProcSysNodes);
692
693 while (dir->subdir)
694 {
695 PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/%s/%s", PVRProcDirRoot, dir->subdir->name));
696
697 RemoveProcEntry(dir->subdir->name);
698 }
699
700 remove_proc_entry(PVRProcDirRoot, NULL);
701}
702
703static void ProcSeqShowVersion(struct seq_file *sfile,void* el)
704{
705 SYS_DATA * psSysData;
706 IMG_CHAR *pszSystemVersionString = "None";
707
708 if(el == PVR_PROC_SEQ_START_TOKEN)
709 {
710 seq_printf( sfile,
711 "Version %s (%s) %s\n",
712 PVRVERSION_STRING,
713 PVR_BUILD_TYPE, PVR_BUILD_DIR);
714 return;
715 }
716
717 SysAcquireData(&psSysData);
718
719 if(psSysData->pszVersionString)
720 {
721 pszSystemVersionString = psSysData->pszVersionString;
722 }
723
724 seq_printf( sfile, "System Version String: %s\n", pszSystemVersionString);
725}
726
727static const IMG_CHAR *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
728{
729 switch (deviceType)
730 {
731 default:
732 {
733 static IMG_CHAR text[10];
734
735 sprintf(text, "?%x", (IMG_UINT)deviceType);
736
737 return text;
738 }
739 }
740}
741
742
743static const IMG_CHAR *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
744{
745 switch (deviceClass)
746 {
747 case PVRSRV_DEVICE_CLASS_3D:
748 {
749 return "3D";
750 }
751 case PVRSRV_DEVICE_CLASS_DISPLAY:
752 {
753 return "display";
754 }
755 case PVRSRV_DEVICE_CLASS_BUFFER:
756 {
757 return "buffer";
758 }
759 default:
760 {
761 static IMG_CHAR text[10];
762
763 sprintf(text, "?%x", (IMG_UINT)deviceClass);
764 return text;
765 }
766 }
767}
768
769static IMG_VOID* DecOffPsDev_AnyVaCb(PVRSRV_DEVICE_NODE *psNode, va_list va)
770{
771 off_t *pOff = va_arg(va, off_t*);
772 if (--(*pOff))
773 {
774 return IMG_NULL;
775 }
776 else
777 {
778 return psNode;
779 }
780}
781
782static void ProcSeqShowSysNodes(struct seq_file *sfile,void* el)
783{
784 SYS_DATA * psSysData;
785 PVRSRV_DEVICE_NODE *psDevNode = (PVRSRV_DEVICE_NODE*)el;
786
787 if(el == PVR_PROC_SEQ_START_TOKEN)
788 {
789 seq_printf( sfile,
790 "Registered nodes\n"
791 "Addr Type Class Index Ref pvDev Size Res\n");
792 return;
793 }
794
795 SysAcquireData(&psSysData);
796
797 seq_printf( sfile,
798 "%p %-8s %-8s %4d %2u %p %3u %p\n",
799 psDevNode,
800 deviceTypeToString(psDevNode->sDevId.eDeviceType),
801 deviceClassToString(psDevNode->sDevId.eDeviceClass),
802 psDevNode->sDevId.eDeviceClass,
803 psDevNode->ui32RefCount,
804 psDevNode->pvDevice,
805 psDevNode->ui32pvDeviceSize,
806 psDevNode->hResManContext);
807
808}
809
810static void* ProcSeqOff2ElementSysNodes(struct seq_file * sfile, loff_t off)
811{
812 SYS_DATA *psSysData;
813 PVRSRV_DEVICE_NODE *psDevNode;
814
815 PVR_UNREFERENCED_PARAMETER(sfile);
816
817 if(!off)
818 {
819 return PVR_PROC_SEQ_START_TOKEN;
820 }
821
822 SysAcquireData(&psSysData);
823
824
825 psDevNode = (PVRSRV_DEVICE_NODE*)
826 List_PVRSRV_DEVICE_NODE_Any_va(psSysData->psDeviceNodeList,
827 DecOffPsDev_AnyVaCb,
828 &off);
829
830
831 return (void*)psDevNode;
832}
833