Commit | Line | Data |
---|---|---|
7725ccfd JH |
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) | |
f8ceafde | 234 | return log_mod->log_level[mod_id]; |
7725ccfd | 235 | else |
f8ceafde | 236 | return bfa_log_info[mod_id].level; |
7725ccfd JH |
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 |