]> Pileus Git - ~andy/linux/blob - drivers/staging/dgap/dgap_trace.c
staging: dgap: Fix trailing whitespace in dgap_trace.c
[~andy/linux] / drivers / staging / dgap / dgap_trace.c
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  *
20  *      NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
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  *
27  *      Send any bug fixes/changes to:  Eng.Linux at digi dot com.
28  *      Thank you.
29  *
30  */
31
32 /* $Id: dgap_trace.c,v 1.1 2009/10/23 14:01:57 markh Exp $ */
33
34 #include <linux/kernel.h>
35 #include <linux/sched.h>        /* For jiffies, task states */
36 #include <linux/interrupt.h>    /* For tasklet and interrupt structs/defines */
37 #include <linux/vmalloc.h>
38
39 #include "dgap_driver.h"
40
41 #define TRC_TO_CONSOLE 1
42
43 /* file level globals */
44 static char *dgap_trcbuf;               /* the ringbuffer */
45
46 #if defined(TRC_TO_KMEM)
47 static int dgap_trcbufi = 0;            /* index of the tilde at the end of */
48 #endif
49
50 extern int dgap_trcbuf_size;            /* size of the ringbuffer */
51
52 #if defined(TRC_TO_KMEM)
53 static DEFINE_SPINLOCK(dgap_tracef_lock);
54 #endif
55
56 #if 0
57
58 #if !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE)
59 void dgap_tracef(const char *fmt, ...)
60 {
61         return;
62 }
63
64 #else /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
65
66 void dgap_tracef(const char *fmt, ...)
67 {
68         va_list          ap;
69         char             buf[TRC_MAXMSG+1];
70         size_t           lenbuf;
71         int              i;
72         static int       failed = FALSE;
73 # if defined(TRC_TO_KMEM)
74         unsigned long    flags;
75 #endif
76
77         if(failed)
78                 return;
79 # if defined(TRC_TO_KMEM)
80         DGAP_LOCK(dgap_tracef_lock, flags);
81 #endif
82
83         /* Format buf using fmt and arguments contained in ap. */
84         va_start(ap, fmt);
85         i = vsprintf(buf, fmt,  ap);
86         va_end(ap);
87         lenbuf = strlen(buf);
88
89 # if defined(TRC_TO_KMEM)
90         {
91                 static int       initd=0;
92
93                 /*
94                  * Now, in addition to (or instead of) printing this stuff out
95                  * (which is a buffered operation), also tuck it away into a
96                  * corner of memory which can be examined post-crash in kdb.
97                  */
98                 if (!initd) {
99                         dgap_trcbuf = (char *) vmalloc(dgap_trcbuf_size);
100                         if(!dgap_trcbuf) {
101                                 failed = TRUE;
102                                 printk("dgap: tracing init failed!\n");
103                                 return;
104                         }
105
106                         memset(dgap_trcbuf, '\0',  dgap_trcbuf_size);
107                         dgap_trcbufi = 0;
108                         initd++;
109
110                         printk("dgap: tracing enabled - " TRC_DTRC
111                                 " 0x%lx 0x%x\n",
112                                 (unsigned long)dgap_trcbuf,
113                                 dgap_trcbuf_size);
114                 }
115
116 #  if defined(TRC_ON_OVERFLOW_WRAP_AROUND)
117                 /*
118                  * This is the less CPU-intensive way to do things.  We simply
119                  * wrap around before we fall off the end of the buffer.  A
120                  * tilde (~) demarcates the current end of the trace.
121                  *
122                  * This method should be used if you are concerned about race
123                  * conditions as it is less likely to affect the timing of
124                  * things.
125                  */
126
127                 if (dgap_trcbufi + lenbuf >= dgap_trcbuf_size) {
128                         /* We are wrapping, so wipe out the last tilde. */
129                         dgap_trcbuf[dgap_trcbufi] = '\0';
130                         /* put the new string at the beginning of the buffer */
131                         dgap_trcbufi = 0;
132                 }
133
134                 strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
135                 dgap_trcbufi += lenbuf;
136                 dgap_trcbuf[dgap_trcbufi] = '~';
137
138 #  elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER)
139                 /*
140                  * This is the more CPU-intensive way to do things.  If we
141                  * venture into the last 1/8 of the buffer, we shift the
142                  * last 7/8 of the buffer forward, wiping out the first 1/8.
143                  * Advantage: No wrap-around, only truncation from the
144                  * beginning.
145                  *
146                  * This method should not be used if you are concerned about
147                  * timing changes affecting the behaviour of the driver (ie,
148                  * race conditions).
149                  */
150                 strcpy(&dgap_trcbuf[dgap_trcbufi], buf);
151                 dgap_trcbufi += lenbuf;
152                 dgap_trcbuf[dgap_trcbufi] = '~';
153                 dgap_trcbuf[dgap_trcbufi+1] = '\0';
154
155                 /* If we're near the end of the trace buffer... */
156                 if (dgap_trcbufi > (dgap_trcbuf_size/8)*7) {
157                         /* Wipe out the first eighth to make some more room. */
158                         strcpy(dgap_trcbuf, &dgap_trcbuf[dgap_trcbuf_size/8]);
159                         dgap_trcbufi = strlen(dgap_trcbuf)-1;
160                         /* Plop overflow message at the top of the buffer. */
161                         bcopy(TRC_OVERFLOW, dgap_trcbuf, strlen(TRC_OVERFLOW));
162                 }
163 #  else
164 #   error "TRC_ON_OVERFLOW_WRAP_AROUND or TRC_ON_OVERFLOW_SHIFT_BUFFER?"
165 #  endif
166         }
167         DGAP_UNLOCK(dgap_tracef_lock, flags);
168
169 # endif /* defined(TRC_TO_KMEM) */
170 }
171
172 #endif /* !defined(TRC_TO_KMEM) && !defined(TRC_TO_CONSOLE) */
173
174 #endif
175
176 /*
177  * dgap_tracer_free()
178  *
179  *
180  */
181 void dgap_tracer_free(void)
182 {
183         if(dgap_trcbuf)
184                 vfree(dgap_trcbuf);
185 }