dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mdb / common / modules / sd / sd.c
blob7baaf5f060a3fd5555b3f113c9678bc445e6c1f8
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/mdb_modapi.h>
28 #include <sys/scsi/scsi.h>
29 #include <sys/dkio.h>
30 #include <sys/taskq.h>
31 #include <sys/scsi/targets/sddef.h>
33 /* Represents global soft state data in walk_step, walk_init */
34 #define SD_DATA(param) ((sd_str_p)wsp->walk_data)->param
36 /* Represents global soft state data in callback and related routines */
37 #define SD_DATA_IN_CBACK(param) ((sd_str_p)walk_data)->param
39 #define SUCCESS WALK_NEXT
40 #define FAIL WALK_ERR
43 * Primary attribute struct for buf extensions.
45 struct __ddi_xbuf_attr {
46 kmutex_t xa_mutex;
47 size_t xa_allocsize;
48 uint32_t xa_pending; /* call to xbuf_iostart() is iminent */
49 uint32_t xa_active_limit;
50 uint32_t xa_active_count;
51 uint32_t xa_active_lowater;
52 struct buf *xa_headp; /* FIFO buf queue head ptr */
53 struct buf *xa_tailp; /* FIFO buf queue tail ptr */
54 kmutex_t xa_reserve_mutex;
55 uint32_t xa_reserve_limit;
56 uint32_t xa_reserve_count;
57 void *xa_reserve_headp;
58 void (*xa_strategy)(struct buf *, void *, void *);
59 void *xa_attr_arg;
60 timeout_id_t xa_timeid;
61 taskq_t *xa_tq;
65 * Provides soft state information like the number of elements, pointer
66 * to soft state elements etc
68 typedef struct i_ddi_soft_state sd_state_str_t, *sd_state_str_ptr;
70 /* structure to store soft state statistics */
71 typedef struct sd_str {
72 void *sd_state;
73 uintptr_t current_root;
74 int current_list_count;
75 int valid_root_count;
76 int silent;
77 sd_state_str_t sd_state_data;
78 } sd_str_t, *sd_str_p;
82 * Function: buf_avforw_walk_init
84 * Description: MDB calls the init function to initiate the walk,
85 * in response to mdb_walk() function called by the
86 * dcmd 'buf_avforw' or when the user executes the
87 * walk dcmd 'address::walk buf_avforw'.
89 * Arguments: new mdb_walk_state_t structure. A new structure is
90 * created for each walk, so that multiple instances of
91 * the walker can be active simultaneously.
93 static int
94 buf_avforw_walk_init(mdb_walk_state_t *wsp)
96 if (wsp->walk_addr == (uintptr_t)NULL) {
97 mdb_warn("buffer address required with the command\n");
98 return (WALK_ERR);
101 wsp->walk_data = mdb_alloc(sizeof (buf_t), UM_SLEEP);
102 return (WALK_NEXT);
107 * Function: buf_avforw_walk_step
109 * Description: The step function is invoked by the walker during each
110 * iteration. Its primary job is to determine the address
111 * of the next 'buf_avforw' object, read in the local copy
112 * of this object, call the callback 'buf_callback' function,
113 * and return its status. The iteration is terminated when
114 * the walker encounters a null queue pointer which signifies
115 * end of queue.
117 * Arguments: mdb_walk_state_t structure
119 static int
120 buf_avforw_walk_step(mdb_walk_state_t *wsp)
122 int status;
125 * if walk_addr is null then it effectively means an end of all
126 * buf structures, hence end the iterations.
128 if (wsp->walk_addr == (uintptr_t)NULL) {
129 return (WALK_DONE);
133 * Read the contents of the current object, invoke the callback
134 * and assign the next objects address to mdb_walk_state_t structure.
136 if (mdb_vread(wsp->walk_data, sizeof (buf_t), wsp->walk_addr) == -1) {
137 mdb_warn("failed to read buf at %p", wsp->walk_addr);
138 return (WALK_DONE);
141 status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
142 wsp->walk_cbdata);
143 wsp->walk_addr = (uintptr_t)(((buf_t *)wsp->walk_data)->av_forw);
145 return (status);
149 * Function: buf_callback
151 * Description: This is the callback function called by the 'buf_avforw'
152 * walker when 'buf_avforw' dcmd is invoked.
153 * It is called during each walk step. It displays the contents
154 * of the current object (addr) passed to it by the step
155 * function. It also prints the header and footer during the
156 * first and the last iteration of the walker.
158 * Arguments: addr -> current buf_avforw objects address.
159 * walk_data -> private storage for the walker.
160 * buf_entries -> private data for the callback. It represents
161 * the count of objects processed so far.
163 static int
164 buf_callback(uintptr_t addr, const void *walk_data, void *buf_entries)
166 int *count = (int *)buf_entries;
169 * If this is the first invocation of the command, print a
170 * header line for the output that will follow.
172 if (*count == 0) {
173 mdb_printf("============================\n");
174 mdb_printf("Walking buf list via av_forw\n");
175 mdb_printf("============================\n");
179 * read the object and print the contents.
181 mdb_set_dot(addr);
182 mdb_eval("$<buf");
184 mdb_printf("---\n");
185 (*count)++;
187 /* if this is the last entry and print the footer */
188 if (((buf_t *)walk_data)->av_forw == NULL) {
189 mdb_printf("---------------------------\n");
190 mdb_printf("Processed %d Buf entries\n", *count);
191 mdb_printf("---------------------------\n");
192 return (WALK_DONE);
195 return (WALK_NEXT);
199 * Function: buf_avforw_walk_fini
201 * Description: The buf_avforw_walk_fini is called when the walk is terminated
202 * in response to WALK_DONE in buf_avforw_walk_step. It frees
203 * the walk_data structure.
205 * Arguments: mdb_walk_state_t structure
207 static void
208 buf_avforw_walk_fini(mdb_walk_state_t *wsp)
210 mdb_free(wsp->walk_data, sizeof (buf_t));
214 * Function: dump_xbuf_attr
216 * Description: Prints the contents of Xbuf queue.
218 * Arguments: object contents pointer and address.
220 static void
221 dump_xbuf_attr(struct __ddi_xbuf_attr *xba_ptr, uintptr_t mem_addr)
223 mdb_printf("0x%8lx:\tmutex\t\tallocsize\tpending\n",
224 mem_addr + offsetof(struct __ddi_xbuf_attr, xa_mutex));
226 mdb_printf(" \t%lx\t\t%d\t\t%d\n",
227 xba_ptr->xa_mutex._opaque[0], xba_ptr->xa_allocsize,
228 xba_ptr->xa_pending);
229 mdb_printf("0x%8lx:\tactive_limit\tactive_count\tactive_lowater\n",
230 mem_addr + offsetof(struct __ddi_xbuf_attr, xa_active_limit));
232 mdb_printf(" \t%lx\t\t%lx\t\t%lx\n",
233 xba_ptr->xa_active_limit, xba_ptr->xa_active_count,
234 xba_ptr->xa_active_lowater);
235 mdb_printf("0x%8lx:\theadp\t\ttailp\n",
236 mem_addr + offsetof(struct __ddi_xbuf_attr, xa_headp));
238 mdb_printf(" \t%lx%c\t%lx\n",
239 xba_ptr->xa_headp, (xba_ptr->xa_headp == 0?'\t':' '),
240 xba_ptr->xa_tailp);
241 mdb_printf("0x%8lx:\treserve_mutex\treserve_limit\t"
242 "reserve_count\treserve_headp\n",
243 mem_addr + offsetof(struct __ddi_xbuf_attr, xa_reserve_mutex));
245 mdb_printf(" \t%lx\t\t%lx\t\t%lx\t\t%lx\n",
246 xba_ptr->xa_reserve_mutex._opaque[0], xba_ptr->xa_reserve_limit,
247 xba_ptr->xa_reserve_count, xba_ptr->xa_reserve_headp);
249 mdb_printf("0x%8lx:\ttimeid\t\ttq\n",
250 mem_addr + offsetof(struct __ddi_xbuf_attr, xa_timeid));
252 mdb_printf(" \t%lx%c\t%lx\n",
253 xba_ptr->xa_timeid, (xba_ptr->xa_timeid == 0?'\t':' '),
254 xba_ptr->xa_tq);
258 * Function: init_softstate_members
260 * Description: Initialize mdb_walk_state_t structure with either 'sd' or
261 * 'ssd' related information.
263 * Arguments: new mdb_walk_state_t structure
265 static int
266 init_softstate_members(mdb_walk_state_t *wsp)
268 wsp->walk_data = mdb_alloc(sizeof (sd_str_t), UM_SLEEP);
271 * store the soft state statistics variables like non-zero
272 * soft state entries, base address, actual count of soft state
273 * processed etc.
275 SD_DATA(sd_state) = (sd_state_str_ptr)wsp->walk_addr;
277 SD_DATA(current_list_count) = 0;
278 SD_DATA(valid_root_count) = 0;
280 if (mdb_vread((void *)&SD_DATA(sd_state_data),
281 sizeof (sd_state_str_t), wsp->walk_addr) == -1) {
282 mdb_warn("failed to sd_state at %p", wsp->walk_addr);
283 return (WALK_ERR);
286 wsp->walk_addr = (uintptr_t)(SD_DATA(sd_state_data.array));
288 SD_DATA(current_root) = wsp->walk_addr;
289 return (WALK_NEXT);
293 * Function: sd_state_walk_init
295 * Description: MDB calls the init function to initiate the walk,
296 * in response to mdb_walk() function called by the
297 * dcmd 'sd_state' or when the user executes the
298 * walk dcmd '::walk sd_state'.
299 * The init function initializes the walker to either
300 * the user specified address or the default kernel
301 * 'sd_state' pointer.
303 * Arguments: new mdb_walk_state_t structure
305 static int
306 sd_state_walk_init(mdb_walk_state_t *wsp)
308 if (wsp->walk_addr == (uintptr_t)NULL &&
309 mdb_readvar(&wsp->walk_addr, "sd_state") == -1) {
310 mdb_warn("failed to read 'sd_state'");
311 return (WALK_ERR);
314 return (init_softstate_members(wsp));
318 * Function: sd_state_walk_step
320 * Description: The step function is invoked by the walker during each
321 * iteration. Its primary job is to determine the address
322 * of the next 'soft state' object, read in the local copy
323 * of this object, call the callback 'sd_callback' function,
324 * and return its status. The iteration is terminated when
325 * the soft state counter equals the total soft state count
326 * obtained initially.
328 * Arguments: mdb_walk_state_t structure
330 static int
331 sd_state_walk_step(mdb_walk_state_t *wsp)
333 int status;
334 void *tp;
337 * If all the soft state entries have been processed then stop
338 * future iterations.
340 if (SD_DATA(current_list_count) >= SD_DATA(sd_state_data.n_items)) {
341 return (WALK_DONE);
345 * read the object contents, invoke the callback and set the
346 * mdb_walk_state_t structure to the next object.
348 if (mdb_vread(&tp, sizeof (void *), wsp->walk_addr) == -1) {
349 mdb_warn("failed to read at %p", wsp->walk_addr);
350 return (WALK_ERR);
353 status = wsp->walk_callback((uintptr_t)tp, wsp->walk_data,
354 wsp->walk_cbdata);
355 if (tp != 0) {
356 /* Count the number of non-zero un entries. */
357 SD_DATA(valid_root_count++);
360 wsp->walk_addr += sizeof (void *);
361 SD_DATA(current_list_count++);
362 return (status);
367 * Function: sd_state_walk_fini
369 * Description: The sd_state_walk_fini is called when the walk is terminated
370 * in response to WALK_DONE in sd_state_walk_step. It frees
371 * the walk_data structure.
373 * Arguments: mdb_walk_state_t structure
375 static void
376 sd_state_walk_fini(mdb_walk_state_t *wsp)
378 mdb_free(wsp->walk_data, sizeof (sd_str_t));
382 * Function: process_semo_sleepq
384 * Description: Iterate over the semoclose wait Q members of the soft state.
385 * Print the contents of each member. In case of silent mode
386 * the contents are avoided and only the address is printed.
388 * Arguments: starting queue address, print mode.
390 static int
391 process_semo_sleepq(uintptr_t walk_addr, int silent)
393 uintptr_t rootBuf;
394 buf_t currentBuf;
395 int semo_sleepq_count = 0;
397 /* Set up to process the device's semoclose wait Q */
398 rootBuf = walk_addr;
400 if (!silent) {
401 mdb_printf("\nSEMOCLOSE SLEEP Q:\n");
402 mdb_printf("----------\n");
405 mdb_printf("SEMOCLOSE sleep Q head: %lx\n", rootBuf);
407 while (rootBuf) {
408 /* Process the device's cmd. wait Q */
409 if (!silent) {
410 mdb_printf("SEMOCLOSE SLEEP Q list entry:\n");
411 mdb_printf("------------------\n");
414 if (mdb_vread((void *)&currentBuf, sizeof (buf_t),
415 rootBuf) == -1) {
416 mdb_warn("failed to read buf at %p", rootBuf);
417 return (FAIL);
420 if (!silent) {
421 mdb_set_dot(rootBuf);
422 mdb_eval("$<buf");
423 mdb_printf("---\n");
425 ++semo_sleepq_count;
426 rootBuf = (uintptr_t)currentBuf.av_forw;
429 if (rootBuf == (uintptr_t)NULL) {
430 mdb_printf("------------------------------\n");
431 mdb_printf("Processed %d SEMOCLOSE SLEEP Q entries\n",
432 semo_sleepq_count);
433 mdb_printf("------------------------------\n");
436 return (SUCCESS);
440 * Function: process_sdlun_waitq
442 * Description: Iterate over the wait Q members of the soft state.
443 * Print the contents of each member. In case of silent mode
444 * the contents are avoided and only the address is printed.
446 * Arguments: starting queue address, print mode.
448 static int
449 process_sdlun_waitq(uintptr_t walk_addr, int silent)
451 uintptr_t rootBuf;
452 buf_t currentBuf;
453 int sdLunQ_count = 0;
455 rootBuf = walk_addr;
457 if (!silent) {
458 mdb_printf("\nUN WAIT Q:\n");
459 mdb_printf("----------\n");
461 mdb_printf("UN wait Q head: %lx\n", rootBuf);
463 while (rootBuf) {
464 /* Process the device's cmd. wait Q */
465 if (!silent) {
466 mdb_printf("UN WAIT Q list entry:\n");
467 mdb_printf("------------------\n");
470 if (mdb_vread(&currentBuf, sizeof (buf_t),
471 (uintptr_t)rootBuf) == -1) {
472 mdb_warn("failed to read buf at %p",
473 (uintptr_t)rootBuf);
474 return (FAIL);
477 if (!silent) {
478 mdb_set_dot(rootBuf);
479 mdb_eval("$<buf");
480 mdb_printf("---\n");
483 rootBuf = (uintptr_t)currentBuf.av_forw;
484 ++sdLunQ_count;
487 if (rootBuf == (uintptr_t)NULL) {
488 mdb_printf("------------------------------\n");
489 mdb_printf("Processed %d UN WAIT Q entries\n", sdLunQ_count);
490 mdb_printf("------------------------------\n");
493 return (SUCCESS);
497 * Function: process_xbuf
499 * Description: Iterate over the Xbuf Attr and Xbuf Attr wait Q of the soft
500 * state.
501 * Print the contents of each member. In case of silent mode
502 * the contents are avoided and only the address is printed.
504 * Arguments: starting xbuf address, print mode.
506 static int
507 process_xbuf(uintptr_t xbuf_attr, int silent)
509 struct __ddi_xbuf_attr xba;
510 buf_t xba_current;
511 void *xba_root;
512 int xbuf_q_count = 0;
514 if (xbuf_attr == (uintptr_t)NULL) {
515 mdb_printf("---------------------------\n");
516 mdb_printf("No XBUF ATTR entry\n");
517 mdb_printf("---------------------------\n");
518 return (SUCCESS);
521 /* Process the Xbuf Attr struct for a device. */
522 if (mdb_vread((void *)&xba, sizeof (struct __ddi_xbuf_attr),
523 xbuf_attr) == -1) {
524 mdb_warn("failed to read xbuf_attr at %p", xbuf_attr);
525 return (FAIL);
528 if (!silent) {
529 mdb_printf("\nXBUF ATTR:\n");
530 mdb_printf("----------\n");
532 dump_xbuf_attr(&xba, xbuf_attr);
533 mdb_printf("---\n");
535 mdb_printf("\nXBUF Q:\n");
536 mdb_printf("-------\n");
539 mdb_printf("xbuf Q head: %lx\n", xba.xa_headp);
541 xba_root = (void *) xba.xa_headp;
543 /* Process the Xbuf Attr wait Q, if there are any entries. */
544 while ((uintptr_t)xba_root) {
545 if (!silent) {
546 mdb_printf("XBUF_Q list entry:\n");
547 mdb_printf("------------------\n");
550 if (mdb_vread((void *)&xba_current, sizeof (buf_t),
551 (uintptr_t)xba_root) == -1) {
552 mdb_warn("failed to read buf at %p",
553 (uintptr_t)xba_root);
554 return (FAIL);
556 if (!silent) {
557 mdb_set_dot((uintptr_t)xba_root);
558 mdb_eval("$<buf");
559 mdb_printf("---\n");
561 ++xbuf_q_count;
563 xba_root = (void *)xba_current.av_forw;
566 if (xba_root == NULL) {
567 mdb_printf("---------------------------\n");
568 mdb_printf("Processed %d XBUF Q entries\n", xbuf_q_count);
569 mdb_printf("---------------------------\n");
571 return (SUCCESS);
575 * Function: print_footer
577 * Description: Prints the footer if all the soft state entries are processed.
579 * Arguments: private storage of the walker.
581 static void
582 print_footer(const void *walk_data)
584 if (SD_DATA_IN_CBACK(current_list_count) >=
585 (SD_DATA_IN_CBACK(sd_state_data.n_items) - 1)) {
586 mdb_printf("---------------------------\n");
587 mdb_printf("Processed %d UN softstate entries\n",
588 SD_DATA_IN_CBACK(valid_root_count));
589 mdb_printf("---------------------------\n");
594 * Function: sd_callback
596 * Description: This is the callback function called by the
597 * 'sd_state/ssd_state' walker when 'sd_state/ssd_state' dcmd
598 * invokes the walker.
599 * It is called during each walk step. It displays the contents
600 * of the current soft state object (addr) passed to it by the
601 * step function. It also prints the header and footer during the
602 * first and the last step of the walker.
603 * The contents of the soft state also includes various queues
604 * it includes like Xbuf, semo_close, sdlun_waitq.
606 * Arguments: addr -> current soft state objects address.
607 * walk_data -> private storage for the walker.
608 * flg_silent -> private data for the callback. It represents
609 * the silent mode of operation.
611 static int
612 sd_callback(uintptr_t addr, const void *walk_data, void *flg_silent)
614 struct sd_lun sdLun;
615 int silent = *(int *)flg_silent;
618 * If this is the first invocation of the command, print a
619 * header line for the output that will follow.
621 if (SD_DATA_IN_CBACK(current_list_count) == 0) {
622 mdb_printf("walk_addr = %lx\n", SD_DATA_IN_CBACK(sd_state));
623 mdb_printf("walking sd_state units via ptr: %lx\n",
624 SD_DATA_IN_CBACK(current_root));
625 mdb_printf("%d entries in sd_state table\n",
626 SD_DATA_IN_CBACK(sd_state_data.n_items));
629 mdb_printf("\nun %d: %lx\n", SD_DATA_IN_CBACK(current_list_count),
630 addr);
632 mdb_printf("--------------\n");
634 /* if null soft state iterate over to next one */
635 if (addr == (uintptr_t)NULL) {
636 print_footer(walk_data);
637 return (SUCCESS);
640 * For each buf, we need to read the sd_lun struct,
641 * and then print out its contents, and get the next.
643 else if (mdb_vread(&sdLun, sizeof (struct sd_lun), (uintptr_t)addr) ==
644 sizeof (sdLun)) {
645 if (!silent) {
646 mdb_set_dot(addr);
647 mdb_eval("$<sd_lun");
648 mdb_printf("---\n");
650 } else {
651 mdb_warn("failed to read softstate at %p", addr);
652 return (FAIL);
655 /* process device Xbuf Attr struct and wait Q */
656 process_xbuf((uintptr_t)sdLun.un_xbuf_attr, silent);
658 /* process device cmd wait Q */
659 process_sdlun_waitq((uintptr_t)sdLun.un_waitq_headp, silent);
661 /* process device semoclose wait Q */
662 if (sdLun.un_semoclose._opaque[1] == 0) {
663 process_semo_sleepq((uintptr_t)sdLun.un_semoclose._opaque[0],
664 silent);
667 /* print the actual number of soft state processed */
668 print_footer(walk_data);
669 return (SUCCESS);
673 * Function: dcmd_sd_state
675 * Description: Scans through the sd soft state entries and prints their
676 * contents including of various queues it contains. It uses
677 * 'sd_state' walker to perform a global walk. If a particular
678 * soft state address is specified than it performs the above job
679 * itself (local walk).
681 * Arguments: addr -> user specified address or NULL if no address is
682 * specified.
683 * flags -> integer reflecting whether an address was specified,
684 * or if it was invoked by the walker in a loop etc.
685 * argc -> the number of arguments supplied to the dcmd.
686 * argv -> the actual arguments supplied by the user.
688 /*ARGSUSED*/
689 static int
690 dcmd_sd_state(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
692 struct sd_lun sdLun;
693 uint_t silent = 0;
695 /* Enable the silent mode if '-s' option specified the user */
696 if (mdb_getopts(argc, argv, 's', MDB_OPT_SETBITS, TRUE, &silent, NULL)
697 != argc) {
698 return (DCMD_USAGE);
702 * If no address is specified on the command line, perform
703 * a global walk invoking 'sd_state' walker. If a particular address
704 * is specified then print the soft state and its queues.
706 if (!(flags & DCMD_ADDRSPEC)) {
707 mdb_walk("sd_state", sd_callback, (void *)&silent);
708 return (DCMD_OK);
709 } else {
710 mdb_printf("\nun: %lx\n", addr);
711 mdb_printf("--------------\n");
713 /* read the sd_lun struct and print the contents */
714 if (mdb_vread(&sdLun, sizeof (struct sd_lun),
715 (uintptr_t)addr) == sizeof (sdLun)) {
717 if (!silent) {
718 mdb_set_dot(addr);
719 mdb_eval("$<sd_lun");
720 mdb_printf("---\n");
722 } else {
723 mdb_warn("failed to read softstate at %p", addr);
724 return (DCMD_OK);
727 /* process Xbuf Attr struct and wait Q for the soft state */
728 process_xbuf((uintptr_t)sdLun.un_xbuf_attr, silent);
730 /* process device' cmd wait Q */
731 process_sdlun_waitq((uintptr_t)sdLun.un_waitq_headp, silent);
733 /* process device's semoclose wait Q */
734 if (sdLun.un_semoclose._opaque[1] == 0) {
735 process_semo_sleepq(
736 (uintptr_t)sdLun.un_semoclose._opaque[0], silent);
739 return (DCMD_OK);
743 * Function: dcmd_buf_avforw
745 * Description: Scans through the buf list via av_forw and prints
746 * their contents.
747 * It uses the 'buf_avforw' walker to perform the walk.
749 * Arguments: addr -> user specified address.
750 * flags -> integer reflecting whether an address was specified,
751 * or if it was invoked by the walker in a loop etc.
752 * argc -> the number of arguments supplied to the dcmd.
753 * argv -> the actual arguments supplied by the user.
755 /*ARGSUSED*/
756 static int
757 dcmd_buf_avforw(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
759 int buf_entries = 0;
761 /* it does not take any arguments */
762 if (argc != 0)
763 return (DCMD_USAGE);
766 * If no address was specified on the command line, print the
767 * error msg, else scan and
768 * print out all the buffers available by invoking buf_avforw walker.
770 if ((flags & DCMD_ADDRSPEC)) {
771 mdb_pwalk("buf_avforw", buf_callback, (void *)&buf_entries,
772 addr);
773 return (DCMD_OK);
774 } else {
775 mdb_printf("buffer address required with the command\n");
778 return (DCMD_USAGE);
782 * MDB module linkage information:
784 * List of structures describing our dcmds, a list of structures
785 * describing our walkers, and a function named _mdb_init to return a pointer
786 * to our module information.
789 static const mdb_dcmd_t dcmds[] = {
790 { "buf_avforw", ":", "buf_t list via av_forw", dcmd_buf_avforw},
791 { "sd_state", "[-s]", "sd soft state list", dcmd_sd_state},
792 { NULL }
795 static const mdb_walker_t walkers[] = {
796 { "buf_avforw", "walk list of buf_t structures via av_forw",
797 buf_avforw_walk_init, buf_avforw_walk_step, buf_avforw_walk_fini },
798 { "sd_state", "walk all sd soft state queues",
799 sd_state_walk_init, sd_state_walk_step, sd_state_walk_fini },
800 { NULL }
803 static const mdb_modinfo_t modinfo = {
804 MDB_API_VERSION, dcmds, walkers
808 * Function: _mdb_init
810 * Description: Returns mdb_modinfo_t structure which provides linkage and
811 * module identification information to the debugger.
813 * Arguments: void
815 const mdb_modinfo_t *
816 _mdb_init(void)
818 return (&modinfo);