i2c-s3c2410: Remove unconditional 1ms delay on each transfer
[safe/jmp/linux-2.6] / drivers / scsi / bfa / bfa_log.c
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License (GPL) Version 2 as
10  * published by the Free Software Foundation
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  */
17
18 /**
19  *  bfa_log.c BFA log library
20  */
21
22 #include <bfa_os_inc.h>
23 #include <cs/bfa_log.h>
24
25 /*
26  * global log info structure
27  */
28 struct bfa_log_info_s {
29         u32        start_idx;   /*  start index for a module */
30         u32        total_count; /*  total count for a module */
31         enum bfa_log_severity level;    /*  global log level */
32         bfa_log_cb_t    cbfn;           /*  callback function */
33 };
34
35 static struct bfa_log_info_s bfa_log_info[BFA_LOG_MODULE_ID_MAX + 1];
36 static u32 bfa_log_msg_total_count;
37 static int      bfa_log_initialized;
38
39 static char    *bfa_log_severity[] =
40         { "[none]", "[critical]", "[error]", "[warn]", "[info]", "" };
41
42 /**
43  * BFA log library initialization
44  *
45  * The log library initialization includes the following,
46  *    - set log instance name and callback function
47  *    - read the message array generated from xml files
48  *    - calculate start index for each module
49  *    - calculate message count for each module
50  *    - perform error checking
51  *
52  * @param[in] log_mod - log module info
53  * @param[in] instance_name - instance name
54  * @param[in] cbfn - callback function
55  *
56  * It return 0 on success, or -1 on failure
57  */
58 int
59 bfa_log_init(struct bfa_log_mod_s *log_mod, char *instance_name,
60                         bfa_log_cb_t cbfn)
61 {
62         struct bfa_log_msgdef_s *msg;
63         u32        pre_mod_id = 0;
64         u32        cur_mod_id = 0;
65         u32        i, pre_idx, idx, msg_id;
66
67         /*
68          * set instance name
69          */
70         if (log_mod) {
71                 strncpy(log_mod->instance_info, instance_name,
72                         sizeof(log_mod->instance_info));
73                 log_mod->cbfn = cbfn;
74                 for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++)
75                         log_mod->log_level[i] = BFA_LOG_WARNING;
76         }
77
78         if (bfa_log_initialized)
79                 return 0;
80
81         for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++) {
82                 bfa_log_info[i].start_idx = 0;
83                 bfa_log_info[i].total_count = 0;
84                 bfa_log_info[i].level = BFA_LOG_WARNING;
85                 bfa_log_info[i].cbfn = cbfn;
86         }
87
88         pre_idx = 0;
89         idx = 0;
90         msg = bfa_log_msg_array;
91         msg_id = BFA_LOG_GET_MSG_ID(msg);
92         pre_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
93         while (msg_id != 0) {
94                 cur_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
95
96                 if (cur_mod_id > BFA_LOG_MODULE_ID_MAX) {
97                         cbfn(log_mod, msg_id,
98                                 "%s%s log: module id %u out of range\n",
99                                 BFA_LOG_CAT_NAME,
100                                 bfa_log_severity[BFA_LOG_ERROR],
101                                 cur_mod_id);
102                         return -1;
103                 }
104
105                 if (pre_mod_id > BFA_LOG_MODULE_ID_MAX) {
106                         cbfn(log_mod, msg_id,
107                                 "%s%s log: module id %u out of range\n",
108                                 BFA_LOG_CAT_NAME,
109                                 bfa_log_severity[BFA_LOG_ERROR],
110                                 pre_mod_id);
111                         return -1;
112                 }
113
114                 if (cur_mod_id != pre_mod_id) {
115                         bfa_log_info[pre_mod_id].start_idx = pre_idx;
116                         bfa_log_info[pre_mod_id].total_count = idx - pre_idx;
117                         pre_mod_id = cur_mod_id;
118                         pre_idx = idx;
119                 }
120
121                 idx++;
122                 msg++;
123                 msg_id = BFA_LOG_GET_MSG_ID(msg);
124         }
125
126         bfa_log_info[cur_mod_id].start_idx = pre_idx;
127         bfa_log_info[cur_mod_id].total_count = idx - pre_idx;
128         bfa_log_msg_total_count = idx;
129
130         cbfn(log_mod, msg_id, "%s%s log: init OK, msg total count %u\n",
131                 BFA_LOG_CAT_NAME,
132                 bfa_log_severity[BFA_LOG_INFO], bfa_log_msg_total_count);
133
134         bfa_log_initialized = 1;
135
136         return 0;
137 }
138
139 /**
140  * BFA log set log level for a module
141  *
142  * @param[in] log_mod - log module info
143  * @param[in] mod_id - module id
144  * @param[in] log_level - log severity level
145  *
146  * It return BFA_STATUS_OK on success, or > 0 on failure
147  */
148 bfa_status_t
149 bfa_log_set_level(struct bfa_log_mod_s *log_mod, int mod_id,
150                   enum bfa_log_severity log_level)
151 {
152         if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
153                 return BFA_STATUS_EINVAL;
154
155         if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
156                 return BFA_STATUS_EINVAL;
157
158         if (log_mod)
159                 log_mod->log_level[mod_id] = log_level;
160         else
161                 bfa_log_info[mod_id].level = log_level;
162
163         return BFA_STATUS_OK;
164 }
165
166 /**
167  * BFA log set log level for all modules
168  *
169  * @param[in] log_mod - log module info
170  * @param[in] log_level - log severity level
171  *
172  * It return BFA_STATUS_OK on success, or > 0 on failure
173  */
174 bfa_status_t
175 bfa_log_set_level_all(struct bfa_log_mod_s *log_mod,
176                   enum bfa_log_severity log_level)
177 {
178         int mod_id = BFA_LOG_UNUSED_ID + 1;
179
180         if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
181                 return BFA_STATUS_EINVAL;
182
183         if (log_mod) {
184                 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
185                         log_mod->log_level[mod_id] = log_level;
186         } else {
187                 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
188                         bfa_log_info[mod_id].level = log_level;
189         }
190
191         return BFA_STATUS_OK;
192 }
193
194 /**
195  * BFA log set log level for all aen sub-modules
196  *
197  * @param[in] log_mod - log module info
198  * @param[in] log_level - log severity level
199  *
200  * It return BFA_STATUS_OK on success, or > 0 on failure
201  */
202 bfa_status_t
203 bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod,
204                   enum bfa_log_severity log_level)
205 {
206         int mod_id = BFA_LOG_AEN_MIN + 1;
207
208         if (log_mod) {
209                 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
210                         log_mod->log_level[mod_id] = log_level;
211         } else {
212                 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
213                         bfa_log_info[mod_id].level = log_level;
214         }
215
216         return BFA_STATUS_OK;
217 }
218
219 /**
220  * BFA log get log level for a module
221  *
222  * @param[in] log_mod - log module info
223  * @param[in] mod_id - module id
224  *
225  * It returns log level or -1 on error
226  */
227 enum bfa_log_severity
228 bfa_log_get_level(struct bfa_log_mod_s *log_mod, int mod_id)
229 {
230         if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
231                 return BFA_LOG_INVALID;
232
233         if (log_mod)
234                 return log_mod->log_level[mod_id];
235         else
236                 return bfa_log_info[mod_id].level;
237 }
238
239 enum bfa_log_severity
240 bfa_log_get_msg_level(struct bfa_log_mod_s *log_mod, u32 msg_id)
241 {
242         struct bfa_log_msgdef_s *msg;
243         u32        mod = BFA_LOG_GET_MOD_ID(msg_id);
244         u32        idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
245
246         if (!bfa_log_initialized)
247                 return BFA_LOG_INVALID;
248
249         if (mod > BFA_LOG_MODULE_ID_MAX)
250                 return BFA_LOG_INVALID;
251
252         if (idx >= bfa_log_info[mod].total_count) {
253                 bfa_log_info[mod].cbfn(log_mod, msg_id,
254                         "%s%s log: inconsistent idx %u vs. total count %u\n",
255                         BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
256                         bfa_log_info[mod].total_count);
257                 return BFA_LOG_INVALID;
258         }
259
260         msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
261         if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
262                 bfa_log_info[mod].cbfn(log_mod, msg_id,
263                         "%s%s log: inconsistent msg id %u array msg id %u\n",
264                         BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
265                         msg_id, BFA_LOG_GET_MSG_ID(msg));
266                 return BFA_LOG_INVALID;
267         }
268
269         return BFA_LOG_GET_SEVERITY(msg);
270 }
271
272 /**
273  * BFA log message handling
274  *
275  * BFA log message handling finds the message based on message id and prints
276  * out the message based on its format and arguments. It also does prefix
277  * the severity etc.
278  *
279  * @param[in] log_mod - log module info
280  * @param[in] msg_id - message id
281  * @param[in] ... - message arguments
282  *
283  * It return 0 on success, or -1 on errors
284  */
285 int
286 bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...)
287 {
288         va_list         ap;
289         char            buf[256];
290         struct bfa_log_msgdef_s *msg;
291         int             log_level;
292         u32        mod = BFA_LOG_GET_MOD_ID(msg_id);
293         u32        idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
294
295         if (!bfa_log_initialized)
296                 return -1;
297
298         if (mod > BFA_LOG_MODULE_ID_MAX)
299                 return -1;
300
301         if (idx >= bfa_log_info[mod].total_count) {
302                 bfa_log_info[mod].
303                         cbfn
304                         (log_mod, msg_id,
305                         "%s%s log: inconsistent idx %u vs. total count %u\n",
306                         BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
307                         bfa_log_info[mod].total_count);
308                 return -1;
309         }
310
311         msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
312         if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
313                 bfa_log_info[mod].
314                         cbfn
315                         (log_mod, msg_id,
316                         "%s%s log: inconsistent msg id %u array msg id %u\n",
317                         BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
318                         msg_id, BFA_LOG_GET_MSG_ID(msg));
319                 return -1;
320         }
321
322         log_level = log_mod ? log_mod->log_level[mod] : bfa_log_info[mod].level;
323         if ((BFA_LOG_GET_SEVERITY(msg) > log_level) &&
324                         (msg->attributes != BFA_LOG_ATTR_NONE))
325                 return 0;
326
327         va_start(ap, msg_id);
328         bfa_os_vsprintf(buf, BFA_LOG_GET_MSG_FMT_STRING(msg), ap);
329         va_end(ap);
330
331         if (log_mod)
332                 log_mod->cbfn(log_mod, msg_id, "%s[%s]%s%s %s: %s\n",
333                                 BFA_LOG_CAT_NAME, log_mod->instance_info,
334                                 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
335                                 (msg->attributes & BFA_LOG_ATTR_AUDIT)
336                                 ? " (audit) " : "", msg->msg_value, buf);
337         else
338                 bfa_log_info[mod].cbfn(log_mod, msg_id, "%s%s%s %s: %s\n",
339                                 BFA_LOG_CAT_NAME,
340                                 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
341                                 (msg->attributes & BFA_LOG_ATTR_AUDIT) ?
342                                 " (audit) " : "", msg->msg_value, buf);
343
344         return 0;
345 }
346