packaging: update the changelog
[profile/ivi/intel-emgd-kmod.git] / pvr / services4 / srvkm / env / linux / pvr_debug.c
1 /**********************************************************************
2  Copyright (c) Imagination Technologies Ltd.
3
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:
10
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13
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
20  THE SOFTWARE.
21  ******************************************************************************/
22
23
24 #include <asm/io.h>
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>
31 #include <stdarg.h>
32 #include "img_types.h"
33 #include "servicesext.h"
34 #include "pvr_debug.h"
35 #include "proc.h"
36 #include "mutex.h"
37 #include "linkage.h"
38
39 #if defined(PVRSRV_NEED_PVR_DPF)
40
41 #define PVR_MAX_FILEPATH_LEN 256
42
43 static IMG_UINT32 gPVRDebugLevel = DBGPRIV_WARNING;
44
45 #endif
46
47 #define PVR_MAX_MSG_LEN PVR_MAX_DEBUG_MESSAGE_LEN
48
49 static IMG_CHAR gszBufferNonIRQ[PVR_MAX_MSG_LEN + 1];
50
51 static IMG_CHAR gszBufferIRQ[PVR_MAX_MSG_LEN + 1];
52
53 static struct mutex gsDebugMutexNonIRQ;
54
55 DEFINE_SPINLOCK(gsDebugLockIRQ);
56
57 #define USE_SPIN_LOCK (in_interrupt() || !preemptible())
58
59 static inline void GetBufferLock(unsigned long *pulLockFlags)
60 {
61         if (USE_SPIN_LOCK)
62         {
63                 spin_lock_irqsave(&gsDebugLockIRQ, *pulLockFlags);
64         }
65         else
66         {
67                 mutex_lock(&gsDebugMutexNonIRQ);
68         }
69 }
70
71 static inline void ReleaseBufferLock(unsigned long ulLockFlags)
72 {
73         if (USE_SPIN_LOCK)
74         {
75                 spin_unlock_irqrestore(&gsDebugLockIRQ, ulLockFlags);
76         }
77         else
78         {
79                 mutex_unlock(&gsDebugMutexNonIRQ);
80         }
81 }
82
83 static inline void SelectBuffer(IMG_CHAR **ppszBuf, IMG_UINT32 *pui32BufSiz)
84 {
85         if (USE_SPIN_LOCK)
86         {
87                 *ppszBuf = gszBufferIRQ;
88                 *pui32BufSiz = sizeof(gszBufferIRQ);
89         }
90         else
91         {
92                 *ppszBuf = gszBufferNonIRQ;
93                 *pui32BufSiz = sizeof(gszBufferNonIRQ);
94         }
95 }
96
97 static IMG_BOOL VBAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR* pszFormat, va_list VArgs)
98 {
99         IMG_UINT32 ui32Used;
100         IMG_UINT32 ui32Space;
101         IMG_INT32 i32Len;
102
103         ui32Used = strlen(pszBuf);
104         BUG_ON(ui32Used >= ui32BufSiz);
105         ui32Space = ui32BufSiz - ui32Used;
106
107         i32Len = vsnprintf(&pszBuf[ui32Used], ui32Space, pszFormat, VArgs);
108         pszBuf[ui32BufSiz - 1] = 0;
109
110
111         return (i32Len < 0 || i32Len >= ui32Space);
112 }
113
114 IMG_VOID PVRDPFInit(IMG_VOID)
115 {
116     mutex_init(&gsDebugMutexNonIRQ);
117 }
118
119 IMG_VOID PVRSRVReleasePrintf(const IMG_CHAR *pszFormat, ...)
120 {
121         va_list vaArgs;
122         unsigned long ulLockFlags = 0;
123         IMG_CHAR *pszBuf;
124         IMG_UINT32 ui32BufSiz;
125
126         SelectBuffer(&pszBuf, &ui32BufSiz);
127
128         va_start(vaArgs, pszFormat);
129
130         GetBufferLock(&ulLockFlags);
131         strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
132
133         if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
134         {
135                 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
136         }
137         else
138         {
139                 printk(KERN_INFO "%s\n", pszBuf);
140         }
141
142         ReleaseBufferLock(ulLockFlags);
143         va_end(vaArgs);
144
145 }
146
147 #if defined(PVRSRV_NEED_PVR_ASSERT)
148
149 IMG_VOID PVRSRVDebugAssertFail(const IMG_CHAR* pszFile, IMG_UINT32 uLine)
150 {
151         PVRSRVDebugPrintf(DBGPRIV_FATAL, pszFile, uLine, "Debug assertion failed!");
152         BUG();
153 }
154
155 #endif
156
157 #if defined(PVRSRV_NEED_PVR_TRACE)
158
159 IMG_VOID PVRSRVTrace(const IMG_CHAR* pszFormat, ...)
160 {
161         va_list VArgs;
162         unsigned long ulLockFlags = 0;
163         IMG_CHAR *pszBuf;
164         IMG_UINT32 ui32BufSiz;
165
166         SelectBuffer(&pszBuf, &ui32BufSiz);
167
168         va_start(VArgs, pszFormat);
169
170         GetBufferLock(&ulLockFlags);
171
172         strncpy(pszBuf, "PVR: ", (ui32BufSiz -1));
173
174         if (VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs))
175         {
176                 printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
177         }
178         else
179         {
180                 printk(KERN_INFO "%s\n", pszBuf);
181         }
182
183         ReleaseBufferLock(ulLockFlags);
184
185         va_end(VArgs);
186 }
187
188 #endif
189
190 #if defined(PVRSRV_NEED_PVR_DPF)
191
192 static IMG_BOOL BAppend(IMG_CHAR *pszBuf, IMG_UINT32 ui32BufSiz, const IMG_CHAR *pszFormat, ...)
193 {
194                 va_list VArgs;
195                 IMG_BOOL bTrunc;
196
197                 va_start (VArgs, pszFormat);
198
199                 bTrunc = VBAppend(pszBuf, ui32BufSiz, pszFormat, VArgs);
200
201                 va_end (VArgs);
202
203                 return bTrunc;
204 }
205
206 IMG_VOID PVRSRVDebugPrintf      (
207                                                 IMG_UINT32      ui32DebugLevel,
208                                                 const IMG_CHAR* pszFullFileName,
209                                                 IMG_UINT32      ui32Line,
210                                                 const IMG_CHAR* pszFormat,
211                                                 ...
212                                         )
213 {
214         IMG_BOOL bTrace, bDebug;
215         const IMG_CHAR *pszFileName = pszFullFileName;
216         IMG_CHAR *pszLeafName;
217
218         bTrace = gPVRDebugLevel & ui32DebugLevel & DBGPRIV_CALLTRACE;
219         bDebug = ((gPVRDebugLevel & DBGPRIV_ALLLEVELS) >= ui32DebugLevel);
220
221         if (bTrace || bDebug)
222         {
223                 va_list vaArgs;
224                 unsigned long ulLockFlags = 0;
225                 IMG_CHAR *pszBuf;
226                 IMG_UINT32 ui32BufSiz;
227
228                 SelectBuffer(&pszBuf, &ui32BufSiz);
229
230                 va_start(vaArgs, pszFormat);
231
232                 GetBufferLock(&ulLockFlags);
233
234
235                 if (bDebug)
236                 {
237                         switch(ui32DebugLevel)
238                         {
239                                 case DBGPRIV_FATAL:
240                                 {
241                                         strncpy (pszBuf, "PVR_K:(Fatal): ", (ui32BufSiz -1));
242                                         break;
243                                 }
244                                 case DBGPRIV_ERROR:
245                                 {
246                                         strncpy (pszBuf, "PVR_K:(Error): ", (ui32BufSiz -1));
247                                         break;
248                                 }
249                                 case DBGPRIV_WARNING:
250                                 {
251                                         strncpy (pszBuf, "PVR_K:(Warning): ", (ui32BufSiz -1));
252                                         break;
253                                 }
254                                 case DBGPRIV_MESSAGE:
255                                 {
256                                         strncpy (pszBuf, "PVR_K:(Message): ", (ui32BufSiz -1));
257                                         break;
258                                 }
259                                 case DBGPRIV_VERBOSE:
260                                 {
261                                         strncpy (pszBuf, "PVR_K:(Verbose): ", (ui32BufSiz -1));
262                                         break;
263                                 }
264                                 default:
265                                 {
266                                         strncpy (pszBuf, "PVR_K:(Unknown message level)", (ui32BufSiz -1));
267                                         break;
268                                 }
269                         }
270                 }
271                 else
272                 {
273                         strncpy (pszBuf, "PVR_K: ", (ui32BufSiz -1));
274                 }
275
276                 if (VBAppend(pszBuf, ui32BufSiz, pszFormat, vaArgs))
277                 {
278                         printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
279                 }
280                 else
281                 {
282
283                         if (!bTrace)
284                         {
285 #ifdef DEBUG_LOG_PATH_TRUNCATE
286
287                                 static IMG_CHAR szFileNameRewrite[PVR_MAX_FILEPATH_LEN];
288
289                                 IMG_CHAR* pszTruncIter;
290                                 IMG_CHAR* pszTruncBackInter;
291
292
293                                 pszFileName = pszFullFileName + strlen(DEBUG_LOG_PATH_TRUNCATE)+1;
294
295
296                                 strncpy(szFileNameRewrite, pszFileName,PVR_MAX_FILEPATH_LEN);
297
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);
301                                 }
302
303                                 pszTruncIter = szFileNameRewrite;
304                                 while(*pszTruncIter++ != 0)
305                                 {
306                                         IMG_CHAR* pszNextStartPoint;
307
308                                         if(
309                                            !( ( *pszTruncIter == '/' && (pszTruncIter-4 >= szFileNameRewrite) ) &&
310                                                  ( *(pszTruncIter-1) == '.') &&
311                                                  ( *(pszTruncIter-2) == '.') &&
312                                                  ( *(pszTruncIter-3) == '/') )
313                                            ) continue;
314
315
316                                         pszTruncBackInter = pszTruncIter - 3;
317                                         while(*(--pszTruncBackInter) != '/')
318                                         {
319                                                 if(pszTruncBackInter <= szFileNameRewrite) break;
320                                         }
321                                         pszNextStartPoint = pszTruncBackInter;
322
323
324                                         while(*pszTruncIter != 0)
325                                         {
326                                                 *pszTruncBackInter++ = *pszTruncIter++;
327                                         }
328                                         *pszTruncBackInter = 0;
329
330
331                                         pszTruncIter = pszNextStartPoint;
332                                 }
333
334                                 pszFileName = szFileNameRewrite;
335
336                                 if(*pszFileName == '/') pszFileName++;
337 #endif
338
339 #if !defined(__sh__)
340                                 pszLeafName = (IMG_CHAR *)strrchr (pszFileName, '\\');
341
342                                 if (pszLeafName)
343                                 {
344                                         pszFileName = pszLeafName;
345                         }
346 #endif
347
348                                 if (BAppend(pszBuf, ui32BufSiz, " [%lu, %s]", ui32Line, pszFileName))
349                                 {
350                                         printk(KERN_INFO "PVR_K:(Message Truncated): %s\n", pszBuf);
351                                 }
352                                 else
353                                 {
354                                         printk(KERN_INFO "%s\n", pszBuf);
355                                 }
356                         }
357                         else
358                         {
359                                 printk(KERN_INFO "%s\n", pszBuf);
360                         }
361                 }
362
363                 ReleaseBufferLock(ulLockFlags);
364
365                 va_end (vaArgs);
366         }
367 }
368
369 #endif
370
371 #if defined(DEBUG)
372
373 IMG_VOID PVRDebugSetLevel(IMG_UINT32 uDebugLevel)
374 {
375         printk(KERN_INFO "PVR: Setting Debug Level = 0x%x\n",(IMG_UINT)uDebugLevel);
376
377         gPVRDebugLevel = uDebugLevel;
378 }
379
380 IMG_INT PVRDebugProcSetLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
381 {
382 #define _PROC_SET_BUFFER_SZ             2
383         IMG_CHAR data_buffer[_PROC_SET_BUFFER_SZ];
384
385         if (count != _PROC_SET_BUFFER_SZ)
386         {
387                 return -EINVAL;
388         }
389         else
390         {
391                 if (copy_from_user(data_buffer, buffer, count))
392                         return -EINVAL;
393                 if (data_buffer[count - 1] != '\n')
394                         return -EINVAL;
395                 PVRDebugSetLevel(data_buffer[0] - '0');
396         }
397         return (count);
398 }
399
400 #ifdef PVR_PROC_USE_SEQ_FILE
401 void ProcSeqShowDebugLevel(struct seq_file *sfile,void* el)
402 {
403         seq_printf(sfile, "%lu\n", gPVRDebugLevel);
404 }
405
406 #else
407 IMG_INT PVRDebugProcGetLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
408 {
409         if (off == 0) {
410                 *start = (IMG_CHAR *)1;
411                 return printAppend(page, count, 0, "%lu\n", gPVRDebugLevel);
412         }
413         *eof = 1;
414         return 0;
415 }
416 #endif
417
418 #endif