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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/ksynch.h>
28 #include <sys/kmem.h>
29 #include <sys/errno.h>
30 #include <sys/ddi.h>
31
32 #include <sys/mdb_modapi.h>
33
34 #define __NSC_GEN__
35 #include <sys/nsc_thread.h>
36 #include <sys/nsctl/nsc_dev.h>
37 #include <sys/nsctl/nsc_gen.h>
38 #include <sys/nsctl/nsc_mem.h>
39 #include <sys/nsctl/nsctl.h>
40 #include <sys/nsctl/nsc_disk.h>
41
42
43 /*
44 * Data struct for the complex walks.
45 */
46
47 struct complex_args {
48 int argc;
49 mdb_arg_t *argv;
50 };
51
52
53 /*
54 * Bit definitions
55 */
56
57 #define NSC_RW_BITS \
58 { "NSC_READ", NSC_READ, NSC_READ }, \
59 { "NSC_WRITE", NSC_WRITE, NSC_WRITE }
60
61
62 static const mdb_bitmask_t nsc_bhflag_bits[] = {
63 NSC_RW_BITS,
64 { "NSC_PINNABLE", NSC_PINNABLE, NSC_PINNABLE },
65 { "NSC_NOBLOCK", NSC_NOBLOCK, NSC_NOBLOCK },
66 { "NSC_HALLOCATED", NSC_HALLOCATED, NSC_HALLOCATED },
67 { "NSC_HACTIVE", NSC_HACTIVE, NSC_HACTIVE },
68 { "NSC_BCOPY", NSC_BCOPY, NSC_BCOPY },
69 { "NSC_PAGEIO", NSC_PAGEIO, NSC_PAGEIO },
70 { "NSC_ABUF", NSC_ABUF, NSC_ABUF },
71 { "NSC_MIXED", NSC_MIXED, NSC_MIXED },
72 { "NSC_WRTHRU", NSC_WRTHRU, NSC_WRTHRU },
73 { "NSC_FORCED_WRTHRU", NSC_FORCED_WRTHRU, NSC_FORCED_WRTHRU },
74 { "NSC_NOCACHE", NSC_NOCACHE, NSC_NOCACHE },
75 { "NSC_QUEUE", NSC_QUEUE, NSC_QUEUE },
76 { "NSC_RDAHEAD", NSC_RDAHEAD, NSC_RDAHEAD },
77 { "NSC_NO_FORCED_WRTHRU", NSC_NO_FORCED_WRTHRU, NSC_NO_FORCED_WRTHRU },
78 { "NSC_METADATA", NSC_METADATA, NSC_METADATA },
79 { "NSC_SEQ_IO", NSC_SEQ_IO, NSC_SEQ_IO },
80 { NULL, 0, 0 }
81 };
82
83
84 static const mdb_bitmask_t nsc_fdflag_bits[] = {
85 NSC_RW_BITS,
86 { NULL, 0, 0 }
87 };
88
89
90 static const mdb_bitmask_t nsc_fdmode_bits[] = {
91 { "NSC_MULTI", NSC_MULTI, NSC_MULTI },
92 { NULL, 0, 0 }
93 };
94
95
96 static const mdb_bitmask_t nsc_type_bits[] = {
97 /* types */
98 { "NSC_NULL", NSC_NULL, NSC_NULL },
99 { "NSC_DEVICE", NSC_DEVICE, NSC_DEVICE },
100 { "NSC_FILE", NSC_FILE, NSC_FILE },
101 { "NSC_CACHE", NSC_CACHE, NSC_CACHE },
102 { "NSC_VCHR", NSC_VCHR, NSC_VCHR },
103 { "NSC_NCALL", NSC_NCALL, NSC_NCALL },
104
105 /* type flags */
106 { "NSC_ANON", NSC_ANON, NSC_ANON },
107
108 /* ids */
109 { "NSC_RAW_ID", NSC_RAW_ID, NSC_RAW_ID },
110 { "NSC_FILE_ID", NSC_FILE_ID, NSC_FILE_ID },
111 { "NSC_FREEZE_ID", NSC_FREEZE_ID, NSC_FREEZE_ID },
112 { "NSC_VCHR_ID", NSC_VCHR_ID, NSC_VCHR_ID },
113 { "NSC_NCALL_ID", NSC_NCALL_ID, NSC_NCALL_ID },
114 { "NSC_SDBC_ID", NSC_SDBC_ID, NSC_SDBC_ID },
115 { "NSC_RDCLR_ID", NSC_RDCLR_ID, NSC_RDCLR_ID },
116 { "NSC_RDCL_ID", NSC_RDCL_ID, NSC_RDCL_ID },
117 { "NSC_IIR_ID", NSC_IIR_ID, NSC_IIR_ID },
118 { "NSC_II_ID", NSC_II_ID, NSC_II_ID },
119 { "NSC_RDCHR_ID", NSC_RDCHR_ID, NSC_RDCHR_ID },
120 { "NSC_RDCH_ID", NSC_RDCH_ID, NSC_RDCH_ID },
121 { NULL, 0, 0 }
122 };
123
124
125 static const mdb_bitmask_t nsc_availpend_bits[] = {
126 NSC_RW_BITS,
127 { "_NSC_OPEN", _NSC_OPEN, _NSC_OPEN },
128 { "_NSC_CLOSE", _NSC_CLOSE, _NSC_CLOSE },
129 { "_NSC_PINNED", _NSC_PINNED, _NSC_PINNED },
130 { "_NSC_ATTACH", _NSC_ATTACH, _NSC_ATTACH },
131 { "_NSC_DETACH", _NSC_DETACH, _NSC_DETACH },
132 { "_NSC_OWNER", _NSC_OWNER, _NSC_OWNER },
133 { NULL, 0, 0 }
134 };
135
136
137 static const mdb_bitmask_t nsc_ioflag_bits[] = {
138 { "NSC_REFCNT", NSC_REFCNT, NSC_REFCNT },
139 { "NSC_FILTER", NSC_FILTER, NSC_FILTER },
140 { NULL, 0, 0 }
141 };
142
143
144 static const mdb_bitmask_t nstset_flag_bits[] = {
145 { "NST_SF_KILL", NST_SF_KILL, NST_SF_KILL },
146 { NULL, 0, 0 }
147 };
148
149
150 static const mdb_bitmask_t nst_flag_bits[] = {
151 { "NST_TF_INUSE", NST_TF_INUSE, NST_TF_INUSE },
152 { "NST_TF_ACTIVE", NST_TF_ACTIVE, NST_TF_ACTIVE },
153 { "NST_TF_PENDING", NST_TF_PENDING, NST_TF_PENDING },
154 { "NST_TF_DESTROY", NST_TF_DESTROY, NST_TF_DESTROY },
155 { "NST_TF_KILL", NST_TF_KILL, NST_TF_KILL },
156 { NULL, 0, 0 }
157 };
158
159
160 /*
161 * Global data.
162 */
163
164 static nsc_mem_t type_mem[20];
165 static int complex_walk;
166 static int complex_hdr;
167
168
169 /* ---------------------------------------------------------------------- */
170
171 /*
172 * Walker for an nsc_io chain.
173 * A global walk is assumed to start at _nsc_io_top.
174 */
175
176 static int
nsc_io_winit(mdb_walk_state_t * wsp)177 nsc_io_winit(mdb_walk_state_t *wsp)
178 {
179 if (wsp->walk_addr == NULL &&
180 mdb_readvar(&wsp->walk_addr, "_nsc_io_top") == -1) {
181 mdb_warn("unable to read '_nsc_io_top'");
182 return (WALK_ERR);
183 }
184
185 return (WALK_NEXT);
186 }
187
188
189 static int
nsc_io_wstep(mdb_walk_state_t * wsp)190 nsc_io_wstep(mdb_walk_state_t *wsp)
191 {
192 uintptr_t next;
193 int status;
194
195 if (wsp->walk_addr == NULL)
196 return (WALK_DONE);
197
198 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
199 wsp->walk_cbdata);
200
201 next = wsp->walk_addr + OFFSETOF(nsc_io_t, next);
202
203 if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) {
204 mdb_warn("failed to read nsc_io_t.next at %p", next);
205 return (WALK_DONE);
206 }
207
208 return (status);
209 }
210
211
212 /* ---------------------------------------------------------------------- */
213
214 /*
215 * Walker for an nsc_dev chain.
216 * A global walk is assumed to start at _nsc_dev_top.
217 */
218
219 static int
nsc_dev_winit(mdb_walk_state_t * wsp)220 nsc_dev_winit(mdb_walk_state_t *wsp)
221 {
222 if (wsp->walk_addr == NULL &&
223 mdb_readvar(&wsp->walk_addr, "_nsc_dev_top") == -1) {
224 mdb_warn("unable to read '_nsc_dev_top'");
225 return (WALK_ERR);
226 }
227
228 return (WALK_NEXT);
229 }
230
231
232 static int
nsc_dev_wstep(mdb_walk_state_t * wsp)233 nsc_dev_wstep(mdb_walk_state_t *wsp)
234 {
235 uintptr_t next;
236 int status;
237
238 if (wsp->walk_addr == NULL)
239 return (WALK_DONE);
240
241 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
242 wsp->walk_cbdata);
243
244 next = wsp->walk_addr + OFFSETOF(nsc_dev_t, nsc_next);
245
246 if (mdb_vread(&wsp->walk_addr, sizeof (uintptr_t), next) == -1) {
247 mdb_warn("failed to read nsc_dev_t.nsc_next at %p", next);
248 return (WALK_DONE);
249 }
250
251 return (status);
252 }
253
254
255 /* ARGSUSED */
256
257 static void
nsc_dev_wfini(mdb_walk_state_t * wsp)258 nsc_dev_wfini(mdb_walk_state_t *wsp)
259 {
260 complex_walk = 0;
261 }
262
263
264 /* ---------------------------------------------------------------------- */
265
266 /*
267 * Walker for a chain of nsc_devval_t structures.
268 * Global walks start from _nsc_devval_top;
269 */
270
271 static int
nsc_devval_winit(mdb_walk_state_t * wsp)272 nsc_devval_winit(mdb_walk_state_t *wsp)
273 {
274 if (wsp->walk_addr == NULL &&
275 mdb_readvar(&wsp->walk_addr, "_nsc_devval_top") == -1) {
276 mdb_warn("unable to read '_nsc_devval_top'");
277 return (WALK_ERR);
278 }
279
280 return (WALK_NEXT);
281 }
282
283
284 static int
nsc_devval_wstep(mdb_walk_state_t * wsp)285 nsc_devval_wstep(mdb_walk_state_t *wsp)
286 {
287 uintptr_t devval = wsp->walk_addr;
288 int status;
289
290 if (!devval)
291 return (WALK_DONE);
292
293 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
294 wsp->walk_cbdata);
295
296 /* move on to next devval */
297
298 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
299 devval + OFFSETOF(nsc_devval_t, dv_next)) == -1) {
300 mdb_warn("failed to read nsc_devval_t.dv_next");
301 return (WALK_ERR);
302 }
303
304 return (status);
305 }
306
307
308 /* ---------------------------------------------------------------------- */
309
310 /*
311 * Walker for a chain of nsc_fd_t structures.
312 * No global walks.
313 */
314
315 static int
nsc_fd_winit(mdb_walk_state_t * wsp)316 nsc_fd_winit(mdb_walk_state_t *wsp)
317 {
318 if (wsp->walk_addr == NULL) {
319 mdb_warn("nsc_fd doesn't support global walks");
320 return (WALK_ERR);
321 }
322
323 return (WALK_NEXT);
324 }
325
326
327 static int
nsc_fd_wstep(mdb_walk_state_t * wsp)328 nsc_fd_wstep(mdb_walk_state_t *wsp)
329 {
330 uintptr_t fd = wsp->walk_addr;
331 int status;
332
333 if (!fd)
334 return (WALK_DONE);
335
336 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
337 wsp->walk_cbdata);
338
339 /* move on to next fd */
340
341 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
342 fd + OFFSETOF(nsc_fd_t, sf_next)) == -1) {
343 mdb_warn("failed to read nsc_fd_t.sf_next");
344 return (WALK_ERR);
345 }
346
347 return (status);
348 }
349
350
351 /* ---------------------------------------------------------------------- */
352
353 /*
354 * Walker for a chain of nsc_iodev_t structures.
355 * No global walks.
356 */
357
358 static int
nsc_iodev_winit(mdb_walk_state_t * wsp)359 nsc_iodev_winit(mdb_walk_state_t *wsp)
360 {
361 if (wsp->walk_addr == NULL) {
362 mdb_warn("nsc_iodev doesn't support global walks");
363 return (WALK_ERR);
364 }
365
366 return (WALK_NEXT);
367 }
368
369
370 static int
nsc_iodev_wstep(mdb_walk_state_t * wsp)371 nsc_iodev_wstep(mdb_walk_state_t *wsp)
372 {
373 uintptr_t iodev = wsp->walk_addr;
374 int status;
375
376 if (!iodev)
377 return (WALK_DONE);
378
379 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
380 wsp->walk_cbdata);
381
382 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
383 iodev + OFFSETOF(nsc_iodev_t, si_next)) == -1) {
384 mdb_warn("failed to read nsc_iodev_t.si_next");
385 return (WALK_ERR);
386 }
387
388 return (status);
389 }
390
391
392 /* ---------------------------------------------------------------------- */
393
394 /*
395 * Walker for a chain of nsc_service_t structures.
396 * Global walks start at _nsc_services.
397 */
398
399 static int
nsc_service_winit(mdb_walk_state_t * wsp)400 nsc_service_winit(mdb_walk_state_t *wsp)
401 {
402 if (wsp->walk_addr == NULL &&
403 mdb_readvar(&wsp->walk_addr, "_nsc_services") == -1) {
404 mdb_warn("unable to read '_nsc_services'");
405 return (WALK_ERR);
406 }
407
408 return (WALK_NEXT);
409 }
410
411
412 static int
nsc_service_wstep(mdb_walk_state_t * wsp)413 nsc_service_wstep(mdb_walk_state_t *wsp)
414 {
415 uintptr_t service = wsp->walk_addr;
416 int status;
417
418 if (!service)
419 return (WALK_DONE);
420
421 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
422 wsp->walk_cbdata);
423
424 /* move on to next service */
425
426 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
427 service + OFFSETOF(nsc_service_t, s_next)) == -1) {
428 mdb_warn("failed to read nsc_service_t.s_next");
429 return (WALK_ERR);
430 }
431
432 return (status);
433 }
434
435
436 /* ---------------------------------------------------------------------- */
437
438 /*
439 * Walker for a chain of nsc_svc_t structures.
440 * No global walks.
441 */
442
443 static int
nsc_svc_winit(mdb_walk_state_t * wsp)444 nsc_svc_winit(mdb_walk_state_t *wsp)
445 {
446 if (wsp->walk_addr == NULL) {
447 mdb_warn("nsc_svc does not support global walks");
448 return (WALK_ERR);
449 }
450
451 return (WALK_NEXT);
452 }
453
454
455 static int
nsc_svc_wstep(mdb_walk_state_t * wsp)456 nsc_svc_wstep(mdb_walk_state_t *wsp)
457 {
458 uintptr_t svc = wsp->walk_addr;
459 int status;
460
461 if (!svc)
462 return (WALK_DONE);
463
464 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
465 wsp->walk_cbdata);
466
467 /* move on to next svc */
468
469 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
470 svc + OFFSETOF(nsc_svc_t, svc_next)) == -1) {
471 mdb_warn("failed to read nsc_svc_t.svc_next");
472 return (WALK_ERR);
473 }
474
475 return (status);
476 }
477
478
479 /* ---------------------------------------------------------------------- */
480
481 /*
482 * Walker for a chain of nsc_val_t structures.
483 * No global walks.
484 */
485
486 static int
nsc_val_winit(mdb_walk_state_t * wsp)487 nsc_val_winit(mdb_walk_state_t *wsp)
488 {
489 if (wsp->walk_addr == NULL) {
490 mdb_warn("nsc_val doesn't support global walks");
491 return (WALK_ERR);
492 }
493
494 return (WALK_NEXT);
495 }
496
497
498 static int
nsc_val_wstep(mdb_walk_state_t * wsp)499 nsc_val_wstep(mdb_walk_state_t *wsp)
500 {
501 uintptr_t val = wsp->walk_addr;
502 int status;
503
504 if (!val)
505 return (WALK_DONE);
506
507 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
508 wsp->walk_cbdata);
509
510 /* move on to next val */
511
512 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
513 val + OFFSETOF(nsc_val_t, sv_next)) == -1) {
514 mdb_warn("failed to read nsc_val_t.sv_next");
515 return (WALK_ERR);
516 }
517
518 return (status);
519 }
520
521
522 /* ---------------------------------------------------------------------- */
523
524 /*
525 * Walker for a chain of nstset_t structures.
526 * Global walks start at _nst_sets.
527 */
528
529 static int
nstset_winit(mdb_walk_state_t * wsp)530 nstset_winit(mdb_walk_state_t *wsp)
531 {
532 if (wsp->walk_addr == NULL &&
533 mdb_readvar(&wsp->walk_addr, "nst_sets") == -1) {
534 mdb_warn("unable to read 'nst_sets'");
535 return (WALK_ERR);
536 }
537
538 return (WALK_NEXT);
539 }
540
541
542 static int
nstset_wstep(mdb_walk_state_t * wsp)543 nstset_wstep(mdb_walk_state_t *wsp)
544 {
545 uintptr_t set = wsp->walk_addr;
546 int status;
547
548 if (!set)
549 return (WALK_DONE);
550
551 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
552 wsp->walk_cbdata);
553
554 /* move on to next set */
555
556 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
557 set + OFFSETOF(nstset_t, set_next)) == -1) {
558 mdb_warn("failed to read nstset_t.set_next");
559 return (WALK_ERR);
560 }
561
562 return (status);
563 }
564
565
566 /* ---------------------------------------------------------------------- */
567
568 /*
569 * Walker for a chain of nsthread_t structures.
570 * No global walks.
571 */
572
573 static int
nsthread_winit(mdb_walk_state_t * wsp)574 nsthread_winit(mdb_walk_state_t *wsp)
575 {
576 if (wsp->walk_addr == NULL) {
577 mdb_warn("nsthread does not support global walks");
578 return (WALK_ERR);
579 }
580
581 return (WALK_NEXT);
582 }
583
584
585 static int
nsthread_wstep(mdb_walk_state_t * wsp)586 nsthread_wstep(mdb_walk_state_t *wsp)
587 {
588 uintptr_t thread = wsp->walk_addr;
589 int status;
590
591 if (!thread)
592 return (WALK_DONE);
593
594 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
595 wsp->walk_cbdata);
596
597 /* move on to next iodev */
598
599 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
600 thread + OFFSETOF(nsthread_t, tp_chain)) == -1) {
601 mdb_warn("failed to read nsthread_t.tp_chain");
602 return (WALK_ERR);
603 }
604
605 return (status);
606 }
607
608
609 /* ---------------------------------------------------------------------- */
610
611 /*
612 * Walker for nsthread_t free/reuse chain.
613 * No global walks.
614 */
615
616 static int
nst_free_winit(mdb_walk_state_t * wsp)617 nst_free_winit(mdb_walk_state_t *wsp)
618 {
619 if (wsp->walk_addr == NULL) {
620 mdb_warn("nst_free does not support global walks");
621 return (WALK_ERR);
622 }
623
624 /* store starting address */
625
626 wsp->walk_data = (void *)wsp->walk_addr;
627
628 /* move on to next thread */
629
630 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
631 wsp->walk_addr + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) {
632 mdb_warn("failed to read nsthread_t.tp_link.q_forw");
633 return (WALK_ERR);
634 }
635
636 return (WALK_NEXT);
637 }
638
639
640 static int
nst_free_wstep(mdb_walk_state_t * wsp)641 nst_free_wstep(mdb_walk_state_t *wsp)
642 {
643 uintptr_t thread = wsp->walk_addr;
644 int status;
645
646 if (!thread)
647 return (WALK_DONE);
648
649 if (thread == (uintptr_t)wsp->walk_data)
650 return (WALK_DONE);
651
652 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
653 wsp->walk_cbdata);
654
655 /* move on to next thread */
656
657 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
658 thread + OFFSETOF(nsthread_t, tp_link.q_forw)) == -1) {
659 mdb_warn("failed to read nsthread_t.tp_link.q_forw");
660 return (WALK_ERR);
661 }
662
663 return (status);
664 }
665
666
667 /* ---------------------------------------------------------------------- */
668
669 /*
670 * Walker for a chain of nsc_mem_t structures.
671 * Global walks start at _nsc_mem_top.
672 */
673
674 static int
nsc_mem_winit(mdb_walk_state_t * wsp)675 nsc_mem_winit(mdb_walk_state_t *wsp)
676 {
677 if (wsp->walk_addr == NULL &&
678 mdb_readvar(&wsp->walk_addr, "_nsc_mem_top") == -1) {
679 mdb_warn("unable to read '_nsc_mem_top'");
680 return (WALK_ERR);
681 }
682
683 return (WALK_NEXT);
684 }
685
686
687 static int
nsc_mem_wstep(mdb_walk_state_t * wsp)688 nsc_mem_wstep(mdb_walk_state_t *wsp)
689 {
690 uintptr_t mem = wsp->walk_addr;
691 int status;
692
693 if (!mem)
694 return (WALK_DONE);
695
696 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
697 wsp->walk_cbdata);
698
699 /* move on to next mem */
700
701 if (mdb_vread(&wsp->walk_addr, sizeof (wsp->walk_addr),
702 mem + OFFSETOF(nsc_mem_t, next)) == -1) {
703 mdb_warn("failed to read nsc_mem_t.next");
704 return (WALK_ERR);
705 }
706
707 return (status);
708 }
709
710
711 /* ---------------------------------------------------------------------- */
712
713 struct {
714 char *name;
715 int id;
716 } io_ids[] = {
717 { "NSC_RAW_ID", NSC_RAW_ID },
718 { "NSC_FILE_ID", NSC_FILE_ID },
719 { "NSC_FREEZE_ID", NSC_FREEZE_ID },
720 { "NSC_SDBC_ID", NSC_SDBC_ID },
721 { "NSC_RDCLR_ID", NSC_RDCLR_ID },
722 { "NSC_RDCL_ID", NSC_RDCL_ID },
723 { "NSC_IIR_ID", NSC_IIR_ID },
724 { "NSC_II_ID", NSC_II_ID },
725 { "NSC_RDCHR_ID", NSC_RDCHR_ID },
726 { "NSC_RDCH_ID", NSC_RDCH_ID },
727 { NULL, 0 }
728 };
729
730
731 static char *
nsc_io_id(const int id)732 nsc_io_id(const int id)
733 {
734 int i;
735
736 for (i = 0; io_ids[i].name != NULL; i++) {
737 if (io_ids[i].id == id) {
738 return (io_ids[i].name);
739 }
740 }
741
742 return ("unknown");
743 }
744
745
746 /*
747 * Display a single nsc_io_t structure.
748 * If called with no address, performs a global walk of all nsc_ios.
749 */
750 static int
nsc_io(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)751 nsc_io(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
752 {
753 char io_name[128];
754 nsc_io_t *io;
755 int v_opt;
756
757 v_opt = 0;
758
759 if (mdb_getopts(argc, argv,
760 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
761 return (DCMD_USAGE);
762
763 if (!(flags & DCMD_ADDRSPEC)) {
764 if (mdb_walk_dcmd("nsctl`nsc_io",
765 "nsctl`nsc_io", argc, argv) == -1) {
766 mdb_warn("failed to walk 'nsc_io'");
767 return (DCMD_ERR);
768 }
769
770 return (DCMD_OK);
771 }
772
773 io = mdb_zalloc(sizeof (*io), UM_SLEEP | UM_GC);
774 memset(io_name, 0, sizeof (io_name));
775
776 if (mdb_vread(io, sizeof (*io), addr) != sizeof (*io)) {
777 mdb_warn("failed to read nsc_io at %p", addr);
778 return (DCMD_ERR);
779 }
780
781 if (io->name) {
782 if (mdb_readstr(io_name, sizeof (io_name),
783 (uintptr_t)io->name) == -1) {
784 mdb_warn("failed to read nsc_io_t.name");
785 return (DCMD_ERR);
786 }
787 }
788
789 if (DCMD_HDRSPEC(flags)) {
790 mdb_printf("%-?s %8Tid fl ref abuf name\n", "io");
791 }
792
793 mdb_printf("%0?p %8T%08x %2x %4d %4d %s\n",
794 addr, io->id, io->flag, io->refcnt, io->abufcnt, io_name);
795
796 if (!v_opt)
797 return (DCMD_OK);
798
799 mdb_inc_indent(4);
800
801 mdb_printf("id: %08x <%s>\n", io->id, nsc_io_id(io->id));
802
803 mdb_printf("provide: %08x <%b>\n", io->provide,
804 io->provide, nsc_type_bits);
805
806 mdb_printf("flag: %08x <%b>\n", io->flag, io->flag, nsc_ioflag_bits);
807
808 mdb_printf("pend: %d\n", io->pend);
809
810 mdb_dec_indent(4);
811
812 return (DCMD_OK);
813 }
814
815
816 /* ---------------------------------------------------------------------- */
817
818 /*
819 * Display a single nsc_dev_t structure.
820 * If called with no address, performs a global walk of all nsc_devs.
821 */
822 static int
nsc_dev(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)823 nsc_dev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
824 {
825 char path[NSC_MAXPATH+1];
826 nsc_devval_t *dv;
827 nsc_dev_t *dev;
828 uintptr_t dev_pend;
829 int a_opt, v_opt;
830
831 a_opt = v_opt = 0;
832
833 if (mdb_getopts(argc, argv,
834 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
835 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
836 return (DCMD_USAGE);
837
838 if (!(flags & DCMD_ADDRSPEC)) {
839 mdb_printf("Active device structures:\n");
840
841 if (mdb_walk_dcmd("nsctl`nsc_dev",
842 "nsctl`nsc_dev", argc, argv) == -1) {
843 mdb_warn("failed to walk 'nsc_dev'");
844 return (DCMD_ERR);
845 }
846
847 if (a_opt) {
848 if (mdb_readvar(&dev_pend, "_nsc_dev_pend") == -1) {
849 mdb_warn("failed to read _nsc_dev_pend");
850 return (DCMD_ERR);
851 }
852
853 mdb_printf("\nPending device structures:");
854
855 if (dev_pend) {
856 mdb_printf("\n");
857
858 if (mdb_pwalk_dcmd("nsctl`nsc_dev",
859 "nsctl`nsc_dev", argc, argv,
860 dev_pend) == -1) {
861 mdb_warn("failed to walk "
862 "pending dev structs");
863 return (DCMD_ERR);
864 }
865 } else {
866 mdb_printf(" none\n");
867 }
868 }
869
870 return (DCMD_OK);
871 }
872
873 memset(path, 0, sizeof (path));
874 dev = mdb_zalloc(sizeof (*dev), UM_SLEEP | UM_GC);
875
876 if (mdb_vread(dev, sizeof (*dev), addr) != sizeof (*dev)) {
877 mdb_warn("failed to read nsc_dev at %p", addr);
878 return (DCMD_ERR);
879 }
880
881 if (mdb_readstr(path, sizeof (path), (uintptr_t)dev->nsc_path) == -1) {
882 mdb_warn("failed to read nsc_path at %p", dev->nsc_path);
883 return (DCMD_ERR);
884 }
885
886 if (DCMD_HDRSPEC(flags)) {
887 mdb_printf("%-?s %8Tref pend rpnd wait path\n", "dev");
888 }
889
890 mdb_printf("%0?p %8T%3d %4d %4d %4d %s\n",
891 addr, dev->nsc_refcnt, dev->nsc_pend, dev->nsc_rpend,
892 dev->nsc_wait, path);
893
894 if (!v_opt)
895 return (DCMD_OK);
896
897 mdb_inc_indent(4);
898
899 mdb_printf("next: %0?p %8Tclose: %0?p\n",
900 dev->nsc_next, dev->nsc_close);
901
902 mdb_printf("list: %0?p %8Tlock: %0?p\n",
903 dev->nsc_list, addr + OFFSETOF(nsc_dev_t, nsc_lock));
904
905 mdb_printf("cv: %0?p %8Tpath: %0?p %8Tphash: %016llx\n",
906 addr + OFFSETOF(nsc_dev_t, nsc_cv),
907 dev->nsc_path, dev->nsc_phash);
908
909 mdb_printf("drop: %d %8Treopen: %d\n",
910 dev->nsc_drop, dev->nsc_reopen);
911
912 if (dev->nsc_values) {
913 dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC);
914 if (mdb_vread(dv, sizeof (*dv), (uintptr_t)dev->nsc_values) !=
915 sizeof (*dv)) {
916 mdb_warn("unable to read nsc_dev_t.nsc_values");
917 mdb_dec_indent(4);
918 return (DCMD_ERR);
919 }
920
921 if (dv->dv_values) {
922 mdb_printf("device/values: (nsc_devval: %0?p)\n",
923 dev->nsc_values);
924
925 mdb_inc_indent(4);
926
927 if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val",
928 0, NULL, (uintptr_t)dv->dv_values) == -1) {
929 mdb_dec_indent(8);
930 return (DCMD_ERR);
931 }
932
933 mdb_dec_indent(4);
934 }
935 }
936
937 mdb_dec_indent(4);
938
939 return (DCMD_OK);
940 }
941
942
943 /* ---------------------------------------------------------------------- */
944
945 /*
946 * Display a single nsc_devval_t structure.
947 * If called with no address, performs a global walk of all nsc_devs.
948 */
949 static int
nsc_devval(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)950 nsc_devval(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
951 {
952 nsc_devval_t *dv;
953 int a_opt;
954
955 a_opt = 0;
956
957 if (mdb_getopts(argc, argv,
958 'a', MDB_OPT_SETBITS, TRUE, &a_opt) != argc)
959 return (DCMD_USAGE);
960
961 if (!(flags & DCMD_ADDRSPEC)) {
962 if (mdb_walk_dcmd("nsctl`nsc_devval",
963 "nsctl`nsc_devval", argc, argv) == -1) {
964 mdb_warn("failed to walk 'nsc_devval'");
965 return (DCMD_ERR);
966 }
967
968 return (DCMD_OK);
969 }
970
971 dv = mdb_zalloc(sizeof (*dv), UM_SLEEP | UM_GC);
972
973 if (mdb_vread(dv, sizeof (*dv), addr) != sizeof (*dv)) {
974 mdb_warn("failed to read nsc_devval at %p", addr);
975 return (DCMD_ERR);
976 }
977
978 if (!a_opt && !dv->dv_values) {
979 return (DCMD_OK);
980 }
981
982 if (DCMD_HDRSPEC(flags)) {
983 mdb_printf("%-?s %8T%?-s %8Tpath\n", "devval", "phash");
984 }
985
986 mdb_printf("%0?p %8T%016llx %8T%s\n", addr,
987 dv->dv_phash, dv->dv_path);
988
989 mdb_inc_indent(4);
990
991 if (dv->dv_values) {
992 if (mdb_pwalk_dcmd("nsctl`nsc_val", "nsctl`nsc_val",
993 0, NULL, (uintptr_t)dv->dv_values) == -1) {
994 return (DCMD_ERR);
995 }
996 } else {
997 mdb_printf("No values\n");
998 }
999
1000 mdb_dec_indent(4);
1001
1002 return (DCMD_OK);
1003 }
1004
1005
1006 /* ---------------------------------------------------------------------- */
1007
1008 /*
1009 * Part 2 callback for the all devices and fds walk. Called per iodev.
1010 */
1011 /* ARGSUSED */
1012 static int
nsc_fd_iodev(uintptr_t addr,const void * data,void * cbdata)1013 nsc_fd_iodev(uintptr_t addr, const void *data, void *cbdata)
1014 {
1015 struct complex_args *fdall = cbdata;
1016 struct nsc_fd_t *fd;
1017
1018 if (mdb_vread(&fd, sizeof (fd),
1019 addr + OFFSETOF(nsc_iodev_t, si_open)) == -1) {
1020 mdb_warn("unable to read nsc_iodev_t.si_open");
1021 return (WALK_ERR);
1022 }
1023
1024 if (fd != NULL) {
1025 if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd",
1026 fdall->argc, fdall->argv, (uintptr_t)fd) == -1)
1027 return (WALK_ERR);
1028 }
1029
1030 return (WALK_NEXT);
1031 }
1032
1033
1034 /*
1035 * Part 1 callback for the all devices and fds walk. Called per device.
1036 */
1037 /* ARGSUSED */
1038 static int
nsc_fd_dev(uintptr_t addr,const void * data,void * cbdata)1039 nsc_fd_dev(uintptr_t addr, const void *data, void *cbdata)
1040 {
1041 struct complex_args *fdall = cbdata;
1042 nsc_iodev_t *iodev;
1043 nsc_fd_t *fd;
1044
1045 if (mdb_vread(&iodev, sizeof (iodev),
1046 addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) {
1047 mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr);
1048 return (WALK_ERR);
1049 }
1050
1051 /* walk iodev chains */
1052
1053 if (iodev != NULL) {
1054 if (mdb_pwalk("nsctl`nsc_iodev",
1055 nsc_fd_iodev, fdall, (uintptr_t)iodev) == -1)
1056 return (WALK_ERR);
1057 }
1058
1059 /* walk nsc_close (closing fds) chains */
1060
1061 if (mdb_vread(&fd, sizeof (fd),
1062 addr + OFFSETOF(nsc_dev_t, nsc_close)) == -1) {
1063 mdb_warn("unable to read nsc_dev_t.nsc_close at %p", addr);
1064 return (WALK_ERR);
1065 }
1066
1067 if (fd != NULL) {
1068 if (mdb_pwalk_dcmd("nsctl`nsc_fd", "nsctl`nsc_fd",
1069 fdall->argc, fdall->argv, (uintptr_t)fd) == -1)
1070 return (WALK_ERR);
1071 }
1072
1073 return (WALK_NEXT);
1074 }
1075
1076
1077 /*
1078 * Walk all devices and fds in the system.
1079 */
1080 static int
nsc_fd_all(int argc,const mdb_arg_t * argv)1081 nsc_fd_all(int argc, const mdb_arg_t *argv)
1082 {
1083 struct complex_args fdall;
1084
1085 fdall.argc = argc;
1086 fdall.argv = (mdb_arg_t *)argv;
1087
1088 complex_walk = 1;
1089 complex_hdr = 0;
1090
1091 if (mdb_walk("nsctl`nsc_dev", nsc_fd_dev, &fdall) == -1) {
1092 return (DCMD_ERR);
1093 }
1094
1095 return (DCMD_OK);
1096 }
1097
1098
1099
1100 /*
1101 * Display an nsd_fd_t structure, or walk all devices and fds in the system.
1102 */
1103 static int
nsc_fd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1104 nsc_fd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1105 {
1106 char io_name[128], *io_namep;
1107 char path[NSC_MAXPATH+1];
1108 uintptr_t pathp;
1109 nsc_fd_t *fd;
1110 nsc_io_t *io;
1111 int v_opt;
1112 int hdr;
1113
1114 v_opt = 0;
1115
1116 if (mdb_getopts(argc, argv,
1117 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1118 return (DCMD_USAGE);
1119
1120 if (!(flags & DCMD_ADDRSPEC)) {
1121 return (nsc_fd_all(argc, argv));
1122 }
1123
1124 memset(path, 0, sizeof (path));
1125 fd = mdb_zalloc(sizeof (*fd), UM_SLEEP | UM_GC);
1126 memset(io_name, 0, sizeof (io_name));
1127
1128 if (mdb_vread(fd, sizeof (*fd), addr) != sizeof (*fd)) {
1129 mdb_warn("failed to read nsc_fd at %p", addr);
1130 return (DCMD_ERR);
1131 }
1132
1133 if (mdb_vread(&pathp, sizeof (pathp),
1134 (uintptr_t)fd->sf_dev + OFFSETOF(nsc_dev_t, nsc_path)) !=
1135 sizeof (pathp)) {
1136 mdb_warn("failed to read nsc_dev.nsc_path");
1137 return (DCMD_ERR);
1138 }
1139
1140 if (mdb_readstr(path, sizeof (path), pathp) == -1) {
1141 mdb_warn("failed to read nsc_path");
1142 return (DCMD_ERR);
1143 }
1144
1145 if (fd->sf_iodev) {
1146 if (mdb_vread(&io, sizeof (io),
1147 (uintptr_t)fd->sf_iodev + OFFSETOF(nsc_iodev_t, si_io)) !=
1148 sizeof (io)) {
1149 mdb_warn("failed to read nsc_iodev.si_io");
1150 return (DCMD_ERR);
1151 }
1152
1153 if (mdb_vread(&io_namep, sizeof (io_namep),
1154 (uintptr_t)io + OFFSETOF(nsc_io_t, name)) !=
1155 sizeof (io_namep)) {
1156 mdb_warn("failed to read nsc_io_t.name");
1157 return (DCMD_ERR);
1158 }
1159
1160 if (mdb_readstr(io_name, sizeof (io_name),
1161 (uintptr_t)io_namep) == -1) {
1162 mdb_warn("failed to read nsc_io_t.name string");
1163 return (DCMD_ERR);
1164 }
1165 }
1166
1167 hdr = 0;
1168 if (complex_walk) {
1169 if (!complex_hdr) {
1170 complex_hdr = 1;
1171 hdr = 1;
1172 }
1173 } else if (DCMD_HDRSPEC(flags)) {
1174 hdr = 1;
1175 }
1176
1177 if (hdr) {
1178 mdb_printf("%-?s %8T%-?s %8T%-8s %-?s\n",
1179 "fd", "dev", "io", "cd");
1180 mdb_printf(" %-?s %8Trv pend av path\n", "arg");
1181 }
1182
1183 mdb_printf("%0?p %8T%0?p %8T%-8s %p\n",
1184 addr, fd->sf_dev, io_name, fd->sf_cd);
1185 mdb_printf(" %0?p %8T%2d %4x %2x %s\n",
1186 fd->sf_arg, fd->sf_reserve, fd->sf_pend,
1187 fd->sf_avail, path);
1188
1189 if (!v_opt)
1190 return (DCMD_OK);
1191
1192 mdb_inc_indent(4);
1193
1194 mdb_printf("open type: %08x <%b>\n", fd->sf_type,
1195 fd->sf_type, nsc_type_bits);
1196
1197 mdb_printf("avail: %08x <%b>\n", fd->sf_avail,
1198 fd->sf_avail, nsc_availpend_bits);
1199
1200 mdb_printf("flag: %08x <%b>\n", fd->sf_flag,
1201 fd->sf_flag, nsc_fdflag_bits);
1202
1203 mdb_printf("rsrv mode: %08x <%b>\n", fd->sf_mode,
1204 fd->sf_mode, nsc_fdmode_bits);
1205
1206 mdb_printf("open lbolt: %?x %8Treopen: %d\n", fd->sf_lbolt,
1207 fd->sf_reopen);
1208
1209 mdb_dec_indent(4);
1210
1211 return (DCMD_OK);
1212 }
1213
1214
1215 /* ---------------------------------------------------------------------- */
1216
1217 /*
1218 * Callback for the all devices and iodevs walk. Called per device.
1219 */
1220 /* ARGSUSED */
1221 static int
nsc_iodev_dev(uintptr_t addr,const void * data,void * cbdata)1222 nsc_iodev_dev(uintptr_t addr, const void *data, void *cbdata)
1223 {
1224 struct complex_args *iodevall = cbdata;
1225 uintptr_t iodev;
1226
1227 if (mdb_vread(&iodev, sizeof (iodev),
1228 addr + OFFSETOF(nsc_dev_t, nsc_list)) == -1) {
1229 mdb_warn("unable to read nsc_dev_t.nsc_list at %p", addr);
1230 return (WALK_ERR);
1231 }
1232
1233 /* walk iodev chains */
1234
1235 if (iodev != NULL) {
1236 if (mdb_pwalk_dcmd("nsctl`nsc_iodev", "nsctl`nsc_iodev",
1237 iodevall->argc, iodevall->argv, iodev) == -1)
1238 return (WALK_ERR);
1239 }
1240
1241 return (WALK_NEXT);
1242 }
1243
1244
1245 /*
1246 * Walk all devices and iodevs in the system.
1247 */
1248 static int
nsc_iodev_all(int argc,const mdb_arg_t * argv)1249 nsc_iodev_all(int argc, const mdb_arg_t *argv)
1250 {
1251 struct complex_args iodevall;
1252
1253 iodevall.argc = argc;
1254 iodevall.argv = (mdb_arg_t *)argv;
1255
1256 complex_walk = 1;
1257 complex_hdr = 0;
1258
1259 if (mdb_walk("nsctl`nsc_dev", nsc_iodev_dev, &iodevall) == -1) {
1260 return (DCMD_ERR);
1261 }
1262
1263 return (DCMD_OK);
1264 }
1265
1266
1267 /*
1268 * Display an nsc_iodev_t structure, or walk all devices and
1269 * iodevs in the system.
1270 */
1271 static int
nsc_iodev(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1272 nsc_iodev(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1273 {
1274 char io_name[128], *io_namep;
1275 char path[NSC_MAXPATH+1];
1276 nsc_iodev_t *iodev;
1277 uintptr_t pathp;
1278 int v_opt;
1279 int hdr;
1280
1281 v_opt = 0;
1282
1283 if (mdb_getopts(argc, argv,
1284 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1285 return (DCMD_USAGE);
1286
1287 if (!(flags & DCMD_ADDRSPEC)) {
1288 return (nsc_iodev_all(argc, argv));
1289 }
1290
1291 memset(path, 0, sizeof (path));
1292 iodev = mdb_zalloc(sizeof (*iodev), UM_SLEEP | UM_GC);
1293 memset(io_name, 0, sizeof (io_name));
1294
1295 if (mdb_vread(iodev, sizeof (*iodev), addr) != sizeof (*iodev)) {
1296 mdb_warn("failed to read nsc_iodev at %p", addr);
1297 return (DCMD_ERR);
1298 }
1299
1300 if (mdb_vread(&pathp, sizeof (pathp),
1301 (uintptr_t)iodev->si_dev + OFFSETOF(nsc_dev_t, nsc_path)) !=
1302 sizeof (pathp)) {
1303 mdb_warn("failed to read nsc_dev.nsc_path");
1304 return (DCMD_ERR);
1305 }
1306
1307 if (mdb_readstr(path, sizeof (path), pathp) == -1) {
1308 mdb_warn("failed to read nsc_path");
1309 return (DCMD_ERR);
1310 }
1311
1312 if (mdb_vread(&io_namep, sizeof (io_namep),
1313 (uintptr_t)iodev->si_io + OFFSETOF(nsc_io_t, name)) !=
1314 sizeof (io_namep)) {
1315 mdb_warn("failed to read nsc_io_t.name");
1316 return (DCMD_ERR);
1317 }
1318
1319 if (mdb_readstr(io_name, sizeof (io_name),
1320 (uintptr_t)io_namep) == -1) {
1321 mdb_warn("failed to read nsc_io_t.name string");
1322 return (DCMD_ERR);
1323 }
1324
1325 hdr = 0;
1326 if (complex_walk) {
1327 if (!complex_hdr) {
1328 complex_hdr = 1;
1329 hdr = 1;
1330 }
1331 } else if (DCMD_HDRSPEC(flags)) {
1332 hdr = 1;
1333 }
1334
1335 if (hdr) {
1336 mdb_printf("%-?s %8T%-?s ref %-8s path\n",
1337 "iodev", "dev", "io");
1338 }
1339
1340 mdb_printf("%0?p %8T%0?p %3d %-8s %s\n",
1341 addr, iodev->si_dev, iodev->si_refcnt, io_name, path);
1342
1343 if (!v_opt)
1344 return (DCMD_OK);
1345
1346 mdb_inc_indent(4);
1347
1348 mdb_printf("open fds: %?p %8Tactive ios: %?p\n",
1349 iodev->si_open, iodev->si_active);
1350
1351 mdb_printf("busy: %d %8Trsrv pend: %d\n",
1352 iodev->si_busy, iodev->si_rpend);
1353
1354 mdb_printf("pend: %08x <%b>\n", iodev->si_pend,
1355 iodev->si_pend, nsc_availpend_bits);
1356
1357 mdb_printf("avail: %08x <%b>\n", iodev->si_avail,
1358 iodev->si_avail, nsc_availpend_bits);
1359
1360 mdb_dec_indent(4);
1361
1362 return (DCMD_OK);
1363 }
1364
1365
1366 /* ---------------------------------------------------------------------- */
1367
1368 /*
1369 * Display an nsc_service_t structure, or walk all services.
1370 */
1371 static int
nsc_service(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1372 nsc_service(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1373 {
1374 nsc_service_t *service;
1375 char s_name[32];
1376 int v_opt;
1377
1378 v_opt = 0;
1379
1380 if (mdb_getopts(argc, argv,
1381 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1382 return (DCMD_USAGE);
1383
1384 if (!(flags & DCMD_ADDRSPEC)) {
1385 if (mdb_walk_dcmd("nsctl`nsc_service",
1386 "nsctl`nsc_service", argc, argv) == -1) {
1387 mdb_warn("failed to walk 'nsc_service'");
1388 return (DCMD_ERR);
1389 }
1390
1391 return (DCMD_OK);
1392 }
1393
1394 service = mdb_zalloc(sizeof (*service), UM_SLEEP | UM_GC);
1395
1396 if (mdb_vread(service, sizeof (*service), addr) != sizeof (*service)) {
1397 mdb_warn("failed to read nsc_service at %p", addr);
1398 return (DCMD_ERR);
1399 }
1400
1401 if (DCMD_HDRSPEC(flags)) {
1402 mdb_printf("%-?s %8Tname\n", "service");
1403 }
1404
1405 memset(s_name, 0, sizeof (s_name));
1406 if (service->s_name) {
1407 if (mdb_readstr(s_name, sizeof (s_name),
1408 (uintptr_t)service->s_name) == -1) {
1409 mdb_warn("failed to read nsc_io_t.name");
1410 return (DCMD_ERR);
1411 }
1412 }
1413
1414 mdb_printf("%0?p %8T%s\n", addr, s_name);
1415
1416 if (!v_opt)
1417 return (DCMD_OK);
1418
1419 mdb_inc_indent(4);
1420
1421 mdb_printf("servers:\n");
1422 if (service->s_servers == NULL) {
1423 mdb_printf("<none>\n");
1424 } else {
1425 mdb_inc_indent(4);
1426 if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc",
1427 argc, argv, (uintptr_t)service->s_servers) == -1) {
1428 mdb_dec_indent(8);
1429 return (DCMD_ERR);
1430 }
1431 mdb_dec_indent(4);
1432 }
1433
1434 mdb_printf("clients:\n");
1435 if (service->s_clients == NULL) {
1436 mdb_printf("<none>\n");
1437 } else {
1438 mdb_inc_indent(4);
1439 if (mdb_pwalk_dcmd("nsctl`nsc_svc", "nsctl`nsc_svc",
1440 argc, argv, (uintptr_t)service->s_clients) == -1) {
1441 mdb_dec_indent(8);
1442 return (DCMD_ERR);
1443 }
1444 mdb_dec_indent(4);
1445 }
1446
1447 mdb_dec_indent(4);
1448
1449 return (DCMD_OK);
1450 }
1451
1452
1453 /* ---------------------------------------------------------------------- */
1454
1455 /*
1456 * Display an nsc_svc_t structure.
1457 */
1458 /*ARGSUSED*/
1459 static int
nsc_svc(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1460 nsc_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1461 {
1462 nsc_svc_t *svc;
1463
1464 if (!(flags & DCMD_ADDRSPEC))
1465 return (DCMD_USAGE);
1466
1467 svc = mdb_zalloc(sizeof (*svc), UM_SLEEP | UM_GC);
1468
1469 if (mdb_vread(svc, sizeof (*svc), addr) != sizeof (*svc)) {
1470 mdb_warn("failed to read nsc_svc at %p", addr);
1471 return (DCMD_ERR);
1472 }
1473
1474 if (DCMD_HDRSPEC(flags)) {
1475 mdb_printf("%-?s %8T%-?s %8Tfunc\n", "svc", "service");
1476 }
1477
1478 mdb_printf("%0?p %8T%0?p %8T%a\n", addr, svc->svc_svc, svc->svc_fn);
1479 return (DCMD_OK);
1480 }
1481
1482
1483 /* ---------------------------------------------------------------------- */
1484
1485 /*
1486 * Display a single nsc_val_t structure.
1487 * If called with no address, performs a global walk of all nsc_devs.
1488 */
1489 /* ARGSUSED3 */
1490 static int
nsc_val(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1491 nsc_val(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1492 {
1493 nsc_val_t *vp;
1494
1495 if (argc != 0)
1496 return (DCMD_USAGE);
1497
1498 if (!(flags & DCMD_ADDRSPEC)) {
1499 mdb_warn("nsc_val requires an address");
1500 return (DCMD_ERR);
1501 }
1502
1503 vp = mdb_zalloc(sizeof (*vp), UM_SLEEP | UM_GC);
1504
1505 if (mdb_vread(vp, sizeof (*vp), addr) != sizeof (*vp)) {
1506 mdb_warn("failed to read nsc_val at %p", addr);
1507 return (DCMD_ERR);
1508 }
1509
1510 if (DCMD_HDRSPEC(flags)) {
1511 mdb_printf("%-?s %8T%8-s %8Tname\n", "val", "value");
1512 }
1513
1514 mdb_printf("%0?p %8T%08x %8T%s\n", addr, vp->sv_value, vp->sv_name);
1515
1516 return (DCMD_OK);
1517 }
1518
1519
1520 /* ---------------------------------------------------------------------- */
1521
1522 /*
1523 * Display an nstset_t structure, or walk all sets.
1524 */
1525
1526 static int
nstset(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1527 nstset(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1528 {
1529 nstset_t *set;
1530 int f_opt, r_opt, t_opt, v_opt;
1531
1532 f_opt = r_opt = t_opt = v_opt = 0;
1533
1534 if (mdb_getopts(argc, argv,
1535 'f', MDB_OPT_SETBITS, TRUE, &f_opt, /* free list */
1536 'r', MDB_OPT_SETBITS, TRUE, &r_opt, /* reuse list */
1537 't', MDB_OPT_SETBITS, TRUE, &t_opt, /* all threads */
1538 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1539 return (DCMD_USAGE);
1540
1541 /* displaying threads implies verbose */
1542 if (f_opt || r_opt || t_opt)
1543 v_opt = 1;
1544
1545 if (!(flags & DCMD_ADDRSPEC)) {
1546 if (mdb_walk_dcmd("nsctl`nstset",
1547 "nsctl`nstset", argc, argv) == -1) {
1548 mdb_warn("failed to walk 'nstset'");
1549 return (DCMD_ERR);
1550 }
1551
1552 return (DCMD_OK);
1553 }
1554
1555 set = mdb_zalloc(sizeof (*set), UM_SLEEP | UM_GC);
1556
1557 if (mdb_vread(set, sizeof (*set), addr) != sizeof (*set)) {
1558 mdb_warn("failed to read nstset at %p", addr);
1559 return (DCMD_ERR);
1560 }
1561
1562 if (DCMD_HDRSPEC(flags)) {
1563 mdb_printf("%-?s %8T live nthr flag name\n", "set");
1564 }
1565
1566 mdb_printf("%0?p %8T%6d %6d %4x %s\n", addr,
1567 set->set_nlive, set->set_nthread, set->set_flag, set->set_name);
1568
1569 if (!v_opt)
1570 return (DCMD_OK);
1571
1572 mdb_inc_indent(4);
1573
1574 mdb_printf("chain: %0?p %8Tpending: %4d res_cnt: %4d\n",
1575 set->set_chain, set->set_pending, set->set_res_cnt);
1576
1577 if (set->set_reuse.q_forw == set->set_reuse.q_back &&
1578 (uintptr_t)set->set_reuse.q_forw ==
1579 (addr + OFFSETOF(nstset_t, set_reuse))) {
1580 mdb_printf("reuse.forw: %-?s %8Treuse.back: %s\n",
1581 "empty", "empty");
1582 } else {
1583 mdb_printf("reuse.forw: %0?p %8Treuse.back: %0?p\n",
1584 set->set_reuse.q_forw, set->set_reuse.q_back);
1585
1586 /* display all threads in reuse list */
1587 if (r_opt &&
1588 mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread",
1589 0, (const mdb_arg_t *)NULL,
1590 (addr + OFFSETOF(nstset_t, set_reuse))) == -1) {
1591 mdb_dec_indent(4);
1592 return (DCMD_ERR);
1593 }
1594 }
1595
1596 if (set->set_free.q_forw == set->set_free.q_back &&
1597 (uintptr_t)set->set_free.q_forw ==
1598 (addr + OFFSETOF(nstset_t, set_free))) {
1599 mdb_printf("free.forw: %-?s %8Tfree.back: %s\n",
1600 "empty", "empty");
1601 } else {
1602 mdb_printf("free.forw: %0?p %8Tfree.back: %0?p\n",
1603 set->set_free.q_forw, set->set_free.q_back);
1604
1605 /* display all threads in free list */
1606 if (f_opt &&
1607 mdb_pwalk_dcmd("nsctl`nst_free", "nsctl`nsthread",
1608 0, (const mdb_arg_t *)NULL,
1609 (addr + OFFSETOF(nstset_t, set_free))) == -1) {
1610 mdb_dec_indent(4);
1611 return (DCMD_ERR);
1612 }
1613 }
1614
1615 mdb_printf("flag: %08x <%b>\n",
1616 set->set_flag, set->set_flag, nstset_flag_bits);
1617
1618 /* display all threads in set */
1619 if (t_opt) {
1620 mdb_printf("all threads in set:\n");
1621 if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread",
1622 0, (const mdb_arg_t *)NULL,
1623 (uintptr_t)set->set_chain) == -1) {
1624 mdb_dec_indent(4);
1625 return (DCMD_ERR);
1626 }
1627 }
1628
1629 mdb_dec_indent(4);
1630
1631 return (DCMD_OK);
1632 }
1633
1634
1635 /* ---------------------------------------------------------------------- */
1636
1637 /*
1638 * Callback for the all nstsets and threads walk. Called per set.
1639 */
1640 /* ARGSUSED */
1641 static int
nst_thr_set(uintptr_t addr,const void * data,void * cbdata)1642 nst_thr_set(uintptr_t addr, const void *data, void *cbdata)
1643 {
1644 struct complex_args *thrall = cbdata;
1645 char set_name[48];
1646 uintptr_t tp;
1647
1648 if (mdb_vread(&tp, sizeof (tp),
1649 addr + OFFSETOF(nstset_t, set_chain)) == -1) {
1650 mdb_warn("unable to read nstset_t.set_chain at %p", addr);
1651 return (WALK_ERR);
1652 }
1653
1654 memset(set_name, 0, sizeof (set_name));
1655
1656 if (mdb_readstr(set_name, sizeof (set_name),
1657 addr + OFFSETOF(nstset_t, set_name)) == -1) {
1658 mdb_warn("unable to read nstset_t.set_name at %p", addr);
1659 }
1660
1661 mdb_printf("nstset: %0?p (%s)\n", addr, set_name);
1662
1663 /* walk thread chains */
1664
1665 if (tp != NULL) {
1666 if (mdb_pwalk_dcmd("nsctl`nsthread", "nsctl`nsthread",
1667 thrall->argc, thrall->argv, tp) == -1)
1668 return (WALK_ERR);
1669 } else
1670 mdb_printf(" no threads\n");
1671
1672 mdb_printf("\n");
1673
1674 return (WALK_NEXT);
1675 }
1676
1677
1678 /*
1679 * Walk all nstsets and threads in the system.
1680 */
1681 static int
nst_thr_all(int argc,const mdb_arg_t * argv)1682 nst_thr_all(int argc, const mdb_arg_t *argv)
1683 {
1684 struct complex_args thrall;
1685
1686 thrall.argc = argc;
1687 thrall.argv = (mdb_arg_t *)argv;
1688
1689 if (mdb_walk("nsctl`nstset", nst_thr_set, &thrall) == -1)
1690 return (DCMD_ERR);
1691
1692 return (DCMD_OK);
1693 }
1694
1695
1696 /*
1697 * Display an nsthread_t structure, or walk all threads.
1698 */
1699
1700 static int
nsthread(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1701 nsthread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1702 {
1703 uintptr_t thrpend;
1704 nsthread_t *tp;
1705 int a_opt, v_opt;
1706 int rc;
1707
1708 a_opt = v_opt = 0;
1709
1710 if (mdb_getopts(argc, argv,
1711 'a', MDB_OPT_SETBITS, TRUE, &a_opt,
1712 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1713 return (DCMD_USAGE);
1714
1715 if (!(flags & DCMD_ADDRSPEC)) {
1716 if ((rc = nst_thr_all(argc, argv)) != DCMD_OK)
1717 return (rc);
1718
1719 if (a_opt) {
1720 if (mdb_readvar(&thrpend, "nst_pending") == -1) {
1721 mdb_warn("unable to read 'nst_pending'");
1722 return (DCMD_ERR);
1723 }
1724
1725 if (thrpend) {
1726 mdb_printf("\nPending threads:\n");
1727
1728 if (mdb_pwalk_dcmd("nsctl`nsthread",
1729 "nsctl`nsthread", argc, argv,
1730 thrpend) == -1) {
1731 mdb_warn("failed to walk 'nsthread'");
1732 return (DCMD_ERR);
1733 }
1734 }
1735 }
1736
1737 return (DCMD_OK);
1738 }
1739
1740 tp = mdb_zalloc(sizeof (*tp), UM_SLEEP | UM_GC);
1741
1742 if (mdb_vread(tp, sizeof (*tp), addr) != sizeof (*tp)) {
1743 mdb_warn("failed to read nsthread at %p", addr);
1744 return (DCMD_ERR);
1745 }
1746
1747 if (DCMD_HDRSPEC(flags)) {
1748 mdb_printf("%-?s %8Tflag %-?s %8Tfunc\n", "thread", "arg");
1749 }
1750
1751 mdb_printf("%0?p %8T%4x %0?p %8T%a\n",
1752 addr, tp->tp_flag, tp->tp_arg, tp->tp_func);
1753
1754 if (!v_opt)
1755 return (DCMD_OK);
1756
1757 mdb_inc_indent(4);
1758
1759 mdb_printf("set: %0?p %8Tchain: %0?p\n",
1760 tp->tp_set, tp->tp_chain);
1761
1762 mdb_printf("link.forw: %0?p %8Tlink.back: %0?p\n",
1763 tp->tp_link.q_forw, tp->tp_link.q_back);
1764
1765 mdb_printf("flag: %08x <%b>\n",
1766 tp->tp_flag, tp->tp_flag, nst_flag_bits);
1767
1768 mdb_dec_indent(4);
1769
1770 return (DCMD_OK);
1771 }
1772
1773
1774 /* ---------------------------------------------------------------------- */
1775
1776 static void
nsc_rmap(char * name)1777 nsc_rmap(char *name)
1778 {
1779 nsc_rmmap_t slot;
1780 uintptr_t addr;
1781 int nslot;
1782 char *cp;
1783
1784 if (mdb_readvar(&addr, name) == -1) {
1785 mdb_warn("unable to read rmap '%s'", name);
1786 return;
1787 }
1788
1789 if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) {
1790 mdb_warn("unable to read rmap '%s' slot 0", name);
1791 return;
1792 }
1793
1794 mdb_printf("\nmap name offset size nslot\n");
1795 mdb_printf("%16s %9d %9d %5d\n",
1796 slot.name, slot.offset, slot.size, slot.inuse);
1797
1798 nslot = slot.inuse;
1799 mdb_printf("\nslot name offset size inuse\n");
1800
1801 while (--nslot) {
1802 addr += sizeof (slot);
1803
1804 if (mdb_vread(&slot, sizeof (slot), addr) != sizeof (slot)) {
1805 mdb_warn("unable to read rmap '%s' slot @ %p",
1806 name, addr);
1807 return;
1808 }
1809
1810 if (!slot.inuse || !slot.size)
1811 continue;
1812
1813 for (cp = slot.name; *cp; cp++)
1814 if (*cp == ':')
1815 *cp = ' ';
1816
1817 mdb_printf("%16s %9d %9d %08x\n",
1818 slot.name, slot.offset, slot.size, slot.inuse);
1819 }
1820 }
1821
1822
1823 static void
nsc_rmhdr(void)1824 nsc_rmhdr(void)
1825 {
1826 nsc_rmhdr_t *rmhdr = mdb_zalloc(sizeof (*rmhdr), UM_SLEEP | UM_GC);
1827 uintptr_t addr;
1828
1829 if (mdb_readvar(&addr, "_nsc_rmhdr_ptr") == -1) {
1830 mdb_warn("unable to read _nsc_rmhdr_ptr");
1831 return;
1832 }
1833
1834 if (!addr) {
1835 mdb_printf("\n\nGlobal header not initialised\n");
1836 return;
1837 }
1838
1839 if (mdb_vread(rmhdr, sizeof (*rmhdr), addr) != sizeof (*rmhdr)) {
1840 mdb_warn("unable to read global header at %p", addr);
1841 return;
1842 }
1843
1844 mdb_printf("\n\nglobal header (magic %08x, version %d, size %d)\n",
1845 rmhdr->magic, rmhdr->ver, rmhdr->size);
1846
1847 nsc_rmap("_nsc_global_map");
1848 }
1849
1850
1851 static nsc_mem_t *
memptr(int type,int flag)1852 memptr(int type, int flag)
1853 {
1854 int i;
1855
1856 type &= NSC_MEM_GLOBAL;
1857
1858 if (type)
1859 flag = 0;
1860
1861 if (!type && !flag)
1862 return (&type_mem[0]);
1863
1864 for (i = 1; i < (sizeof (type_mem) / sizeof (nsc_mem_t)); i++) {
1865 if (!type_mem[i].flag && !type_mem[i].type) {
1866 type_mem[i].flag = flag;
1867 type_mem[i].type = type;
1868 return (&type_mem[i]);
1869 }
1870
1871 if (type_mem[i].flag == flag && type_mem[i].type == type)
1872 return (&type_mem[i]);
1873 }
1874
1875 return (&type_mem[i]);
1876 }
1877
1878
1879 #define typename(t) \
1880 (((t) & NSC_MEM_GLOBAL) ? "gbl" : " - ")
1881
1882 #define memname(t) \
1883 (((t) & NSC_MEM_GLOBAL) ? "nsc_global" : "system kmem")
1884
1885 static void
nsc_mem_type(const int first,nsc_mem_t * mp)1886 nsc_mem_type(const int first, nsc_mem_t *mp)
1887 {
1888 char *type, *name;
1889
1890 if (first) {
1891 mdb_printf("\nregion typ f ");
1892 mdb_printf("used hwm pgs alloc free\n");
1893 }
1894
1895 type = typename(mp->type);
1896 name = memname(mp->type);
1897
1898 mdb_printf("%16s %s %2x %9d %9d %6d %5d %5d\n",
1899 name, type, mp->flag, mp->used, mp->hwm, mp->pagehwm,
1900 mp->nalloc, mp->nfree);
1901 }
1902
1903
1904 static int
nsc_mem_all(int argc,const mdb_arg_t * argv,int v_opt)1905 nsc_mem_all(int argc, const mdb_arg_t *argv, int v_opt)
1906 {
1907 int first;
1908 int i;
1909
1910 memset(type_mem, 0, sizeof (type_mem));
1911
1912 if (mdb_walk_dcmd("nsctl`nsc_mem",
1913 "nsctl`nsc_mem", argc, argv) == -1) {
1914 mdb_warn("unable to walk 'nsc_mem'");
1915 return (DCMD_ERR);
1916 }
1917
1918 for (first = 1, i = 0;
1919 i < (sizeof (type_mem) / sizeof (nsc_mem_t)); first = 0, i++) {
1920 if (type_mem[i].nalloc || type_mem[i].hwm) {
1921 nsc_mem_type(first, &type_mem[i]);
1922 }
1923 }
1924
1925 if (v_opt)
1926 nsc_rmhdr();
1927
1928 return (DCMD_OK);
1929 }
1930
1931
1932 static int
nsc_mem(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1933 nsc_mem(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1934 {
1935 char name[16], *type, *cp;
1936 nsc_mem_t mem, *mp;
1937 int v_opt;
1938
1939 v_opt = 0;
1940
1941 if (mdb_getopts(argc, argv,
1942 'v', MDB_OPT_SETBITS, TRUE, &v_opt) != argc)
1943 return (DCMD_USAGE);
1944
1945 if (!(flags & DCMD_ADDRSPEC)) {
1946 return (nsc_mem_all(argc, argv, v_opt));
1947 }
1948
1949 if (mdb_vread(&mem, sizeof (mem), addr) != sizeof (mem)) {
1950 mdb_warn("failed to read nsc_mem_t at %p", addr);
1951 return (DCMD_ERR);
1952 }
1953
1954 if (mdb_readstr(name, sizeof (name), (uintptr_t)mem.name) == -1) {
1955 mdb_warn("failed to read nsc_mem_t.name at %p", addr);
1956 return (DCMD_ERR);
1957 }
1958
1959 if (!mem.nalloc && !mem.hwm && !v_opt)
1960 return (DCMD_OK);
1961
1962 if (DCMD_HDRSPEC(flags)) {
1963 mdb_printf("name typ f ");
1964 mdb_printf("used hwm pgs alloc free base\n");
1965 }
1966
1967 type = typename(mem.type);
1968 mp = memptr(mem.type, mem.flag);
1969
1970 for (cp = name; *cp; cp++)
1971 if (*cp == ':')
1972 *cp = ' ';
1973
1974 mdb_printf("%-16s %s %2x %9d %9d %5d %5d %5d %0?p\n",
1975 name, type, mem.flag, mem.used, mem.hwm, mem.pagehwm,
1976 mem.nalloc, mem.nfree, mem.base);
1977
1978 mp->used += mem.used;
1979 mp->hwm += mem.hwm;
1980 mp->pagehwm += mem.pagehwm;
1981 mp->nalloc += mem.nalloc;
1982 mp->nfree += mem.nfree;
1983
1984 return (DCMD_OK);
1985 }
1986
1987 /*ARGSUSED*/
1988 static int
nsc_vec(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1989 nsc_vec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1990 {
1991 nsc_vec_t *vec;
1992
1993 vec = mdb_zalloc(sizeof (*vec), UM_SLEEP | UM_GC);
1994 if (mdb_vread(vec, sizeof (*vec), addr) != sizeof (*vec)) {
1995 mdb_warn("failed to read nsc_vec at %p", addr);
1996 return (DCMD_ERR);
1997 }
1998 mdb_printf("nsc_vec_t @ 0x%p = {\n", addr);
1999 mdb_inc_indent(4);
2000 mdb_printf("sv_addr: %p\n", vec->sv_addr);
2001 mdb_printf("sv_vme: %lu\n", vec->sv_vme);
2002 mdb_printf("sv_len: %d\n", vec->sv_len);
2003 mdb_dec_indent(4);
2004 mdb_printf("};\n");
2005 if (vec->sv_addr)
2006 return (DCMD_OK);
2007 else
2008 return (DCMD_ERR);
2009 }
2010
2011 /* ---------------------------------------------------------------------- */
2012 /*
2013 * Display an nsc_buf_t structure.
2014 */
2015
2016 #ifdef NSC_MULTI_TERABYTE
2017 #define STRCONV "ll"
2018 #else
2019 #define STRCONV ""
2020 #endif
2021
2022 /* ARGSUSED */
2023 static int
nsc_buf(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2024 nsc_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2025 {
2026 nsc_buf_t *bh;
2027 nsc_vec_t *v;
2028
2029 if (!(flags & DCMD_ADDRSPEC))
2030 return (DCMD_USAGE);
2031
2032 bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC);
2033
2034 if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) {
2035 mdb_warn("failed to read nsc_buf at %p", addr);
2036 return (DCMD_ERR);
2037 }
2038
2039 mdb_printf("nsc_buf_t @ 0x%p = {\n", addr);
2040 mdb_inc_indent(4);
2041 mdb_printf("sb_fd: 0x%p\n", bh->sb_fd);
2042 mdb_printf("sb_pos: 0x%" STRCONV "x\n", bh->sb_pos);
2043 mdb_printf("sb_len: 0x%" STRCONV "x\n", bh->sb_len);
2044 mdb_printf("sb_flag: 0x%08x <%b>\n", bh->sb_flag,
2045 bh->sb_flag, nsc_bhflag_bits);
2046 mdb_printf("sb_error: %d\n", bh->sb_error);
2047 #ifdef NSC_MULTI_TERABYTE
2048 mdb_printf("sb_user: 0x%p\n", bh->sb_user);
2049 #else
2050 mdb_printf("sb_user: 0x%x\n", bh->sb_user);
2051 #endif
2052 mdb_printf("sb_vec: 0x%p\n", bh->sb_vec);
2053 v = bh->sb_vec++;
2054 while (nsc_vec((uintptr_t)v, flags, argc, argv) == DCMD_OK)
2055 v++;
2056
2057 mdb_dec_indent(4);
2058 mdb_printf("};\n");
2059
2060 return (DCMD_OK);
2061 }
2062
2063 /* ---------------------------------------------------------------------- */
2064
2065 /* ARGSUSED */
2066 static int
nsc_dbuf(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2067 nsc_dbuf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2068 {
2069 nsc_dbuf_t *bh;
2070
2071 if (!(flags & DCMD_ADDRSPEC))
2072 return (DCMD_USAGE);
2073
2074 bh = mdb_zalloc(sizeof (*bh), UM_SLEEP | UM_GC);
2075
2076 if (mdb_vread(bh, sizeof (*bh), addr) != sizeof (*bh)) {
2077 mdb_warn("failed to read nsc_dbuf at %p", addr);
2078 return (DCMD_ERR);
2079 }
2080
2081 mdb_printf("nsc_dbuf_t @ 0x%p = {\n", addr);
2082 mdb_inc_indent(4);
2083 mdb_printf("db_disc: 0x%p\n", bh->db_disc);
2084 mdb_printf("db_addr: 0x%p\n", bh->db_addr);
2085 mdb_printf("db_next: 0x%p\n", bh->db_next);
2086 mdb_printf("db_maxfbas: 0x%d\n", bh->db_maxfbas);
2087
2088
2089 mdb_dec_indent(4);
2090 mdb_printf("};\n");
2091
2092 return (DCMD_OK);
2093 }
2094 /* ---------------------------------------------------------------------- */
2095
2096 /*
2097 * MDB module linkage information:
2098 */
2099
2100 static const mdb_dcmd_t dcmds[] = {
2101 #if 0
2102 { "nsctl", NULL, "display nsctl module info", nsctl },
2103 #endif
2104 { "nsc_buf", ":", "list nsc_buf structure", nsc_buf },
2105 { "nsc_dbuf", ":", "list nsc_dbuf structure", nsc_dbuf },
2106 { "nsc_dev", "?[-av]", "list nsc_dev structure", nsc_dev },
2107 { "nsc_devval", "?[-a]", "list nsc_devval structure", nsc_devval },
2108 { "nsc_fd", "?[-v]", "list nsc_fd structure", nsc_fd },
2109 { "nsc_iodev", "?[-v]", "list nsc_iodev structure", nsc_iodev },
2110 { "nsc_io", "?[-v]", "list nsc_io structure", nsc_io },
2111 { "nsc_mem", "?[-v]", "list nsc_mem structure", nsc_mem },
2112 { "nsc_svc", ":", "list nsc_svc structure", nsc_svc },
2113 { "nsc_service", "?[-v]", "list nsc_service structure", nsc_service },
2114 { "nsc_val", ":", "list nsc_val structure", nsc_val },
2115 { "nstset", "?[-frtv]", "list nstset structure", nstset },
2116 { "nsthread", "?[-av]", "list nsthread structure", nsthread },
2117 { NULL }
2118 };
2119
2120
2121 static const mdb_walker_t walkers[] = {
2122 { "nsc_dev", "walk nsc_dev chain",
2123 nsc_dev_winit, nsc_dev_wstep, nsc_dev_wfini, NULL },
2124 { "nsc_devval", "walk nsc_devval chain",
2125 nsc_devval_winit, nsc_devval_wstep, NULL, NULL },
2126 { "nsc_fd", "walk nsc_fd chain",
2127 nsc_fd_winit, nsc_fd_wstep, NULL, NULL },
2128 { "nsc_io", "walk nsc_io chain",
2129 nsc_io_winit, nsc_io_wstep, NULL, NULL },
2130 { "nsc_iodev", "walk nsc_iodev chain",
2131 nsc_iodev_winit, nsc_iodev_wstep, NULL, NULL },
2132 { "nsc_mem", "walk nsc_mem chain",
2133 nsc_mem_winit, nsc_mem_wstep, NULL, NULL },
2134 { "nsc_service", "walk nsc_service chain",
2135 nsc_service_winit, nsc_service_wstep, NULL, NULL },
2136 { "nsc_svc", "walk nsc_svc chain",
2137 nsc_svc_winit, nsc_svc_wstep, NULL, NULL },
2138 { "nsc_val", "walk nsc_val chain",
2139 nsc_val_winit, nsc_val_wstep, NULL, NULL },
2140 { "nstset", "walk nstset chain",
2141 nstset_winit, nstset_wstep, NULL, NULL },
2142 { "nsthread", "walk nsthread chain",
2143 nsthread_winit, nsthread_wstep, NULL, NULL },
2144 { "nst_free", "walk nsthread free/reuse list",
2145 nst_free_winit, nst_free_wstep, NULL, NULL },
2146 { NULL }
2147 };
2148
2149
2150 static const mdb_modinfo_t modinfo = {
2151 MDB_API_VERSION, dcmds, walkers
2152 };
2153
2154
2155 const mdb_modinfo_t *
_mdb_init(void)2156 _mdb_init(void)
2157 {
2158 return (&modinfo);
2159 }
2160