1 #include <linux/version.h>
4 #include <linux/pagemap.h>
5 #include <linux/genalloc.h>
6 #include <linux/sched.h>
7 #include <linux/mutex.h>
8 //#include <linux/xlog.h>
9 #include <linux/proc_fs.h>
10 #include <linux/seq_file.h>
11 #include <linux/rtc.h>
15 #include "ged_debugFS.h"
16 #include "ged_profile_dvfs.h"
17 #include "ged_hashtable.h"
21 /* 0x00 - 0xff reserved for internal buffer type */
23 /* rewrite the oldest log when buffer is full */
24 GED_LOG_ATTR_RINGBUFFER
= 0x1,
25 /* stop logging when buffer is full */
26 GED_LOG_ATTR_QUEUEBUFFER
= 0x2,
27 /* increase buffersize when buffer is full */
28 GED_LOG_ATTR_AUTO_INCREASE
= 0x4,
31 typedef struct GED_LOG_BUF_LINE_TAG
41 typedef struct GED_LOG_BUF_TAG
43 GED_LOG_BUF_TYPE eType
;
49 GED_LOG_BUF_LINE
*psLine
;
57 unsigned long ui32IRQFlags
;
59 char acName
[GED_LOG_BUF_NAME_LENGTH
];
60 char acNodeName
[GED_LOG_BUF_NODE_NAME_LENGTH
];
62 struct dentry
* psEntry
;
64 struct list_head sList
;
66 unsigned int ui32HashNodeID
;
70 typedef struct GED_LOG_LISTEN_TAG
72 GED_LOG_BUF_HANDLE
*pCBHnd
;
73 char acName
[GED_LOG_BUF_NAME_LENGTH
];
74 struct list_head sList
;
77 typedef struct GED_LOG_BUF_LIST_TAG
80 struct list_head sList_buf
;
81 struct list_head sList_listen
;
84 static GED_LOG_BUF_LIST gsGEDLogBufList
= {
85 .sLock
= __RW_LOCK_UNLOCKED(gsGEDLogBufList
.sLock
),
86 .sList_buf
= LIST_HEAD_INIT(gsGEDLogBufList
.sList_buf
),
87 .sList_listen
= LIST_HEAD_INIT(gsGEDLogBufList
.sList_listen
),
90 static struct dentry
* gpsGEDLogEntry
= NULL
;
91 static struct dentry
* gpsGEDLogBufsDir
= NULL
;
93 static GED_HASHTABLE_HANDLE ghHashTable
= NULL
;
95 //-----------------------------------------------------------------------------
99 //-----------------------------------------------------------------------------
100 static GED_LOG_BUF
* ged_log_buf_from_handle(GED_LOG_BUF_HANDLE hLogBuf
)
102 return ged_hashtable_find(ghHashTable
, (unsigned int)hLogBuf
);
105 static GED_ERROR
__ged_log_buf_vprint(GED_LOG_BUF
*psGEDLogBuf
, const char *fmt
, va_list args
, int attrs
)
113 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
116 if (psGEDLogBuf
->i32LineCurrent
>= psGEDLogBuf
->i32LineCount
||
117 psGEDLogBuf
->i32BufferCurrent
+ 256 > psGEDLogBuf
->i32BufferSize
)
119 if (attrs
& GED_LOG_ATTR_RINGBUFFER
)
121 /* for ring buffer, we start over. */
122 psGEDLogBuf
->i32LineCurrent
= 0;
123 psGEDLogBuf
->i32BufferCurrent
= 0;
125 else if (attrs
& GED_LOG_ATTR_QUEUEBUFFER
)
127 if (attrs
& GED_LOG_ATTR_AUTO_INCREASE
)
129 int newLineCount
, newBufferSize
;
131 /* incease min(25%, 1MB) */
132 if ((psGEDLogBuf
->i32LineCount
>> 2) <= 1024 * 1024)
134 newLineCount
= psGEDLogBuf
->i32LineCount
+ (psGEDLogBuf
->i32LineCount
>> 2);
135 newBufferSize
= psGEDLogBuf
->i32BufferSize
+ (psGEDLogBuf
->i32BufferSize
>> 2);
139 newLineCount
= psGEDLogBuf
->i32LineCount
+ 4096;
140 newBufferSize
= psGEDLogBuf
->i32BufferSize
+ 1024 * 1024;
143 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
144 if (ged_log_buf_resize(psGEDLogBuf
->ui32HashNodeID
, newLineCount
, newBufferSize
) != GED_OK
)
146 return GED_ERROR_OOM
;
148 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
152 /* for queuebuffer only, we skip the log. */
153 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
154 return GED_ERROR_OOM
;
159 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].offset
= psGEDLogBuf
->i32BufferCurrent
;
160 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].tattrs
= 0;
161 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].time
= 0;
163 /* record the kernel time */
164 if (attrs
& GED_LOG_ATTR_TIME
)
166 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].tattrs
= GED_LOG_ATTR_TIME
;
167 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].time
= ged_get_time();
170 /* record the user time */
171 if (attrs
& GED_LOG_ATTR_TIME_TPT
)
174 unsigned long local_time
;
176 do_gettimeofday(&time
);
177 local_time
= (u32
)(time
.tv_sec
- (sys_tz
.tz_minuteswest
* 60));
179 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].tattrs
= GED_LOG_ATTR_TIME_TPT
;
180 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].time
= local_time
;
181 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].time_usec
= time
.tv_usec
;
182 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].pid
= current
->tgid
;
183 psGEDLogBuf
->psLine
[psGEDLogBuf
->i32LineCurrent
].tid
= current
->pid
;
186 buf_n
= psGEDLogBuf
->i32BufferSize
- psGEDLogBuf
->i32BufferCurrent
;
187 len
= vsnprintf(psGEDLogBuf
->pcBuffer
+ psGEDLogBuf
->i32BufferCurrent
, buf_n
, fmt
, args
);
189 if (len
> buf_n
) len
= buf_n
;
193 if (attrs
& GED_LOG_ATTR_RINGBUFFER
)
196 int check
= 10 + 1; /* we check the following 10 items. */
197 int a
= psGEDLogBuf
->i32BufferCurrent
;
198 int b
= psGEDLogBuf
->i32BufferCurrent
+ len
+ 2;
200 for (i
= psGEDLogBuf
->i32LineCurrent
+1; --check
&& i
< psGEDLogBuf
->i32LineCount
; ++i
)
202 int pos
= psGEDLogBuf
->psLine
[i
].offset
;
203 if (pos
>= a
&& pos
< b
)
204 psGEDLogBuf
->psLine
[i
].offset
= -1;
207 if (check
&& i
== psGEDLogBuf
->i32LineCount
)
209 for (i
= 0; --check
&& i
< psGEDLogBuf
->i32LineCurrent
; ++i
)
211 int pos
= psGEDLogBuf
->psLine
[i
].offset
;
213 if (pos
>= a
&& pos
< b
)
214 psGEDLogBuf
->psLine
[i
].offset
= -1;
220 psGEDLogBuf
->i32BufferCurrent
+= len
+ 2;
221 psGEDLogBuf
->i32LineCurrent
+= 1;
223 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
228 static GED_ERROR
__ged_log_buf_print(GED_LOG_BUF
*psGEDLogBuf
, const char *fmt
, ...)
234 err
= __ged_log_buf_vprint(psGEDLogBuf
, fmt
, args
, psGEDLogBuf
->attrs
| GED_LOG_ATTR_TIME
);
240 static int __ged_log_buf_write(GED_LOG_BUF
*psGEDLogBuf
, const char __user
*pszBuffer
, int i32Count
)
250 cnt
= (i32Count
>= 256) ? 255 : i32Count
;
252 ged_copy_from_user(buf
, pszBuffer
, cnt
);
255 if (buf
[cnt
-1] == '\n')
260 __ged_log_buf_print(psGEDLogBuf
, buf
);
265 static void __ged_log_buf_check_get_early_list(GED_LOG_BUF_HANDLE hLogBuf
, const char *pszName
)
267 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
268 GED_LOG_LISTEN
*psFound
= NULL
, *psLogListen
;
270 read_lock_bh(&gsGEDLogBufList
.sLock
);
272 psList
= &gsGEDLogBufList
.sList_listen
;
273 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
275 psLogListen
= list_entry(psListEntry
, GED_LOG_LISTEN
, sList
);
276 if (0 == strcmp(psLogListen
->acName
, pszName
))
278 psFound
= psLogListen
;
283 read_unlock_bh(&gsGEDLogBufList
.sLock
);
287 write_lock_bh(&gsGEDLogBufList
.sLock
);
288 *psFound
->pCBHnd
= hLogBuf
;
289 list_del(&psFound
->sList
);
290 write_unlock_bh(&gsGEDLogBufList
.sLock
);
294 static ssize_t
ged_log_buf_write_entry(const char __user
*pszBuffer
, size_t uiCount
, loff_t uiPosition
, void *pvData
)
296 return (ssize_t
)__ged_log_buf_write((GED_LOG_BUF
*)pvData
, pszBuffer
, (int)uiCount
);
298 //-----------------------------------------------------------------------------
299 static void* ged_log_buf_seq_start(struct seq_file
*psSeqFile
, loff_t
*puiPosition
)
301 GED_LOG_BUF
*psGEDLogBuf
= (GED_LOG_BUF
*)psSeqFile
->private;
303 if (0 == *puiPosition
)
309 //-----------------------------------------------------------------------------
310 static void ged_log_buf_seq_stop(struct seq_file
*psSeqFile
, void *pvData
)
314 //-----------------------------------------------------------------------------
315 static void* ged_log_buf_seq_next(struct seq_file
*psSeqFile
, void *pvData
, loff_t
*puiPosition
)
321 //-----------------------------------------------------------------------------
322 static int ged_log_buf_seq_show_print(struct seq_file
*psSeqFile
, GED_LOG_BUF
*psGEDLogBuf
, int i
)
325 GED_LOG_BUF_LINE
*line
;
327 line
= &psGEDLogBuf
->psLine
[i
];
329 if (line
->offset
>= 0)
331 if (line
->tattrs
& GED_LOG_ATTR_TIME
)
333 unsigned long long t
;
334 unsigned long nanosec_rem
;
337 nanosec_rem
= do_div(t
, 1000000000);
339 seq_printf(psSeqFile
,"[%5llu.%06lu] ", t
, nanosec_rem
/ 1000);
342 if (line
->tattrs
& GED_LOG_ATTR_TIME_TPT
)
344 unsigned long local_time
;
347 local_time
= line
->time
;
348 rtc_time_to_tm(local_time
, &tm
);
350 seq_printf(psSeqFile
,"%02d-%02d %02d:%02d:%02d.%06lu %5d %5d ",
351 /*tm.tm_year + 1900,*/ tm
.tm_mon
+ 1, tm
.tm_mday
,
352 tm
.tm_hour
, tm
.tm_min
, tm
.tm_sec
,
353 line
->time_usec
, line
->pid
, line
->tid
);
356 err
= seq_printf(psSeqFile
, "%s\n", psGEDLogBuf
->pcBuffer
+ line
->offset
);
362 static int ged_log_buf_seq_show(struct seq_file
*psSeqFile
, void *pvData
)
364 GED_LOG_BUF
*psGEDLogBuf
= (GED_LOG_BUF
*)pvData
;
366 if (psGEDLogBuf
!= NULL
)
370 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
372 if (psGEDLogBuf
->acName
[0] != '\0')
374 seq_printf(psSeqFile
, "---------- %s (%d/%d) ----------\n",
375 psGEDLogBuf
->acName
, psGEDLogBuf
->i32BufferCurrent
, psGEDLogBuf
->i32BufferSize
);
378 if (psGEDLogBuf
->attrs
& GED_LOG_ATTR_RINGBUFFER
)
380 for (i
= psGEDLogBuf
->i32LineCurrent
; i
< psGEDLogBuf
->i32LineCount
; ++i
)
382 if (0 != ged_log_buf_seq_show_print(psSeqFile
, psGEDLogBuf
, i
))
386 //seq_printf(psSeqFile, " > ---------- start over ----------\n");
388 for (i
= 0; i
< psGEDLogBuf
->i32LineCurrent
; ++i
)
390 if (0 != ged_log_buf_seq_show_print(psSeqFile
, psGEDLogBuf
, i
))
394 else if (psGEDLogBuf
->attrs
& GED_LOG_ATTR_QUEUEBUFFER
)
396 for (i
= 0; i
< psGEDLogBuf
->i32LineCount
; ++i
)
398 if (0 != ged_log_buf_seq_show_print(psSeqFile
, psGEDLogBuf
, i
))
403 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
408 //-----------------------------------------------------------------------------
409 static struct seq_operations gsGEDLogBufReadOps
=
411 .start
= ged_log_buf_seq_start
,
412 .stop
= ged_log_buf_seq_stop
,
413 .next
= ged_log_buf_seq_next
,
414 .show
= ged_log_buf_seq_show
,
416 //-----------------------------------------------------------------------------
417 GED_LOG_BUF_HANDLE
ged_log_buf_alloc(
419 int i32MaxBufferSizeByte
,
420 GED_LOG_BUF_TYPE eType
,
422 const char* pszNodeName
)
424 GED_LOG_BUF
*psGEDLogBuf
;
427 if (((!pszName
) && (!pszNodeName
)) || (i32MaxLineCount
<= 0) || (i32MaxBufferSizeByte
<= 0))
429 return (GED_LOG_BUF_HANDLE
)0;
432 psGEDLogBuf
= (GED_LOG_BUF
*)ged_alloc(sizeof(GED_LOG_BUF
));
433 if (NULL
== psGEDLogBuf
)
435 GED_LOGE("ged: failed to allocate log buf!\n");
436 return (GED_LOG_BUF_HANDLE
)0;
439 psGEDLogBuf
->eType
= eType
;
443 case GED_LOG_BUF_TYPE_RINGBUFFER
:
444 psGEDLogBuf
->attrs
= GED_LOG_ATTR_RINGBUFFER
;
446 case GED_LOG_BUF_TYPE_QUEUEBUFFER
:
447 psGEDLogBuf
->attrs
= GED_LOG_ATTR_QUEUEBUFFER
;
449 case GED_LOG_BUF_TYPE_QUEUEBUFFER_AUTO_INCREASE
:
450 psGEDLogBuf
->attrs
= GED_LOG_ATTR_QUEUEBUFFER
| GED_LOG_ATTR_AUTO_INCREASE
;
454 psGEDLogBuf
->i32MemorySize
= i32MaxBufferSizeByte
+ sizeof(GED_LOG_BUF_LINE
) * i32MaxLineCount
;
455 psGEDLogBuf
->pMemory
= ged_alloc(psGEDLogBuf
->i32MemorySize
);
456 if (NULL
== psGEDLogBuf
->pMemory
)
458 ged_free(psGEDLogBuf
, sizeof(GED_LOG_BUF
));
459 GED_LOGE("ged: failed to allocate log buf!\n");
460 return (GED_LOG_BUF_HANDLE
)0;
463 psGEDLogBuf
->psLine
= (GED_LOG_BUF_LINE
*)psGEDLogBuf
->pMemory
;
464 psGEDLogBuf
->pcBuffer
= (char *)&psGEDLogBuf
->psLine
[i32MaxLineCount
];
465 psGEDLogBuf
->i32LineCount
= i32MaxLineCount
;
466 psGEDLogBuf
->i32BufferSize
= i32MaxBufferSizeByte
;
467 psGEDLogBuf
->i32LineCurrent
= 0;
468 psGEDLogBuf
->i32BufferCurrent
= 0;
470 psGEDLogBuf
->psEntry
= NULL
;
471 spin_lock_init(&psGEDLogBuf
->sSpinLock
);
472 psGEDLogBuf
->acName
[0] = '\0';
473 psGEDLogBuf
->acNodeName
[0] = '\0';
478 for (i
= 0; i
< psGEDLogBuf
->i32LineCount
; ++i
)
479 psGEDLogBuf
->psLine
[i
].offset
= -1;
484 snprintf(psGEDLogBuf
->acName
, GED_LOG_BUF_NAME_LENGTH
, "%s", pszName
);
487 // Add into the global list
488 INIT_LIST_HEAD(&psGEDLogBuf
->sList
);
489 write_lock_bh(&gsGEDLogBufList
.sLock
);
490 list_add(&psGEDLogBuf
->sList
, &gsGEDLogBufList
.sList_buf
);
491 write_unlock_bh(&gsGEDLogBufList
.sLock
);
496 snprintf(psGEDLogBuf
->acNodeName
, GED_LOG_BUF_NODE_NAME_LENGTH
, "%s", pszNodeName
);
497 err
= ged_debugFS_create_entry(
498 psGEDLogBuf
->acNodeName
,
501 ged_log_buf_write_entry
,
503 &psGEDLogBuf
->psEntry
);
507 GED_LOGE("ged: failed to create %s entry, err(%d)!\n", pszNodeName
, err
);
508 ged_log_buf_free(psGEDLogBuf
->ui32HashNodeID
);
509 return (GED_LOG_BUF_HANDLE
)0;
513 error
= ged_hashtable_insert(ghHashTable
, psGEDLogBuf
, &psGEDLogBuf
->ui32HashNodeID
);
516 GED_LOGE("ged: failed to insert into a hash table, err(%d)!\n", error
);
517 ged_log_buf_free(psGEDLogBuf
->ui32HashNodeID
);
518 return (GED_LOG_BUF_HANDLE
)0;
521 GED_LOGI("ged_log_buf_alloc OK\n");
523 __ged_log_buf_check_get_early_list(psGEDLogBuf
->ui32HashNodeID
, pszName
);
525 return (GED_LOG_BUF_HANDLE
)psGEDLogBuf
->ui32HashNodeID
;
528 GED_ERROR
ged_log_buf_resize(
529 GED_LOG_BUF_HANDLE hLogBuf
,
530 int i32NewMaxLineCount
,
531 int i32NewMaxBufferSizeByte
)
534 GED_LOG_BUF
*psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
535 int i32NewMemorySize
, i32OldMemorySize
;
536 void *pNewMemory
, *pOldMemory
;
537 GED_LOG_BUF_LINE
*pi32NewLine
;
540 if ((NULL
== psGEDLogBuf
) || (i32NewMaxLineCount
<= 0) || (i32NewMaxBufferSizeByte
<= 0))
542 return GED_ERROR_INVALID_PARAMS
;
545 i32NewMemorySize
= i32NewMaxBufferSizeByte
+ sizeof(GED_LOG_BUF_LINE
) * i32NewMaxLineCount
;
546 pNewMemory
= ged_alloc(i32NewMemorySize
);
547 if (NULL
== pNewMemory
)
549 return GED_ERROR_OOM
;
552 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
554 pi32NewLine
= (GED_LOG_BUF_LINE
*)pNewMemory
;
555 pcNewBuffer
= (char *)&pi32NewLine
[i32NewMaxLineCount
];
557 memcpy(pi32NewLine
, psGEDLogBuf
->psLine
, sizeof(GED_LOG_BUF_LINE
) * min(i32NewMaxLineCount
, psGEDLogBuf
->i32LineCount
));
558 memcpy(pcNewBuffer
, psGEDLogBuf
->pcBuffer
, min(i32NewMaxBufferSizeByte
, psGEDLogBuf
->i32BufferSize
));
560 for (i
= psGEDLogBuf
->i32LineCount
; i
< i32NewMaxLineCount
; ++i
)
561 pi32NewLine
[i
].offset
= -1;
563 i32OldMemorySize
= psGEDLogBuf
->i32MemorySize
;
564 pOldMemory
= psGEDLogBuf
->pMemory
;
566 psGEDLogBuf
->i32MemorySize
= i32NewMemorySize
;
567 psGEDLogBuf
->pMemory
= pNewMemory
;
568 psGEDLogBuf
->psLine
= pi32NewLine
;
569 psGEDLogBuf
->pcBuffer
= pcNewBuffer
;
570 psGEDLogBuf
->i32LineCount
= i32NewMaxLineCount
;
571 psGEDLogBuf
->i32BufferSize
= i32NewMaxBufferSizeByte
;
573 if (psGEDLogBuf
->i32BufferCurrent
>= i32NewMaxBufferSizeByte
)
574 psGEDLogBuf
->i32BufferCurrent
= i32NewMaxBufferSizeByte
- 1;
575 pcNewBuffer
[psGEDLogBuf
->i32BufferCurrent
] = 0;
577 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
578 ged_free(pOldMemory
, i32OldMemorySize
);
583 GED_ERROR
ged_log_buf_ignore_lines(GED_LOG_BUF_HANDLE hLogBuf
, int n
)
585 GED_LOG_BUF
*psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
587 if (psGEDLogBuf
&& n
> 0)
589 if (psGEDLogBuf
->attrs
& GED_LOG_ATTR_QUEUEBUFFER
)
591 if (n
>= psGEDLogBuf
->i32LineCurrent
)
593 /* reset all buffer */
594 ged_log_buf_reset(hLogBuf
);
602 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
604 buf_offset
= psGEDLogBuf
->psLine
[n
].offset
;
605 buf_size
= psGEDLogBuf
->i32BufferCurrent
- buf_offset
;
607 /* Move lines, update offset and update current */
608 for (i
= 0; n
+ i
< psGEDLogBuf
->i32LineCount
; ++i
)
610 psGEDLogBuf
->psLine
[i
] = psGEDLogBuf
->psLine
[n
+ i
];
611 psGEDLogBuf
->psLine
[i
].offset
-= buf_offset
;
613 psGEDLogBuf
->i32LineCurrent
-= n
;
615 /* Move buffers and update current */
616 for (i
= 0; i
< buf_size
; ++i
)
617 psGEDLogBuf
->pcBuffer
[i
] = psGEDLogBuf
->pcBuffer
[buf_offset
+ i
];
618 psGEDLogBuf
->i32BufferCurrent
= buf_size
;
620 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
628 GED_LOG_BUF_HANDLE
ged_log_buf_get(const char* pszName
)
630 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
631 GED_LOG_BUF
*psFound
= NULL
, *psLogBuf
;
635 return (GED_LOG_BUF_HANDLE
)0;
638 read_lock_bh(&gsGEDLogBufList
.sLock
);
640 psList
= &gsGEDLogBufList
.sList_buf
;
641 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
643 psLogBuf
= list_entry(psListEntry
, GED_LOG_BUF
, sList
);
644 if (0 == strcmp(psLogBuf
->acName
, pszName
))
651 read_unlock_bh(&gsGEDLogBufList
.sLock
);
655 return (GED_LOG_BUF_HANDLE
)0;
658 return (GED_LOG_BUF_HANDLE
)psFound
->ui32HashNodeID
;
661 int ged_log_buf_get_early(const char* pszName
, GED_LOG_BUF_HANDLE
*callback_set_handle
)
667 return GED_ERROR_INVALID_PARAMS
;
670 *callback_set_handle
= ged_log_buf_get(pszName
);
672 if (0 == *callback_set_handle
)
674 GED_LOG_LISTEN
*psGEDLogListen
;
676 write_lock_bh(&gsGEDLogBufList
.sLock
);
680 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
681 GED_LOG_BUF
*psFound
= NULL
, *psLogBuf
;
683 psList
= &gsGEDLogBufList
.sList_buf
;
684 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
686 psLogBuf
= list_entry(psListEntry
, GED_LOG_BUF
, sList
);
687 if (0 == strcmp(psLogBuf
->acName
, pszName
))
696 *callback_set_handle
= (GED_LOG_BUF_HANDLE
)psFound
->ui32HashNodeID
;
701 /* add to listen list */
702 psGEDLogListen
= (GED_LOG_LISTEN
*)ged_alloc(sizeof(GED_LOG_LISTEN
));
703 if (NULL
== psGEDLogListen
)
708 psGEDLogListen
->pCBHnd
= callback_set_handle
;
709 snprintf(psGEDLogListen
->acName
, GED_LOG_BUF_NAME_LENGTH
, "%s", pszName
);
710 INIT_LIST_HEAD(&psGEDLogListen
->sList
);
711 list_add(&psGEDLogListen
->sList
, &gsGEDLogBufList
.sList_listen
);
714 write_unlock_bh(&gsGEDLogBufList
.sLock
);
720 //-----------------------------------------------------------------------------
721 void ged_log_buf_free(GED_LOG_BUF_HANDLE hLogBuf
)
723 GED_LOG_BUF
*psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
726 ged_hashtable_remove(ghHashTable
, psGEDLogBuf
->ui32HashNodeID
);
728 write_lock_bh(&gsGEDLogBufList
.sLock
);
729 list_del(&psGEDLogBuf
->sList
);
730 write_unlock_bh(&gsGEDLogBufList
.sLock
);
732 if (psGEDLogBuf
->psEntry
)
734 ged_debugFS_remove_entry(psGEDLogBuf
->psEntry
);
737 ged_free(psGEDLogBuf
->pMemory
, psGEDLogBuf
->i32MemorySize
);
738 ged_free(psGEDLogBuf
, sizeof(GED_LOG_BUF
));
740 GED_LOGI("ged_log_buf_free OK\n");
743 //-----------------------------------------------------------------------------
744 GED_ERROR
ged_log_buf_print(GED_LOG_BUF_HANDLE hLogBuf
, const char *fmt
, ...)
748 GED_LOG_BUF
*psGEDLogBuf
;
752 psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
755 err
= __ged_log_buf_vprint(psGEDLogBuf
, fmt
, args
, psGEDLogBuf
->attrs
);
761 GED_ERROR
ged_log_buf_print2(GED_LOG_BUF_HANDLE hLogBuf
, int i32LogAttrs
, const char *fmt
, ...)
765 GED_LOG_BUF
*psGEDLogBuf
;
769 psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
771 /* clear reserved attrs */
772 i32LogAttrs
&= ~0xff;
775 err
= __ged_log_buf_vprint(psGEDLogBuf
, fmt
, args
, psGEDLogBuf
->attrs
| i32LogAttrs
);
781 //-----------------------------------------------------------------------------
782 GED_ERROR
ged_log_buf_reset(GED_LOG_BUF_HANDLE hLogBuf
)
784 GED_LOG_BUF
*psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
788 spin_lock_irqsave(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
790 psGEDLogBuf
->i32LineCurrent
= 0;
791 psGEDLogBuf
->i32BufferCurrent
= 0;
792 for (i
= 0; i
< psGEDLogBuf
->i32LineCount
; ++i
)
794 psGEDLogBuf
->psLine
[i
].offset
= -1;
797 spin_unlock_irqrestore(&psGEDLogBuf
->sSpinLock
, psGEDLogBuf
->ui32IRQFlags
);
803 //-----------------------------------------------------------------------------
807 //-----------------------------------------------------------------------------
808 static ssize_t
ged_log_write_entry(const char __user
*pszBuffer
, size_t uiCount
, loff_t uiPosition
, void *pvData
)
810 #define GED_LOG_CMD_SIZE 64
811 char acBuffer
[GED_LOG_CMD_SIZE
];
815 if ((0 < uiCount
) && (uiCount
< GED_LOG_CMD_SIZE
))
817 if (0 == ged_copy_from_user(acBuffer
, pszBuffer
, uiCount
))
819 acBuffer
[uiCount
- 1] = '\0';
820 if (strcmp(acBuffer
, "reset") == 0)
822 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
823 write_lock_bh(&gsGEDLogBufList
.sLock
);
824 psList
= &gsGEDLogBufList
.sList_buf
;
825 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
827 GED_LOG_BUF
* psGEDLogBuf
= (GED_LOG_BUF
*)list_entry(psListEntry
, GED_LOG_BUF
, sList
);
828 ged_log_buf_reset(psGEDLogBuf
->ui32HashNodeID
);
830 write_unlock_bh(&gsGEDLogBufList
.sLock
);
832 else if (strcmp(acBuffer
, "profile_dvfs_enable") == 0)
834 ged_profile_dvfs_enable();
836 else if (strcmp(acBuffer
, "profile_dvfs_disable") == 0)
838 ged_profile_dvfs_disable();
840 else if (strcmp(acBuffer
, "profile_dvfs_start") == 0)
842 ged_profile_dvfs_start();
844 else if (strcmp(acBuffer
, "profile_dvfs_stop") == 0)
846 ged_profile_dvfs_stop();
848 else if (sscanf(acBuffer
, "profile_dvfs_ignore_lines %d", &i32Value
) == 1)
850 ged_profile_dvfs_ignore_lines(i32Value
);
852 //else if (...) //for other commands
860 //-----------------------------------------------------------------------------
861 static void* ged_log_seq_start(struct seq_file
*psSeqFile
, loff_t
*puiPosition
)
863 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
864 loff_t uiCurrentPosition
= 0;
866 read_lock_bh(&gsGEDLogBufList
.sLock
);
868 psList
= &gsGEDLogBufList
.sList_buf
;
869 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
871 GED_LOG_BUF
* psGEDLogBuf
= (GED_LOG_BUF
*)list_entry(psListEntry
, GED_LOG_BUF
, sList
);
872 if (psGEDLogBuf
->acName
[0] != '\0')
874 if (uiCurrentPosition
== *puiPosition
)
878 uiCurrentPosition
++;
884 //-----------------------------------------------------------------------------
885 static void ged_log_seq_stop(struct seq_file
*psSeqFile
, void *pvData
)
887 read_unlock_bh(&gsGEDLogBufList
.sLock
);
889 //-----------------------------------------------------------------------------
890 static void* ged_log_seq_next(struct seq_file
*psSeqFile
, void *pvData
, loff_t
*puiPosition
)
892 struct list_head
*psListEntry
, *psListEntryTemp
, *psList
;
893 loff_t uiCurrentPosition
= 0;
897 psList
= &gsGEDLogBufList
.sList_buf
;
898 list_for_each_safe(psListEntry
, psListEntryTemp
, psList
)
900 GED_LOG_BUF
* psGEDLogBuf
= (GED_LOG_BUF
*)list_entry(psListEntry
, GED_LOG_BUF
, sList
);
901 if (psGEDLogBuf
->acName
[0] != '\0')
903 if (uiCurrentPosition
== *puiPosition
)
907 uiCurrentPosition
++;
913 //-----------------------------------------------------------------------------
914 static struct seq_operations gsGEDLogReadOps
=
916 .start
= ged_log_seq_start
,
917 .stop
= ged_log_seq_stop
,
918 .next
= ged_log_seq_next
,
919 .show
= ged_log_buf_seq_show
,
921 //-----------------------------------------------------------------------------
922 GED_ERROR
ged_log_system_init(void)
924 GED_ERROR err
= GED_OK
;
926 err
= ged_debugFS_create_entry(
934 if (unlikely(err
!= GED_OK
))
936 GED_LOGE("ged: failed to create gedlog entry!\n");
940 err
= ged_debugFS_create_entry_dir(
945 if (unlikely(err
!= GED_OK
))
947 err
= GED_ERROR_FAIL
;
948 GED_LOGE("ged: failed to create logbufs dir!\n");
952 ghHashTable
= ged_hashtable_create(5);
956 GED_LOGE("ged: failed to create a hash table!\n");
964 ged_log_system_exit();
968 //-----------------------------------------------------------------------------
969 void ged_log_system_exit(void)
971 ged_hashtable_destroy(ghHashTable
);
973 ged_debugFS_remove_entry(gpsGEDLogEntry
);
975 //-----------------------------------------------------------------------------
976 int ged_log_buf_write(GED_LOG_BUF_HANDLE hLogBuf
, const char __user
*pszBuffer
, int i32Count
)
978 GED_LOG_BUF
*psGEDLogBuf
= ged_log_buf_from_handle(hLogBuf
);
979 return __ged_log_buf_write(psGEDLogBuf
, pszBuffer
, i32Count
);
982 EXPORT_SYMBOL(ged_log_buf_alloc
);
983 EXPORT_SYMBOL(ged_log_buf_reset
);
984 EXPORT_SYMBOL(ged_log_buf_get
);
985 EXPORT_SYMBOL(ged_log_buf_get_early
);
986 EXPORT_SYMBOL(ged_log_buf_free
);
987 EXPORT_SYMBOL(ged_log_buf_print
);
988 EXPORT_SYMBOL(ged_log_buf_print2
);