Print this page
5255 uts shouldn't open-code ISP2
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/sun4/io/px/px_debug.c
+++ new/usr/src/uts/sun4/io/px/px_debug.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 -#pragma ident "%Z%%M% %I% %E% SMI"
27 -
28 26 /*
29 27 * PCI nexus driver general debug support
30 28 */
29 +#include <sys/sysmacros.h>
31 30 #include <sys/async.h>
32 31 #include <sys/sunddi.h> /* dev_info_t */
33 32 #include <sys/ddi_impldefs.h>
34 33 #include <sys/disp.h>
35 34 #include <sys/archsystm.h> /* getpil() */
36 35 #include "px_obj.h"
37 36
38 37 /*LINTLIBRARY*/
39 38
40 39 #ifdef DEBUG
41 40 uint64_t px_debug_flags = 0;
42 41
43 42 static char *px_debug_sym [] = { /* same sequence as px_debug_bit */
44 43 /* 0 */ "attach",
45 44 /* 1 */ "detach",
46 45 /* 2 */ "map",
47 46 /* 3 */ "nex-ctlops",
48 47
49 48 /* 4 */ "introps",
50 49 /* 5 */ "intx-add",
51 50 /* 6 */ "intx-rem",
52 51 /* 7 */ "intx-intr",
53 52
54 53 /* 8 */ "msiq",
55 54 /* 9 */ "msiq-intr",
56 55 /* 10 */ "msg",
57 56 /* 11 */ "msg-intr",
58 57
59 58 /* 12 */ "msix-add",
60 59 /* 13 */ "msix-rem",
61 60 /* 14 */ "msix-intr",
62 61 /* 15 */ "err",
63 62
64 63 /* 16 */ "dma-alloc",
65 64 /* 17 */ "dma-free",
66 65 /* 18 */ "dma-bind",
67 66 /* 19 */ "dma-unbind",
68 67
69 68 /* 20 */ "chk-dma-mode",
70 69 /* 21 */ "bypass-dma",
71 70 /* 22 */ "fast-dvma",
72 71 /* 23 */ "init_child",
73 72
74 73 /* 24 */ "dma-map",
75 74 /* 25 */ "dma-win",
76 75 /* 26 */ "map-win",
77 76 /* 27 */ "unmap-win",
78 77
79 78 /* 28 */ "dma-ctl",
80 79 /* 29 */ "dma-sync",
81 80 /* 30 */ NULL,
82 81 /* 31 */ NULL,
83 82
84 83 /* 32 */ "ib",
85 84 /* 33 */ "cb",
86 85 /* 34 */ "dmc",
87 86 /* 35 */ "pec",
88 87
89 88 /* 36 */ "ilu",
90 89 /* 37 */ "tlu",
91 90 /* 38 */ "lpu",
92 91 /* 39 */ "mmu",
93 92
94 93 /* 40 */ "open",
95 94 /* 41 */ "close",
96 95 /* 42 */ "ioctl",
97 96 /* 43 */ "pwr",
98 97
99 98 /* 44 */ "lib-cfg",
100 99 /* 45 */ "lib-intr",
101 100 /* 46 */ "lib-dma",
102 101 /* 47 */ "lib-msiq",
103 102
104 103 /* 48 */ "lib-msi",
105 104 /* 49 */ "lib-msg",
106 105 /* 50 */ "NULL",
107 106 /* 51 */ "NULL",
108 107
109 108 /* 52 */ "tools",
110 109 /* 53 */ "phys_acc",
111 110
112 111 /* 54 */ "hotplug",
113 112 /* LAST */ "unknown"
114 113 };
115 114
116 115 /* Tunables */
117 116 static int px_dbg_msg_size = 16; /* # of Qs. Must be ^2 */
118 117
119 118 /* Non-Tunables */
120 119 static int px_dbg_qmask = 0xFFFF; /* Mask based on Q size */
121 120 static px_dbg_msg_t *px_dbg_msgq = NULL; /* Debug Msg Queue */
122 121 static uint8_t px_dbg_reference = 0; /* Reference Counter */
123 122 static kmutex_t px_dbg_mutex; /* Mutex for dequeuing */
124 123 static uint8_t px_dbg_qtail = 0; /* Pointer to q tail */
125 124 static uint8_t px_dbg_qhead = 0; /* Pointer to q head */
126 125 static uint_t px_dbg_qsize = 0; /* # of pending messages */
127 126 static uint_t px_dbg_failed = 0; /* # of overflows */
128 127
129 128 /* Forward Declarations */
130 129 static void px_dbg_print(px_debug_bit_t bit, dev_info_t *dip, char *fmt,
131 130 va_list args);
132 131 static void px_dbg_queue(px_debug_bit_t bit, dev_info_t *dip, char *fmt,
133 132 va_list args);
134 133 static uint_t px_dbg_drain(caddr_t arg1, caddr_t arg2);
135 134
136 135 /*
137 136 * Print function called either directly by px_dbg or through soft interrupt.
138 137 * This function cannot be called directly in threads with PIL above clock.
139 138 */
140 139 static void
141 140 px_dbg_print(px_debug_bit_t bit, dev_info_t *dip, char *fmt, va_list args)
142 141 {
143 142 int cont = bit >> DBG_BITS;
144 143
145 144 if (cont)
146 145 goto body;
147 146
148 147 if (dip)
149 148 prom_printf("%s(%d): %s: ", ddi_driver_name(dip),
150 149 ddi_get_instance(dip), px_debug_sym[bit]);
151 150 else
152 151 prom_printf("px: %s: ", px_debug_sym[bit]);
153 152 body:
154 153 if (args)
155 154 prom_vprintf(fmt, args);
156 155 else
157 156 prom_printf(fmt);
158 157 }
159 158
160 159 /*
161 160 * Queueing mechanism to log px_dbg messages if calling thread is running with a
162 161 * PIL above clock. It's Multithreaded safe.
163 162 */
164 163 static void
165 164 px_dbg_queue(px_debug_bit_t bit, dev_info_t *dip, char *fmt, va_list args)
166 165 {
167 166 int instance = DIP_TO_INST(dip);
168 167 px_t *px_p = INST_TO_STATE(instance);
169 168 uint8_t q_no;
170 169 px_dbg_msg_t *msg_p;
171 170
172 171 /* Check to make sure the queue hasn't overflowed */
173 172 if (atomic_inc_uint_nv(&px_dbg_qsize) >= px_dbg_msg_size) {
174 173 px_dbg_failed++;
175 174 atomic_dec_uint(&px_dbg_qsize);
176 175 return;
177 176 }
178 177
179 178 /*
180 179 * Grab the next available queue bucket. Incrementing the tail here
181 180 * doesn't need to be protected, as it is guaranteed to not overflow.
182 181 */
183 182 q_no = ++px_dbg_qtail & px_dbg_qmask;
184 183 msg_p = &px_dbg_msgq[q_no];
185 184
186 185 ASSERT(msg_p->active == B_FALSE);
187 186
188 187 /* Print the message in the buffer */
189 188 vsnprintf(msg_p->msg, DBG_MSG_SIZE, fmt, args);
190 189 msg_p->bit = bit;
191 190 msg_p->dip = dip;
192 191 msg_p->active = B_TRUE;
193 192
194 193 /* Trigger Soft Int */
195 194 ddi_intr_trigger_softint(px_p->px_dbg_hdl, (caddr_t)NULL);
196 195 }
197 196
198 197 /*
199 198 * Callback function for queuing px_dbg in high PIL by soft intr. This code
200 199 * assumes it will be called serially for every msg.
201 200 */
202 201 static uint_t
203 202 px_dbg_drain(caddr_t arg1, caddr_t arg2) {
204 203 uint8_t q_no;
205 204 px_dbg_msg_t *msg_p;
206 205 uint_t ret = DDI_INTR_UNCLAIMED;
207 206
208 207 mutex_enter(&px_dbg_mutex);
209 208 while (px_dbg_qsize) {
210 209 atomic_dec_uint(&px_dbg_qsize);
211 210 if (px_dbg_failed) {
212 211 cmn_err(CE_WARN, "%d msg(s) were lost",
213 212 px_dbg_failed);
214 213 px_dbg_failed = 0;
215 214 }
216 215
217 216 q_no = ++px_dbg_qhead & px_dbg_qmask;
218 217 msg_p = &px_dbg_msgq[q_no];
219 218
220 219 if (msg_p->active) {
221 220 px_dbg_print(msg_p->bit, msg_p->dip, msg_p->msg, NULL);
222 221 msg_p->active = B_FALSE;
223 222 }
224 223 ret = DDI_INTR_CLAIMED;
225 224 }
226 225
227 226 mutex_exit(&px_dbg_mutex);
228 227 return (ret);
229 228 }
230 229
231 230 void
232 231 px_dbg(px_debug_bit_t bit, dev_info_t *dip, char *fmt, ...)
233 232 {
234 233 va_list ap;
235 234
236 235 bit &= DBG_MASK;
237 236 if (bit >= sizeof (px_debug_sym) / sizeof (char *))
238 237 return;
239 238 if (!(1ull << bit & px_debug_flags))
240 239 return;
241 240
242 241 va_start(ap, fmt);
243 242 if (getpil() > LOCK_LEVEL)
244 243 px_dbg_queue(bit, dip, fmt, ap);
245 244 else
246 245 px_dbg_print(bit, dip, fmt, ap);
247 246 va_end(ap);
248 247 }
↓ open down ↓ |
208 lines elided |
↑ open up ↑ |
249 248 #endif /* DEBUG */
250 249
251 250 void
252 251 px_dbg_attach(dev_info_t *dip, ddi_softint_handle_t *dbg_hdl)
253 252 {
254 253 #ifdef DEBUG
255 254 if (px_dbg_reference++ == 0) {
256 255 int size = px_dbg_msg_size;
257 256
258 257 /* Check if px_dbg_msg_size is ^2 */
259 - size = (size & (size - 1)) ? ((size | ~size) + 1) : size;
258 + size = !ISP2(size) ? ((size | ~size) + 1) : size;
260 259 px_dbg_msg_size = size;
261 260 px_dbg_qmask = size - 1;
262 261 px_dbg_msgq = kmem_zalloc(sizeof (px_dbg_msg_t) * size,
263 262 KM_SLEEP);
264 263
265 264 mutex_init(&px_dbg_mutex, NULL, MUTEX_DRIVER, NULL);
266 265 }
267 266
268 267 if (ddi_intr_add_softint(dip, dbg_hdl,
269 268 DDI_INTR_SOFTPRI_MAX, px_dbg_drain, NULL) != DDI_SUCCESS) {
270 269 DBG(DBG_ATTACH, dip,
271 270 "Unable to allocate soft int for DBG printing.\n");
272 271 dbg_hdl = NULL;
273 272 }
274 273 #endif /* DEBUG */
275 274 }
276 275
277 276 /* ARGSUSED */
278 277 void
279 278 px_dbg_detach(dev_info_t *dip, ddi_softint_handle_t *dbg_hdl)
280 279 {
281 280 #ifdef DEBUG
282 281 if (dbg_hdl != NULL)
283 282 (void) ddi_intr_remove_softint(*dbg_hdl);
284 283
285 284 if (--px_dbg_reference == 0) {
286 285 if (px_dbg_msgq != NULL)
287 286 kmem_free(px_dbg_msgq,
288 287 sizeof (px_dbg_msg_t) * px_dbg_msg_size);
289 288 mutex_destroy(&px_dbg_mutex);
290 289 }
291 290 #endif /* DEBUG */
292 291 }
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX