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
******************************************************************************/
28
#ifndef AUTOCONF_INCLUDED
29
#include <linux/config.h>
33
#include <asm/uaccess.h>
34
#include <linux/kernel.h>
35
#include <linux/hardirq.h>
36
#include <linux/module.h>
37
#include <linux/spinlock.h>
38
#include <linux/tty.h>
40
#include "img_types.h"
41
#include "servicesext.h"
42
#include "pvr_debug.h"
47
#if defined(PVRSRV_NEED_PVR_DPF)
49
#define PVR_MAX_FILEPATH_LEN 256
51
static IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING;
55
#define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
57
static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
59
static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
61
static PVRSRV_LINUX_MUTEX gsDebugMutexNonIRQ;
63
static spinlock_t gsDebugLockIRQ = SPIN_LOCK_UNLOCKED;
65
#define USE_SPIN_LOCK (in_interrupt() || !preemptible())
67
static inline void GetBufferLock(unsigned long *pulLockFlags)
71
spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
75
LinuxLockMutex(&gsDebugMutexNonIRQ);
79
static inline void ReleaseBufferLock(unsigned long ulLockFlags)
83
spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
87
LinuxUnLockMutex(&gsDebugMutexNonIRQ);
91
static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
95
*ppszBuf = gszBufferIRQ;
96
*pui32BufSiz = sizeof(gszBufferIRQ);
100
*ppszBuf = gszBufferNonIRQ;
101
*pui32BufSiz = sizeof(gszBufferNonIRQ);
105
static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
108
IMG_UINT32 ui32Space;
111
ui32Used = strlen(pszBuf);
112
BUG_ON(ui32Used >= ui32BufSiz);
113
ui32Space = ui32BufSiz - ui32Used;
115
i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
116
pszBuf[ui32BufSiz - 1] = 0;
119
return (i32Len < 0 || i32Len >= ui32Space);
122
IMG_VOID PVRDPFInit(IMG_VOID)
124
LinuxInitMutex(&gsDebugMutexNonIRQ);
127
IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
130
unsigned long ulLockFlags = 0;
132
IMG_UINT32 ui32BufSiz;
134
SelectBuffer(&pszBuf, &ui32BufSiz);
136
va_start(vaArgs, pszFormat);
138
GetBufferLock(&ulLockFlags);
139
strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
141
if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
143
printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
147
printk(KERN_INFO "%s\n", pszBuf);
150
ReleaseBufferLock(ulLockFlags);
155
#if defined(PVRSRV_NEED_PVR_ASSERT)
157
IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
159
PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
165
#if defined(PVRSRV_NEED_PVR_TRACE)
167
IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
170
unsigned long ulLockFlags = 0;
172
IMG_UINT32 ui32BufSiz;
174
SelectBuffer(&pszBuf, &ui32BufSiz);
176
va_start(VArgs, pszFormat);
178
GetBufferLock(&ulLockFlags);
180
strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
182
if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
184
printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
188
printk(KERN_INFO "%s\n", pszBuf);
191
ReleaseBufferLock(ulLockFlags);
198
#if defined(PVRSRV_NEED_PVR_DPF)
200
static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
205
va_start (VArgs, pszFormat);
207
bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
214
IMG_VOID PVRSRVDebugPrintf (
215
IMG_UINT32 ui32DebugLevel,
216
const IMG_CHAR* pszFullFileName,
218
const IMG_CHAR* pszFormat,
222
IMG_BOOL bTrace, bDebug;
223
const IMG_CHAR *pszFileName = pszFullFileName;
224
IMG_CHAR *pszLeafName;
226
bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE;
227
bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel);
229
if (bTrace || bDebug)
232
unsigned long ulLockFlags = 0;
234
IMG_UINT32 ui32BufSiz;
236
SelectBuffer(&pszBuf, &ui32BufSiz);
238
va_start(vaArgs, pszFormat);
240
GetBufferLock(&ulLockFlags);
245
switch(ui32DebugLevel)
249
strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
254
strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
257
case DBGPRIV_WARNING:
259
strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
262
case DBGPRIV_MESSAGE:
264
strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
267
case DBGPRIV_VERBOSE:
269
strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
274
strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
281
strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
284
if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
286
printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
293
#ifdef DEBUG_LOG_PATH_TRUNCATE
295
static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
297
IMG_CHAR* pszTruncIter;
298
IMG_CHAR* pszTruncBackInter;
301
pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
304
strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
306
if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
307
IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
308
strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
311
pszTruncIter = szFileNameRewrite;
312
while(*pszTruncIter++ != 0)
314
IMG_CHAR* pszNextStartPoint;
317
!( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
318
( *(pszTruncIter-1) == '.') &&
319
( *(pszTruncIter-2) == '.') &&
320
( *(pszTruncIter-3) == '/') )
324
pszTruncBackInter = pszTruncIter - 3;
325
while(*(--pszTruncBackInter) != '/')
327
if(pszTruncBackInter <= szFileNameRewrite) break;
329
pszNextStartPoint = pszTruncBackInter;
332
while(*pszTruncIter != 0)
334
*pszTruncBackInter++ = *pszTruncIter++;
336
*pszTruncBackInter = 0;
339
pszTruncIter = pszNextStartPoint;
342
pszFileName = szFileNameRewrite;
344
if(*pszFileName == '/') pszFileName++;
348
pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
352
pszFileName = pszLeafName;
356
if (BAppend(pszBuf, ui32BufSiz, " [%lu, %s]", ui32Line, pszFileName))
358
printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
362
printk(KERN_INFO "%s\n", pszBuf);
367
printk(KERN_INFO "%s\n", pszBuf);
371
ReleaseBufferLock(ulLockFlags);
381
IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel)
383
printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(IMG_UINT)uDebugLevel);
385
gPVRDebugLevel = uDebugLevel;
388
IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
390
#define _PROC_SET_BUFFER_SZ 2
391
IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
393
if (count != _PROC_SET_BUFFER_SZ)
399
if (copy_from_user(data_buffer, buffer, count))
401
if (data_buffer[count - 1] != '\n')
403
PVRDebugSetLevel(data_buffer[0] - '0');
408
#ifdef PVR_PROC_USE_SEQ_FILE
409
void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
411
seq_printf(sfile, "%lu\n", gPVRDebugLevel);
415
IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
418
*start = (IMG_CHAR *)1;
419
return printAppend(page, count, 0, "%lu\n", gPVRDebugLevel);