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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "rge.h" 28 29 /* 30 * Global variable for default debug flags 31 */ 32 uint32_t rge_debug; 33 34 /* 35 * Global mutex used by logging routines below 36 */ 37 kmutex_t rge_log_mutex[1]; 38 39 /* 40 * Static data used by logging routines; protected by <rge_log_mutex> 41 */ 42 static struct { 43 const char *who; 44 const char *fmt; 45 int level; 46 } rge_log_data; 47 48 49 /* 50 * Backend print routine for all the routines below 51 */ 52 static void 53 rge_vprt(const char *fmt, va_list args) 54 { 55 char buf[128]; 56 57 ASSERT(mutex_owned(rge_log_mutex)); 58 59 (void) vsnprintf(buf, sizeof (buf), fmt, args); 60 cmn_err(rge_log_data.level, rge_log_data.fmt, rge_log_data.who, buf); 61 } 62 63 /* 64 * Report a run-time event (CE_NOTE, to console & log) 65 */ 66 void 67 rge_notice(rge_t *rgep, const char *fmt, ...) 68 { 69 va_list args; 70 71 mutex_enter(rge_log_mutex); 72 rge_log_data.who = rgep->ifname; 73 rge_log_data.fmt = "%s: %s"; 74 rge_log_data.level = CE_NOTE; 75 76 va_start(args, fmt); 77 rge_vprt(fmt, args); 78 va_end(args); 79 80 mutex_exit(rge_log_mutex); 81 } 82 83 /* 84 * Log a run-time event (CE_NOTE, log only) 85 */ 86 void 87 rge_log(rge_t *rgep, const char *fmt, ...) 88 { 89 va_list args; 90 91 mutex_enter(rge_log_mutex); 92 rge_log_data.who = rgep->ifname; 93 rge_log_data.fmt = "!%s: %s"; 94 rge_log_data.level = CE_NOTE; 95 96 va_start(args, fmt); 97 rge_vprt(fmt, args); 98 va_end(args); 99 100 mutex_exit(rge_log_mutex); 101 } 102 103 /* 104 * Log a run-time problem (CE_WARN, log only) 105 */ 106 void 107 rge_problem(rge_t *rgep, const char *fmt, ...) 108 { 109 va_list args; 110 111 mutex_enter(rge_log_mutex); 112 rge_log_data.who = rgep->ifname; 113 rge_log_data.fmt = "!%s: %s"; 114 rge_log_data.level = CE_WARN; 115 116 va_start(args, fmt); 117 rge_vprt(fmt, args); 118 va_end(args); 119 120 mutex_exit(rge_log_mutex); 121 } 122 123 /* 124 * Log a programming error (CE_WARN, log only) 125 */ 126 void 127 rge_error(rge_t *rgep, const char *fmt, ...) 128 { 129 va_list args; 130 131 mutex_enter(rge_log_mutex); 132 rge_log_data.who = rgep->ifname; 133 rge_log_data.fmt = "!%s: %s"; 134 rge_log_data.level = CE_WARN; 135 136 va_start(args, fmt); 137 rge_vprt(fmt, args); 138 va_end(args); 139 140 mutex_exit(rge_log_mutex); 141 } 142 143 #if RGE_DEBUGGING 144 145 static void 146 rge_prt(const char *fmt, ...) 147 { 148 va_list args; 149 150 ASSERT(mutex_owned(rge_log_mutex)); 151 152 va_start(args, fmt); 153 rge_vprt(fmt, args); 154 va_end(args); 155 156 mutex_exit(rge_log_mutex); 157 } 158 159 void 160 (*rge_gdb(void))(const char *fmt, ...) 161 { 162 mutex_enter(rge_log_mutex); 163 rge_log_data.who = "rge"; 164 rge_log_data.fmt = "?%s: %s\n"; 165 rge_log_data.level = CE_CONT; 166 167 return (rge_prt); 168 } 169 170 void 171 (*rge_db(rge_t *rgep))(const char *fmt, ...) 172 { 173 mutex_enter(rge_log_mutex); 174 rge_log_data.who = rgep->ifname; 175 rge_log_data.fmt = "?%s: %s\n"; 176 rge_log_data.level = CE_CONT; 177 178 return (rge_prt); 179 } 180 181 /* 182 * Dump a chunk of memory, 16 bytes at a time 183 */ 184 static void 185 minidump(rge_t *rgep, const char *caption, void *dp, uint_t len) 186 { 187 uint32_t buf[4]; 188 uint32_t nbytes; 189 190 rge_log(rgep, "%d bytes of %s at address %p:-", len, caption, dp); 191 192 for (len = MIN(len, rgep->rxbuf_size); len != 0; len -= nbytes) { 193 nbytes = MIN(len, sizeof (buf)); 194 bzero(buf, sizeof (buf)); 195 bcopy(dp, buf, nbytes); 196 rge_log(rgep, "%08x %08x %08x %08x", 197 buf[0], buf[1], buf[2], buf[3]); 198 dp = (caddr_t)dp + nbytes; 199 } 200 } 201 202 void 203 rge_pkt_dump(rge_t *rgep, rge_bd_t *hrbdp, sw_rbd_t *srbdp, const char *msg) 204 { 205 rge_problem(rgep, "driver-detected hardware error: %s", msg); 206 207 minidump(rgep, "hardware descriptor", hrbdp, sizeof (*hrbdp)); 208 209 rge_log(rgep, "PCI address %lx flags_len 0x%x" 210 "vlan_tag 0x%x", 211 hrbdp->host_buf_addr, 212 hrbdp->flags_len, 213 hrbdp->vlan_tag); 214 215 if (srbdp != NULL) { 216 minidump(rgep, "software descriptor", srbdp, sizeof (*srbdp)); 217 218 rge_log(rgep, "PCI address %llx buffer len 0x%x token 0x%x", 219 srbdp->rx_buf->pbuf.cookie.dmac_laddress, 220 srbdp->rx_buf->pbuf.alength, 221 srbdp->rx_buf->pbuf.token); 222 223 minidump(rgep, "packet data", srbdp->rx_buf->pbuf.mem_va, 224 hrbdp->flags_len & RBD_LEN_MASK); 225 } 226 } 227 228 void 229 rge_dbg_enter(rge_t *rgep, const char *s) 230 { 231 uint32_t debug; 232 233 debug = rgep != NULL ? rgep->debug : rge_debug; 234 if (debug & RGE_DBG_STOP) { 235 cmn_err(CE_CONT, "rge_dbg_enter(%p): %s\n", (void *)rgep, s); 236 debug_enter(""); 237 } 238 } 239 240 #endif /* RGE_DEBUGGING */ 241