1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #ifndef AUTOCONF_INCLUDED
28 #include <linux/config.h>
31 #include <linux/init.h>
32 #include <linux/module.h>
33 #include <linux/version.h>
35 #include <linux/proc_fs.h>
37 #include "services_headers.h"
42 #include "pvr_debug.h"
43 #include "pvrversion.h"
47 int PVRDebugProcSetLevel(struct file *file, const char *buffer,
48 unsigned long count, void *data);
49 int PVRDebugProcGetLevel(char *page, char **start, off_t off, int count,
50 int *eof, void *data);
54 static struct proc_dir_entry *dir;
56 static off_t procDumpSysNodes(char *buf, size_t size, off_t off);
57 static off_t procDumpVersion(char *buf, size_t size, off_t off);
59 off_t printAppend(char *buffer, size_t size, off_t off, const char *format, ...)
62 int space = size - off;
67 n = vsnprintf(buffer + off, space, format, ap);
71 if (n > space || n < 0) {
78 static int pvr_read_proc(char *page, char **start, off_t off,
79 int count, int *eof, void *data)
81 pvr_read_proc_t *pprn = data;
83 off_t len = pprn(page, count, off);
85 if (len == END_OF_FILE) {
97 int CreateProcEntry(const char *name, read_proc_t rhandler,
98 write_proc_t whandler, void *data)
100 struct proc_dir_entry *file;
104 PVR_DPF((PVR_DBG_ERROR,
105 "CreateProcEntry: cannot make proc entry /proc/pvr/%s: no parent",
120 file = create_proc_entry(name, mode, dir);
123 file->owner = THIS_MODULE;
124 file->read_proc = rhandler;
125 file->write_proc = whandler;
128 PVR_DPF((PVR_DBG_MESSAGE, "Created /proc/pvr/%s", name));
133 PVR_DPF((PVR_DBG_ERROR,
134 "CreateProcEntry: cannot make proc entry /proc/pvr/%s: no memory",
140 int CreateProcReadEntry(const char *name, pvr_read_proc_t handler)
142 struct proc_dir_entry *file;
145 PVR_DPF((PVR_DBG_ERROR,
146 "CreateProcReadEntry: cannot make proc entry /proc/pvr/%s: no parent",
153 create_proc_read_entry(name, S_IFREG | S_IRUGO, dir, pvr_read_proc,
157 file->owner = THIS_MODULE;
162 PVR_DPF((PVR_DBG_ERROR,
163 "CreateProcReadEntry: cannot make proc entry /proc/pvr/%s: no memory",
169 int CreateProcEntries(void)
171 dir = proc_mkdir("pvr", NULL);
174 PVR_DPF((PVR_DBG_ERROR,
175 "CreateProcEntries: cannot make /proc/pvr directory"));
180 if (CreateProcReadEntry("queue", QueuePrintQueues) ||
181 CreateProcReadEntry("version", procDumpVersion) ||
182 CreateProcReadEntry("nodes", procDumpSysNodes)) {
183 PVR_DPF((PVR_DBG_ERROR,
184 "CreateProcEntries: couldn't make /proc/pvr files"));
190 ("debug_level", PVRDebugProcGetLevel, PVRDebugProcSetLevel, 0)) {
191 PVR_DPF((PVR_DBG_ERROR,
192 "CreateProcEntries: couldn't make /proc/pvr/debug_level"));
201 void RemoveProcEntry(const char *name)
204 remove_proc_entry(name, dir);
207 PVR_DPF((PVR_DBG_MESSAGE, "Removing /proc/pvr/%s", name));
210 void RemoveProcEntries(void)
213 RemoveProcEntry("debug_level");
215 RemoveProcEntry("queue");
216 RemoveProcEntry("nodes");
217 RemoveProcEntry("version");
219 while (dir->subdir) {
220 PVR_DPF((PVR_DBG_WARNING, "Belatedly removing /proc/pvr/%s",
223 RemoveProcEntry(dir->subdir->name);
226 remove_proc_entry("pvr", NULL);
229 static off_t procDumpVersion(char *buf, size_t size, off_t off)
234 return printAppend(buf, size, 0,
235 "Version %s (%s) %s\n",
237 PVR_BUILD_TYPE, PVR_BUILD_DIR);
240 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
241 return PVRSRV_ERROR_GENERIC;
245 IMG_CHAR *pszSystemVersionString = "None";
247 if (psSysData->pszVersionString) {
248 pszSystemVersionString = psSysData->pszVersionString;
251 if (strlen(pszSystemVersionString)
252 + strlen("System Version String: \n")
256 return printAppend(buf, size, 0,
257 "System Version String: %s\n",
258 pszSystemVersionString);
264 static const char *deviceTypeToString(PVRSRV_DEVICE_TYPE deviceType)
266 switch (deviceType) {
269 static char text[10];
271 sprintf(text, "?%x", deviceType);
278 static const char *deviceClassToString(PVRSRV_DEVICE_CLASS deviceClass)
280 switch (deviceClass) {
281 case PVRSRV_DEVICE_CLASS_3D:
285 case PVRSRV_DEVICE_CLASS_DISPLAY:
289 case PVRSRV_DEVICE_CLASS_BUFFER:
295 static char text[10];
297 sprintf(text, "?%x", deviceClass);
304 off_t procDumpSysNodes(char *buf, size_t size, off_t off)
307 PVRSRV_DEVICE_NODE *psDevNode;
315 return printAppend(buf, size, 0,
317 "Addr Type Class Index Ref pvDev Size Res\n");
320 if (SysAcquireData(&psSysData) != PVRSRV_OK) {
321 return PVRSRV_ERROR_GENERIC;
324 for (psDevNode = psSysData->psDeviceNodeList;
325 --off && psDevNode; psDevNode = psDevNode->psNext) ;
331 len = printAppend(buf, size, 0,
332 "%p %-8s %-8s %4d %2lu %p %3lu %p\n",
334 deviceTypeToString(psDevNode->sDevId.eDeviceType),
335 deviceClassToString(psDevNode->sDevId.eDeviceClass),
336 psDevNode->sDevId.eDeviceClass,
337 psDevNode->ui32RefCount,
339 psDevNode->ui32pvDeviceSize,
340 psDevNode->hResManContext);