1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/kmem.h> 28 #include <sys/cmn_err.h> 29 #include <sys/conf.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 #include <sys/ksynch.h> 33 #include <sys/varargs.h> 34 35 #include <sys/ib/clients/eoib/eib_impl.h> 36 37 /* 38 * Defaults 39 */ 40 uint_t eib_log_size = EIB_LOGSZ_DEFAULT; 41 int eib_log_level = EIB_MSGS_DEFAULT | EIB_MSGS_DEBUG; 42 int eib_log_timestamps = 0; 43 44 /* 45 * Debug variables, should not be tunables so allocated debug buffer 46 * and its size remain consistent. 47 */ 48 static kmutex_t eib_debug_buf_lock; 49 static uint8_t *eib_debug_buf; 50 static uint32_t eib_debug_buf_ndx; 51 static uint_t eib_debug_buf_sz = 0; 52 53 /* 54 * Local declarations 55 */ 56 static void eib_log(char *); 57 58 void 59 eib_debug_init(void) 60 { 61 eib_debug_buf_ndx = 0; 62 eib_debug_buf_sz = eib_log_size; 63 eib_debug_buf = kmem_zalloc(eib_debug_buf_sz, KM_SLEEP); 64 65 mutex_init(&eib_debug_buf_lock, NULL, MUTEX_DRIVER, NULL); 66 } 67 68 void 69 eib_debug_fini(void) 70 { 71 mutex_destroy(&eib_debug_buf_lock); 72 73 if (eib_debug_buf && eib_debug_buf_sz) { 74 kmem_free(eib_debug_buf, eib_debug_buf_sz); 75 eib_debug_buf = NULL; 76 } 77 eib_debug_buf_sz = 0; 78 eib_debug_buf_ndx = 0; 79 } 80 81 void 82 eib_log(char *msg) 83 { 84 uint32_t off; 85 int msglen; 86 char msgbuf[EIB_MAX_LINE]; 87 88 if (eib_debug_buf == NULL) 89 return; 90 91 if (eib_log_timestamps) { 92 msglen = snprintf(msgbuf, EIB_MAX_LINE, "%llx: %s", 93 (unsigned long long)ddi_get_lbolt64(), msg); 94 } else { 95 msglen = snprintf(msgbuf, EIB_MAX_LINE, "%s", msg); 96 } 97 98 if (msglen < 0) 99 return; 100 else if (msglen >= EIB_MAX_LINE) 101 msglen = EIB_MAX_LINE - 1; 102 103 mutex_enter(&eib_debug_buf_lock); 104 if ((eib_debug_buf_ndx == 0) || 105 (eib_debug_buf[eib_debug_buf_ndx-1] != '\n')) { 106 eib_debug_buf[eib_debug_buf_ndx] = '\n'; 107 eib_debug_buf_ndx++; 108 } 109 110 off = eib_debug_buf_ndx; /* current msg should go here */ 111 112 eib_debug_buf_ndx += msglen; /* next msg should start here */ 113 eib_debug_buf[eib_debug_buf_ndx] = 0; /* terminate current msg */ 114 115 if (eib_debug_buf_ndx >= (eib_debug_buf_sz - 2 * EIB_MAX_LINE)) 116 eib_debug_buf_ndx = 0; 117 118 mutex_exit(&eib_debug_buf_lock); 119 120 bcopy(msgbuf, eib_debug_buf+off, msglen); /* no lock needed */ 121 } 122 123 #ifdef EIB_DEBUG 124 void 125 eib_dprintf_verbose(int inst, const char *fmt, ...) 126 { 127 va_list ap; 128 int msglen; 129 char msgbuf[EIB_MAX_LINE]; 130 char newfmt[EIB_MAX_LINE]; 131 132 if ((eib_log_level & EIB_MSGS_VERBOSE) != EIB_MSGS_VERBOSE) 133 return; 134 135 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 136 137 va_start(ap, fmt); 138 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 139 va_end(ap); 140 141 if (msglen > 0) { 142 eib_log(msgbuf); 143 } 144 } 145 146 void 147 eib_dprintf_pkt(int inst, uint8_t *pkt, uint_t sz) 148 { 149 char msgbuf[EIB_MAX_LINE]; 150 char *bufp; 151 uint8_t *p = pkt; 152 uint_t len; 153 uint_t i; 154 155 if ((eib_log_level & EIB_MSGS_PKT) != EIB_MSGS_PKT) 156 return; 157 158 while (sz >= 16) { 159 (void) snprintf(msgbuf, EIB_MAX_LINE, 160 "eoib%02d__%02x %02x %02x %02x %02x %02x %02x %02x " 161 "%02x %02x %02x %02x %02x %02x %02x %02x\n", inst, 162 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], 163 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); 164 165 eib_log(msgbuf); 166 167 p += 16; 168 sz -= 16; 169 } 170 171 len = EIB_MAX_LINE; 172 bufp = msgbuf; 173 for (i = 0; i < sz; i++) { 174 if (i == 0) { 175 (void) snprintf(bufp, len, "eoib%02d__%02x ", 176 inst, p[i]); 177 len -= 11; 178 bufp += 11; 179 } else if (i < (sz - 1)) { 180 (void) snprintf(bufp, len, "%02x ", p[i]); 181 len -= 3; 182 bufp += 3; 183 } else { 184 (void) snprintf(bufp, len, "%02x\n", p[i]); 185 len -= 3; 186 bufp += 3; 187 } 188 } 189 190 eib_log(msgbuf); 191 } 192 193 void 194 eib_dprintf_args(int inst, const char *fmt, ...) 195 { 196 va_list ap; 197 int msglen; 198 char msgbuf[EIB_MAX_LINE]; 199 char newfmt[EIB_MAX_LINE]; 200 201 if ((eib_log_level & EIB_MSGS_ARGS) != EIB_MSGS_ARGS) 202 return; 203 204 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 205 206 va_start(ap, fmt); 207 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 208 va_end(ap); 209 210 if (msglen > 0) { 211 eib_log(msgbuf); 212 } 213 } 214 215 void 216 eib_dprintf_debug(int inst, const char *fmt, ...) 217 { 218 va_list ap; 219 int msglen; 220 char msgbuf[EIB_MAX_LINE]; 221 char newfmt[EIB_MAX_LINE]; 222 223 if ((eib_log_level & EIB_MSGS_DEBUG) != EIB_MSGS_DEBUG) 224 return; 225 226 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 227 228 va_start(ap, fmt); 229 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 230 va_end(ap); 231 232 if (msglen > 0) { 233 eib_log(msgbuf); 234 } 235 } 236 #endif 237 238 void 239 eib_dprintf_warn(int inst, const char *fmt, ...) 240 { 241 va_list ap; 242 int msglen; 243 char msgbuf[EIB_MAX_LINE]; 244 char newfmt[EIB_MAX_LINE]; 245 246 if ((eib_log_level & EIB_MSGS_WARN) != EIB_MSGS_WARN) 247 return; 248 249 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 250 251 va_start(ap, fmt); 252 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 253 va_end(ap); 254 255 if (msglen > 0) { 256 eib_log(msgbuf); 257 } 258 } 259 260 void 261 eib_dprintf_err(int inst, const char *fmt, ...) 262 { 263 va_list ap; 264 int msglen; 265 char msgbuf[EIB_MAX_LINE]; 266 char newfmt[EIB_MAX_LINE]; 267 268 if ((eib_log_level & EIB_MSGS_ERR) != EIB_MSGS_ERR) 269 return; 270 271 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 272 273 va_start(ap, fmt); 274 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 275 va_end(ap); 276 277 if (msglen > 0) { 278 eib_log(msgbuf); 279 cmn_err(CE_WARN, "!%s\n", msgbuf); 280 } 281 } 282 283 void 284 eib_dprintf_crit(int inst, const char *fmt, ...) 285 { 286 va_list ap; 287 int msglen; 288 char msgbuf[EIB_MAX_LINE]; 289 char newfmt[EIB_MAX_LINE]; 290 291 if ((eib_log_level & EIB_MSGS_CRIT) != EIB_MSGS_CRIT) 292 return; 293 294 (void) snprintf(newfmt, EIB_MAX_LINE, "eoib%d__%s", inst, fmt); 295 296 va_start(ap, fmt); 297 msglen = vsnprintf(msgbuf, EIB_MAX_LINE, newfmt, ap); 298 va_end(ap); 299 300 if (msglen > 0) { 301 eib_log(msgbuf); 302 cmn_err(CE_PANIC, "!%s\n", msgbuf); 303 } 304 } 305