1 #ifndef _FTAPE_TRACING_H
2 #define _FTAPE_TRACING_H
3 
4 /*
5  * Copyright (C) 1994-1996 Bas Laarhoven,
6  *           (C) 1996-1997 Claus-Justus Heine.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2, or (at your option)
11  any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; see the file COPYING.  If not, write to
20  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22  *
23  * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-tracing.h,v $
24  * $Revision: 1.2 $
25  * $Date: 1997/10/05 19:18:28 $
26  *
27  *      This file contains definitions that eases the debugging of the
28  *      QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
29  */
30 
31 #include <linux/config.h>
32 #include <linux/kernel.h>
33 
34 /*
35  *  Be very careful with TRACE_EXIT and TRACE_ABORT.
36  *
37  *  if (something) TRACE_EXIT error;
38  *
39  *  will NOT work. Use
40  *
41  *  if (something) {
42  *    TRACE_EXIT error;
43  *  }
44  *
45  *  instead. Maybe a bit dangerous, but save lots of lines of code.
46  */
47 
48 #define LL_X "%d/%d KB"
49 #define LL(x) (unsigned int)((__u64)(x)>>10), (unsigned int)((x)&1023)
50 
51 typedef enum {
52 	ft_t_nil = -1,
53 	ft_t_bug,
54 	ft_t_err,
55 	ft_t_warn,
56 	ft_t_info,
57 	ft_t_noise,
58 	ft_t_flow,
59 	ft_t_fdc_dma,
60 	ft_t_data_flow,
61 	ft_t_any
62 } ft_trace_t;
63 
64 #ifdef  CONFIG_FT_NO_TRACE_AT_ALL
65 /*  the compiler will optimize away most TRACE() macros
66  */
67 #define FT_TRACE_TOP_LEVEL	ft_t_bug
68 #define TRACE_FUN(level)	do {} while(0)
69 #define TRACE_EXIT		return
70 #define TRACE(l, m, i...)						\
71 {									\
72 	if ((ft_trace_t)(l) == FT_TRACE_TOP_LEVEL) {			\
73 		printk(KERN_INFO"ftape"__FILE__"("__FUNCTION__"):\n"	\
74 		       KERN_INFO m".\n" ,##i);				\
75 	}								\
76 }
77 #define SET_TRACE_LEVEL(l)      if ((l) == (l)) do {} while(0)
78 #define TRACE_LEVEL		FT_TRACE_TOP_LEVEL
79 
80 #else
81 
82 #ifdef CONFIG_FT_NO_TRACE
83 /*  the compiler will optimize away many TRACE() macros
84  *  the ftape_simple_trace_call() function simply increments
85  *  the function nest level.
86  */
87 #define FT_TRACE_TOP_LEVEL	ft_t_warn
88 #define TRACE_FUN(level)	ftape_function_nest_level++
89 #define TRACE_EXIT		ftape_function_nest_level--; return
90 
91 #else
92 #ifdef CONFIG_FT_FULL_DEBUG
93 #define FT_TRACE_TOP_LEVEL ft_t_any
94 #else
95 #define FT_TRACE_TOP_LEVEL ft_t_flow
96 #endif
97 #define TRACE_FUN(level)					\
98 	const ft_trace_t _tracing = level;			\
99 	if (ftape_tracing >= (ft_trace_t)(level) &&		\
100 	    (ft_trace_t)(level) <= FT_TRACE_TOP_LEVEL)		\
101 		ftape_trace_call(__FILE__, __FUNCTION__);	\
102 	ftape_function_nest_level ++;
103 
104 #define TRACE_EXIT						\
105 	--ftape_function_nest_level;				\
106 	if (ftape_tracing >= (ft_trace_t)(_tracing) &&		\
107 	    (ft_trace_t)(_tracing) <= FT_TRACE_TOP_LEVEL)	\
108 		ftape_trace_exit(__FILE__, __FUNCTION__);	\
109 	return
110 
111 #endif
112 
113 #define TRACE(l, m, i...)					\
114 {								\
115 	if (ftape_tracing >= (ft_trace_t)(l) &&			\
116 	    (ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) {		\
117 		ftape_trace_log(__FILE__, __FUNCTION__);	\
118 		printk(m".\n" ,##i);				\
119 	}							\
120 }
121 
122 #define SET_TRACE_LEVEL(l) 				\
123 {							\
124 	if ((ft_trace_t)(l) <= FT_TRACE_TOP_LEVEL) {	\
125 		ftape_tracing = (ft_trace_t)(l);	\
126 	} else {					\
127 		ftape_tracing = FT_TRACE_TOP_LEVEL;	\
128 	}						\
129 }
130 #define TRACE_LEVEL    							     \
131 ((ftape_tracing <= FT_TRACE_TOP_LEVEL) ? ftape_tracing : FT_TRACE_TOP_LEVEL)
132 
133 
134 /*      Global variables declared in tracing.c
135  */
136 extern ft_trace_t ftape_tracing;  /* sets default level */
137 extern int ftape_function_nest_level;
138 
139 /*      Global functions declared in tracing.c
140  */
141 extern void ftape_trace_call(const char *file, const char *name);
142 extern void ftape_trace_exit(const char *file, const char *name);
143 extern void ftape_trace_log (const char *file, const char *name);
144 
145 #endif /* !defined(CONFIG_FT_NO_TRACE_AT_ALL) */
146 
147 /*
148  *   Abort with a message.
149  */
150 #define TRACE_ABORT(res, i...)			\
151 {						\
152  	TRACE(i);				\
153 	TRACE_EXIT res;				\
154 }
155 
156 /*   The following transforms the common "if(result < 0) ... " into a
157  *   one-liner.
158  */
159 #define _TRACE_CATCH(level, fun, action)				\
160 {									\
161 	int _res = (fun);						\
162 	if (_res < 0) {							\
163 		do { action /* */ ; } while(0);				\
164 		TRACE_ABORT(_res, level, "%s failed: %d", #fun,	_res);	\
165 	}								\
166 }
167 
168 #define TRACE_CATCH(fun, fail) _TRACE_CATCH(ft_t_err, fun, fail)
169 
170 /*  Abort the current function when signalled. This doesn't belong here,
171  *  but rather into ftape-rw.h (maybe)
172  */
173 #define FT_SIGNAL_EXIT(sig_mask)					\
174 	if (sigtestsetmask(&current->pending.signal, sig_mask)) {	\
175 		TRACE_ABORT(-EINTR,					\
176 			    ft_t_warn,					\
177 			    "interrupted by non-blockable signal");	\
178 	}
179 
180 #endif /* _FTAPE_TRACING_H */
181