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 */ 28struct 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 35static struct bfa_log_info_s bfa_log_info[BFA_LOG_MODULE_ID_MAX + 1]; 36static u32 bfa_log_msg_total_count; 37static int bfa_log_initialized; 38 39static 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 */ 58int 59bfa_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 */ 148bfa_status_t 149bfa_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 */ 174bfa_status_t 175bfa_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 */ 202bfa_status_t 203bfa_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 */ 227enum bfa_log_severity 228bfa_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 239enum bfa_log_severity 240bfa_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 */ 285int 286bfa_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