1 /**********************************************************************
2 Copyright (c) Imagination Technologies Ltd.
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 ******************************************************************************/
25 #include <asm/uaccess.h>
26 #include <linux/kernel.h>
27 #include <linux/hardirq.h>
28 #include <linux/module.h>
29 #include <linux/spinlock.h>
30 #include <linux/tty.h>
32 #include "img_types.h"
33 #include "servicesext.h"
34 #include "pvr_debug.h"
39 #if defined(PVRSRV_NEED_PVR_DPF)
41 #define PVR_MAX_FILEPATH_LEN 256
43 static IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING;
47 #define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
49 static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
51 static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
53 static struct mutex gsDebugMutexNonIRQ;
55 DEFINE_SPINLOCK(gsDebugLockIRQ);
57 #define USE_SPIN_LOCK (in_interrupt() || !preemptible())
59 static inline void GetBufferLock(unsigned long *pulLockFlags)
63 spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
67 mutex_lock(&gsDebugMutexNonIRQ);
71 static inline void ReleaseBufferLock(unsigned long ulLockFlags)
75 spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
79 mutex_unlock(&gsDebugMutexNonIRQ);
83 static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
87 *ppszBuf = gszBufferIRQ;
88 *pui32BufSiz = sizeof(gszBufferIRQ);
92 *ppszBuf = gszBufferNonIRQ;
93 *pui32BufSiz = sizeof(gszBufferNonIRQ);
97 static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
100 IMG_UINT32 ui32Space;
103 ui32Used = strlen(pszBuf);
104 BUG_ON(ui32Used >= ui32BufSiz);
105 ui32Space = ui32BufSiz - ui32Used;
107 i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
108 pszBuf[ui32BufSiz - 1] = 0;
111 return (i32Len < 0 || i32Len >= ui32Space);
114 IMG_VOID PVRDPFInit(IMG_VOID)
116 mutex_init(&gsDebugMutexNonIRQ);
119 IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
122 unsigned long ulLockFlags = 0;
124 IMG_UINT32 ui32BufSiz;
126 SelectBuffer(&pszBuf, &ui32BufSiz);
128 va_start(vaArgs, pszFormat);
130 GetBufferLock(&ulLockFlags);
131 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
133 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
135 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
139 printk(KERN_INFO "%s\n", pszBuf);
142 ReleaseBufferLock(ulLockFlags);
147 #if defined(PVRSRV_NEED_PVR_ASSERT)
149 IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
151 PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
157 #if defined(PVRSRV_NEED_PVR_TRACE)
159 IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
162 unsigned long ulLockFlags = 0;
164 IMG_UINT32 ui32BufSiz;
166 SelectBuffer(&pszBuf, &ui32BufSiz);
168 va_start(VArgs, pszFormat);
170 GetBufferLock(&ulLockFlags);
172 strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
174 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
176 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
180 printk(KERN_INFO "%s\n", pszBuf);
183 ReleaseBufferLock(ulLockFlags);
190 #if defined(PVRSRV_NEED_PVR_DPF)
192 static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
197 va_start (VArgs, pszFormat);
199 bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
206 IMG_VOID PVRSRVDebugPrintf (
207 IMG_UINT32 ui32DebugLevel,
208 const IMG_CHAR* pszFullFileName,
210 const IMG_CHAR* pszFormat,
214 IMG_BOOL bTrace, bDebug;
215 const IMG_CHAR *pszFileName = pszFullFileName;
216 IMG_CHAR *pszLeafName;
218 bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE;
219 bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel);
221 if (bTrace || bDebug)
224 unsigned long ulLockFlags = 0;
226 IMG_UINT32 ui32BufSiz;
228 SelectBuffer(&pszBuf, &ui32BufSiz);
230 va_start(vaArgs, pszFormat);
232 GetBufferLock(&ulLockFlags);
237 switch(ui32DebugLevel)
241 strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
246 strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
249 case DBGPRIV_WARNING:
251 strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
254 case DBGPRIV_MESSAGE:
256 strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
259 case DBGPRIV_VERBOSE:
261 strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
266 strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
273 strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
276 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
278 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
285 #ifdef DEBUG_LOG_PATH_TRUNCATE
287 static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
289 IMG_CHAR* pszTruncIter;
290 IMG_CHAR* pszTruncBackInter;
293 pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
296 strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
298 if(strlen(szFileNameRewrite) == PVR_MAX_FILEPATH_LEN-1) {
299 IMG_CHAR szTruncateMassage[] = "FILENAME TRUNCATED";
300 strcpy(szFileNameRewrite + (PVR_MAX_FILEPATH_LEN - 1 - strlen(szTruncateMassage)), szTruncateMassage);
303 pszTruncIter = szFileNameRewrite;
304 while(*pszTruncIter++ != 0)
306 IMG_CHAR* pszNextStartPoint;
309 !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
310 ( *(pszTruncIter-1) == '.') &&
311 ( *(pszTruncIter-2) == '.') &&
312 ( *(pszTruncIter-3) == '/') )
316 pszTruncBackInter = pszTruncIter - 3;
317 while(*(--pszTruncBackInter) != '/')
319 if(pszTruncBackInter <= szFileNameRewrite) break;
321 pszNextStartPoint = pszTruncBackInter;
324 while(*pszTruncIter != 0)
326 *pszTruncBackInter++ = *pszTruncIter++;
328 *pszTruncBackInter = 0;
331 pszTruncIter = pszNextStartPoint;
334 pszFileName = szFileNameRewrite;
336 if(*pszFileName == '/') pszFileName++;
340 pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
344 pszFileName = pszLeafName;
348 if (BAppend(pszBuf, ui32BufSiz, " [%lu, %s]", ui32Line, pszFileName))
350 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
354 printk(KERN_INFO "%s\n", pszBuf);
359 printk(KERN_INFO "%s\n", pszBuf);
363 ReleaseBufferLock(ulLockFlags);
373 IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel)
375 printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(IMG_UINT)uDebugLevel);
377 gPVRDebugLevel = uDebugLevel;
380 IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
382 #define _PROC_SET_BUFFER_SZ 2
383 IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
385 if (count != _PROC_SET_BUFFER_SZ)
391 if (copy_from_user(data_buffer, buffer, count))
393 if (data_buffer[count - 1] != '\n')
395 PVRDebugSetLevel(data_buffer[0] - '0');
400 #ifdef PVR_PROC_USE_SEQ_FILE
401 void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
403 seq_printf(sfile, "%lu\n", gPVRDebugLevel);
407 IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
410 *start = (IMG_CHAR *)1;
411 return printAppend(page, count, 0, "%lu\n", gPVRDebugLevel);