Merge tag 'stable/for-linus-3.14-rc1-tag' of git://git.kernel.org/pub/scm/linux/kerne...
[deliverable/linux.git] / drivers / staging / dgnc / dgnc_trace.c
CommitLineData
0b99d589
LL
1/*
2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
cfa4ccc9 20 * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
0b99d589
LL
21 *
22 * This is shared code between Digi's CVS archive and the
23 * Linux Kernel sources.
24 * Changing the source just for reformatting needlessly breaks
25 * our CVS diff history.
26 *
cfa4ccc9
LL
27 * Send any bug fixes/changes to: Eng.Linux at digi dot com.
28 * Thank you.
0b99d589
LL
29 *
30 */
31
0b99d589 32#include <linux/kernel.h>
0b99d589
LL
33#include <linux/sched.h> /* For jiffies, task states */
34#include <linux/interrupt.h> /* For tasklet and interrupt structs/defines */
35#include <linux/vmalloc.h>
36
37#include "dgnc_driver.h"
f4ad847a 38#include "dgnc_trace.h"
0b99d589
LL
39
40#define TRC_TO_CONSOLE 1
41
42/* file level globals */
43static char *dgnc_trcbuf; /* the ringbuffer */
44
45#if defined(TRC_TO_KMEM)
46static int dgnc_trcbufi = 0; /* index of the tilde at the end of */
47#endif
48
49#if defined(TRC_TO_KMEM)
50static DEFINE_SPINLOCK(dgnc_tracef_lock);
51#endif
52
53
54#if 0
55
56#if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
57
58void dgnc_tracef(const char *fmt, ...)
59{
60 return;
61}
62
63#else /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
64
65void dgnc_tracef(const char *fmt, ...)
66{
5ba21c46
AI
67 va_list ap;
68 char buf[TRC_MAXMSG+1];
69 size_t lenbuf;
70 int i;
71 static int failed = FALSE;
0b99d589
LL
72# if defined(TRC_TO_KMEM)
73 unsigned long flags;
74#endif
75
5ba21c46 76 if (failed)
0b99d589
LL
77 return;
78# if defined(TRC_TO_KMEM)
79 DGNC_LOCK(dgnc_tracef_lock, flags);
80#endif
81
82 /* Format buf using fmt and arguments contained in ap. */
83 va_start(ap, fmt);
84 i = vsprintf(buf, fmt, ap);
85 va_end(ap);
86 lenbuf = strlen(buf);
87
88# if defined(TRC_TO_KMEM)
89 {
5ba21c46 90 static int initd = 0;
0b99d589
LL
91
92 /*
93 * Now, in addition to (or instead of) printing this stuff out
94 * (which is a buffered operation), also tuck it away into a
95 * corner of memory which can be examined post-crash in kdb.
96 */
97 if (!initd) {
98 dgnc_trcbuf = (char *) vmalloc(dgnc_trcbuf_size);
5ba21c46 99 if (!dgnc_trcbuf) {
0b99d589
LL
100 failed = TRUE;
101 printk("dgnc: tracing init failed!\n");
102 return;
103 }
104
105 memset(dgnc_trcbuf, '\0', dgnc_trcbuf_size);
106 dgnc_trcbufi = 0;
107 initd++;
108
cfa4ccc9 109 printk("dgnc: tracing enabled - " TRC_DTRC
0b99d589 110 " 0x%lx 0x%x\n",
cfa4ccc9 111 (unsigned long)dgnc_trcbuf,
0b99d589
LL
112 dgnc_trcbuf_size);
113 }
114
115# if defined(TRC_ON_OVERFLOW_WRAP_AROUND)
116 /*
117 * This is the less CPU-intensive way to do things. We simply
cfa4ccc9 118 * wrap around before we fall off the end of the buffer. A
0b99d589
LL
119 * tilde (~) demarcates the current end of the trace.
120 *
121 * This method should be used if you are concerned about race
122 * conditions as it is less likely to affect the timing of
123 * things.
124 */
125
126 if (dgnc_trcbufi + lenbuf >= dgnc_trcbuf_size) {
127 /* We are wrapping, so wipe out the last tilde. */
128 dgnc_trcbuf[dgnc_trcbufi] = '\0';
129 /* put the new string at the beginning of the buffer */
130 dgnc_trcbufi = 0;
131 }
132
cfa4ccc9 133 strcpy(&dgnc_trcbuf[dgnc_trcbufi], buf);
0b99d589
LL
134 dgnc_trcbufi += lenbuf;
135 dgnc_trcbuf[dgnc_trcbufi] = '~';
136
137# elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER)
138 /*
139 * This is the more CPU-intensive way to do things. If we
cfa4ccc9 140 * venture into the last 1/8 of the buffer, we shift the
0b99d589
LL
141 * last 7/8 of the buffer forward, wiping out the first 1/8.
142 * Advantage: No wrap-around, only truncation from the
143 * beginning.
144 *
145 * This method should not be used if you are concerned about
146 * timing changes affecting the behaviour of the driver (ie,
147 * race conditions).
148 */
149 strcpy(&dgnc_trcbuf[dgnc_trcbufi], buf);
150 dgnc_trcbufi += lenbuf;
151 dgnc_trcbuf[dgnc_trcbufi] = '~';
152 dgnc_trcbuf[dgnc_trcbufi+1] = '\0';
153
154 /* If we're near the end of the trace buffer... */
155 if (dgnc_trcbufi > (dgnc_trcbuf_size/8)*7) {
156 /* Wipe out the first eighth to make some more room. */
157 strcpy(dgnc_trcbuf, &dgnc_trcbuf[dgnc_trcbuf_size/8]);
158 dgnc_trcbufi = strlen(dgnc_trcbuf)-1;
159 /* Plop overflow message at the top of the buffer. */
160 bcopy(TRC_OVERFLOW, dgnc_trcbuf, strlen(TRC_OVERFLOW));
161 }
162# else
163# error "TRC_ON_OVERFLOW_WRAP_AROUND or TRC_ON_OVERFLOW_SHIFT_BUFFER?"
164# endif
165 }
166 DGNC_UNLOCK(dgnc_tracef_lock, flags);
167
168# endif /* defined(TRC_TO_KMEM) */
169}
170
171#endif /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
172
173#endif
174
175
176/*
177 * dgnc_tracer_free()
178 *
179 *
180 */
181void dgnc_tracer_free(void)
182{
5ba21c46 183 if (dgnc_trcbuf)
0b99d589
LL
184 vfree(dgnc_trcbuf);
185}
This page took 0.076976 seconds and 5 git commands to generate.