17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5ca9327a6Smeem * Common Development and Distribution License (the "License").
6ca9327a6Smeem * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22*a45f3f93Smeem * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
277c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
287c478bd9Sstevel@tonic-gate
29*a45f3f93Smeem #include <ctype.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
327c478bd9Sstevel@tonic-gate #include <sys/stream.h>
337c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
347c478bd9Sstevel@tonic-gate #include <sys/strft.h>
357c478bd9Sstevel@tonic-gate #include <sys/strsun.h>
367c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include "streams.h"
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate typedef struct str_flags {
417c478bd9Sstevel@tonic-gate uint_t strf_flag;
427c478bd9Sstevel@tonic-gate const char *strf_name;
437c478bd9Sstevel@tonic-gate const char *strf_descr;
447c478bd9Sstevel@tonic-gate } strflags_t;
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate typedef struct str_types {
477c478bd9Sstevel@tonic-gate const char *strt_name;
487c478bd9Sstevel@tonic-gate int strt_value;
497c478bd9Sstevel@tonic-gate const char *strt_descr;
507c478bd9Sstevel@tonic-gate } strtypes_t;
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate typedef struct ftblk_data {
537c478bd9Sstevel@tonic-gate ftblk_t ft_data; /* Copy of ftblk */
547c478bd9Sstevel@tonic-gate int ft_ix; /* Index in event list */
557c478bd9Sstevel@tonic-gate boolean_t ft_in_evlist; /* Iterating through evlist */
567c478bd9Sstevel@tonic-gate } ftblkdata_t;
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate typedef void qprint_func(queue_t *, queue_t *);
597c478bd9Sstevel@tonic-gate typedef void sdprint_func(stdata_t *, stdata_t *);
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate #define SF(flag) flag, #flag
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate /*
647c478bd9Sstevel@tonic-gate * Queue flags
657c478bd9Sstevel@tonic-gate */
667c478bd9Sstevel@tonic-gate static const strflags_t qf[] = {
677c478bd9Sstevel@tonic-gate { SF(QENAB), "Queue is already enabled to run" },
687c478bd9Sstevel@tonic-gate { SF(QWANTR), "Someone wants to read Q" },
697c478bd9Sstevel@tonic-gate { SF(QWANTW), "Someone wants to write Q" },
707c478bd9Sstevel@tonic-gate { SF(QFULL), "Q is considered full" },
717c478bd9Sstevel@tonic-gate { SF(QREADR), "This is the reader (first) Q" },
727c478bd9Sstevel@tonic-gate { SF(QUSE), "This queue in use (allocation)" },
737c478bd9Sstevel@tonic-gate { SF(QNOENB), "Don't enable Q via putq" },
747c478bd9Sstevel@tonic-gate { SF(QWANTRMQSYNC), "Want to remove sync stream Q" },
757c478bd9Sstevel@tonic-gate { SF(QBACK), "queue has been back-enabled" },
767c478bd9Sstevel@tonic-gate { SF(0x00000200), "unused (was QHLIST)" },
777c478bd9Sstevel@tonic-gate { SF(0x00000400), "unused (was QUNSAFE)" },
787c478bd9Sstevel@tonic-gate { SF(QPAIR), "per queue-pair syncq" },
797c478bd9Sstevel@tonic-gate { SF(QPERQ), "per queue-instance syncq" },
807c478bd9Sstevel@tonic-gate { SF(QPERMOD), "per module syncq" },
817c478bd9Sstevel@tonic-gate { SF(QMTSAFE), "stream module is MT-safe" },
827c478bd9Sstevel@tonic-gate { SF(QMTOUTPERIM), "Has outer perimeter" },
837c478bd9Sstevel@tonic-gate { SF(QINSERVICE), "service routine executing" },
847c478bd9Sstevel@tonic-gate { SF(QWCLOSE), "will not be enabled" },
857c478bd9Sstevel@tonic-gate { SF(QEND), "last queue in stream" },
867c478bd9Sstevel@tonic-gate { SF(QWANTWSYNC), "Streamhead wants to write Q" },
877c478bd9Sstevel@tonic-gate { SF(QSYNCSTR), "Q supports Synchronous STREAMS" },
887c478bd9Sstevel@tonic-gate { SF(QISDRV), "the Queue is attached to a driver" },
897c478bd9Sstevel@tonic-gate { SF(0x00400000), "unused (was QHOT)" },
907c478bd9Sstevel@tonic-gate { SF(0x00800000), "unused (was QNEXTHOT)" },
917c478bd9Sstevel@tonic-gate { SF(0x01000000), "unused (was _QNEXTLESS)" },
927c478bd9Sstevel@tonic-gate { SF(0x02000000), "unused" },
937c478bd9Sstevel@tonic-gate { SF(_QINSERTING), "module is inserted with _I_INSERT" },
947c478bd9Sstevel@tonic-gate { SF(_QREMOVING) "module is removed with _I_REMOVE" },
957c478bd9Sstevel@tonic-gate { SF(_QASSOCIATED), "queue is associated with a device" },
96595aa6e4Smeem { 0, NULL, NULL }
977c478bd9Sstevel@tonic-gate };
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate * Syncq flags
1017c478bd9Sstevel@tonic-gate */
1027c478bd9Sstevel@tonic-gate static const struct str_flags sqf[] = {
1037c478bd9Sstevel@tonic-gate { SF(SQ_EXCL), "Exclusive access to inner perimeter" },
1047c478bd9Sstevel@tonic-gate { SF(SQ_BLOCKED), "qprocsoff in progress" },
1057c478bd9Sstevel@tonic-gate { SF(SQ_FROZEN), "freezestr in progress" },
1067c478bd9Sstevel@tonic-gate { SF(SQ_WRITER), "qwriter(OUTER) pending or running" },
1077c478bd9Sstevel@tonic-gate { SF(SQ_MESSAGES), "There are messages on syncq" },
1087c478bd9Sstevel@tonic-gate { SF(SQ_WANTWAKEUP) "Thread waiting on sq_wait" },
1097c478bd9Sstevel@tonic-gate { SF(SQ_WANTEXWAKEUP), "Thread waiting on sq_exwait" },
1107c478bd9Sstevel@tonic-gate { SF(SQ_EVENTS), "There are events on syncq" },
111595aa6e4Smeem { 0, NULL, NULL }
1127c478bd9Sstevel@tonic-gate };
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate /*
1157c478bd9Sstevel@tonic-gate * Syncq types
1167c478bd9Sstevel@tonic-gate */
1177c478bd9Sstevel@tonic-gate static const struct str_flags sqt[] = {
1187c478bd9Sstevel@tonic-gate { SF(SQ_CIPUT), "Concurrent inner put procedure" },
1197c478bd9Sstevel@tonic-gate { SF(SQ_CISVC), "Concurrent inner svc procedure" },
1207c478bd9Sstevel@tonic-gate { SF(SQ_CIOC), "Concurrent inner open/close" },
1217c478bd9Sstevel@tonic-gate { SF(SQ_CICB), "Concurrent inner callback" },
1227c478bd9Sstevel@tonic-gate { SF(SQ_COPUT), "Concurrent outer put procedure" },
1237c478bd9Sstevel@tonic-gate { SF(SQ_COSVC), "Concurrent outer svc procedure" },
1247c478bd9Sstevel@tonic-gate { SF(SQ_COOC), "Concurrent outer open/close" },
1257c478bd9Sstevel@tonic-gate { SF(SQ_COCB), "Concurrent outer callback" },
126595aa6e4Smeem { 0, NULL, NULL }
1277c478bd9Sstevel@tonic-gate };
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate * Stdata flags
1317c478bd9Sstevel@tonic-gate */
1327c478bd9Sstevel@tonic-gate static const struct str_flags stdf[] = {
1337c478bd9Sstevel@tonic-gate { SF(IOCWAIT), "someone is doing an ioctl" },
1347c478bd9Sstevel@tonic-gate { SF(RSLEEP), "someone wants to read/recv msg" },
1357c478bd9Sstevel@tonic-gate { SF(WSLEEP), "someone wants to write" },
1367c478bd9Sstevel@tonic-gate { SF(STRPRI), "an M_PCPROTO is at stream head" },
1377c478bd9Sstevel@tonic-gate { SF(STRHUP), "device has vanished" },
1387c478bd9Sstevel@tonic-gate { SF(STWOPEN), "waiting for 1st open" },
1397c478bd9Sstevel@tonic-gate { SF(STPLEX), "stream is being multiplexed" },
1407c478bd9Sstevel@tonic-gate { SF(STRISTTY), "stream is a terminal" },
1417c478bd9Sstevel@tonic-gate { SF(STRGETINPROG), "(k)strgetmsg is running" },
1427c478bd9Sstevel@tonic-gate { SF(IOCWAITNE), "STR_NOERROR ioctl running" },
1437c478bd9Sstevel@tonic-gate { SF(STRDERR), "fatal read error from M_ERROR" },
1447c478bd9Sstevel@tonic-gate { SF(STWRERR), "fatal write error from M_ERROR" },
1457c478bd9Sstevel@tonic-gate { SF(STRDERRNONPERSIST), "nonpersistent read errors" },
1467c478bd9Sstevel@tonic-gate { SF(STWRERRNONPERSIST), "nonpersistent write errors" },
1477c478bd9Sstevel@tonic-gate { SF(STRCLOSE), "wait for a close to complete" },
1487c478bd9Sstevel@tonic-gate { SF(SNDMREAD), "used for read notification" },
1497c478bd9Sstevel@tonic-gate { SF(OLDNDELAY), "use old NDELAY TTY semantics" },
1507c478bd9Sstevel@tonic-gate { SF(0x00020000), "unused" },
1517c478bd9Sstevel@tonic-gate { SF(0x00040000), "unused" },
1527c478bd9Sstevel@tonic-gate { SF(STRTOSTOP), "block background writes" },
153ca9327a6Smeem { SF(STRCMDWAIT), "someone is doing an _I_CMD" },
1547c478bd9Sstevel@tonic-gate { SF(0x00200000), "unused" },
1557c478bd9Sstevel@tonic-gate { SF(STRMOUNT), "stream is mounted" },
1567c478bd9Sstevel@tonic-gate { SF(STRNOTATMARK), "Not at mark (when empty read q)" },
1577c478bd9Sstevel@tonic-gate { SF(STRDELIM), "generate delimited messages" },
1587c478bd9Sstevel@tonic-gate { SF(STRATMARK), "at mark (due to MSGMARKNEXT)" },
1597c478bd9Sstevel@tonic-gate { SF(STZCNOTIFY), "wait for zerocopy mblk to be acked" },
1607c478bd9Sstevel@tonic-gate { SF(STRPLUMB), "stream plumbing changes in progress" },
1617c478bd9Sstevel@tonic-gate { SF(STREOF), "End-of-file indication" },
1627c478bd9Sstevel@tonic-gate { SF(STREOPENFAIL), "re-open has failed" },
1637c478bd9Sstevel@tonic-gate { SF(STRMATE), "this stream is a mate" },
1647c478bd9Sstevel@tonic-gate { SF(STRHASLINKS), "there are I_LINKs under this stream" },
165595aa6e4Smeem { 0, NULL, NULL }
1667c478bd9Sstevel@tonic-gate };
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate static const struct str_flags mbf[] = {
1697c478bd9Sstevel@tonic-gate { SF(MSGMARK), "last byte of message is marked" },
1707c478bd9Sstevel@tonic-gate { SF(MSGNOLOOP), "don't loop message to write side" },
1717c478bd9Sstevel@tonic-gate { SF(MSGDELIM), "message is delimited" },
1727c478bd9Sstevel@tonic-gate { SF(0x08), "unused" },
1737c478bd9Sstevel@tonic-gate { SF(MSGMARKNEXT), "Private: b_next's first byte marked" },
1747c478bd9Sstevel@tonic-gate { SF(MSGNOTMARKNEXT), "Private: ... not marked" },
175595aa6e4Smeem { 0, NULL, NULL }
1767c478bd9Sstevel@tonic-gate };
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate #define M_DATA_T 0xff
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate static const strtypes_t mbt[] = {
1817c478bd9Sstevel@tonic-gate { "M_DATA", M_DATA_T, "regular data" },
1827c478bd9Sstevel@tonic-gate { "M_PROTO", M_PROTO, "protocol control" },
1837c478bd9Sstevel@tonic-gate { "M_MULTIDATA", M_MULTIDATA, "multidata" },
1847c478bd9Sstevel@tonic-gate { "M_BREAK", M_BREAK, "line break" },
1857c478bd9Sstevel@tonic-gate { "M_PASSFP", M_PASSFP, "pass file pointer" },
1867c478bd9Sstevel@tonic-gate { "M_EVENT", M_EVENT, "Obsoleted: do not use" },
1877c478bd9Sstevel@tonic-gate { "M_SIG", M_SIG, "generate process signal" },
1887c478bd9Sstevel@tonic-gate { "M_DELAY", M_DELAY, "real-time xmit delay" },
1897c478bd9Sstevel@tonic-gate { "M_CTL", M_CTL, "device-specific control message" },
1907c478bd9Sstevel@tonic-gate { "M_IOCTL", M_IOCTL, "ioctl; set/get params" },
1917c478bd9Sstevel@tonic-gate { "M_SETOPTS", M_SETOPTS, "set stream head options" },
1927c478bd9Sstevel@tonic-gate { "M_RSE", M_RSE, "reserved for RSE use only" },
1937c478bd9Sstevel@tonic-gate { "M_IOCACK", M_IOCACK, "acknowledge ioctl" },
1947c478bd9Sstevel@tonic-gate { "M_IOCNAK", M_IOCNAK, "negative ioctl acknowledge" },
1957c478bd9Sstevel@tonic-gate { "M_PCPROTO", M_PCPROTO, "priority proto message" },
1967c478bd9Sstevel@tonic-gate { "M_PCSIG", M_PCSIG, "generate process signal" },
1977c478bd9Sstevel@tonic-gate { "M_READ", M_READ, "generate read notification" },
1987c478bd9Sstevel@tonic-gate { "M_FLUSH", M_FLUSH, "flush your queues" },
1997c478bd9Sstevel@tonic-gate { "M_STOP", M_STOP, "stop transmission immediately" },
2007c478bd9Sstevel@tonic-gate { "M_START", M_START, "restart transmission after stop" },
2017c478bd9Sstevel@tonic-gate { "M_HANGUP", M_HANGUP, "line disconnect" },
2027c478bd9Sstevel@tonic-gate { "M_ERROR", M_ERROR, "send error to stream head" },
2037c478bd9Sstevel@tonic-gate { "M_COPYIN", M_COPYIN, "request to copyin data" },
2047c478bd9Sstevel@tonic-gate { "M_COPYOUT", M_COPYOUT, "request to copyout data" },
2057c478bd9Sstevel@tonic-gate { "M_IOCDATA", M_IOCDATA, "response to M_COPYIN and M_COPYOUT" },
2067c478bd9Sstevel@tonic-gate { "M_PCRSE", M_PCRSE, "reserved for RSE use only" },
2077c478bd9Sstevel@tonic-gate { "M_STOPI", M_STOPI, "stop reception immediately" },
2087c478bd9Sstevel@tonic-gate { "M_STARTI", M_STARTI, "restart reception after stop" },
2097c478bd9Sstevel@tonic-gate { "M_PCEVENT", M_PCEVENT, "Obsoleted: do not use" },
2107c478bd9Sstevel@tonic-gate { "M_UNHANGUP", M_UNHANGUP, "line reconnect" },
211ca9327a6Smeem { "M_CMD", M_CMD, "out-of-band ioctl command" },
212595aa6e4Smeem { NULL, 0, NULL }
2137c478bd9Sstevel@tonic-gate };
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate /* Allocation flow trace events, starting from 0 */
2167c478bd9Sstevel@tonic-gate static const char *ftev_alloc[] = {
217*a45f3f93Smeem /* 0 */ "allocb",
218*a45f3f93Smeem /* 1 */ "esballoc",
219*a45f3f93Smeem /* 2 */ "desballoc",
220*a45f3f93Smeem /* 3 */ "esballoca",
221*a45f3f93Smeem /* 4 */ "desballoca",
222*a45f3f93Smeem /* 5 */ "allocbig",
223*a45f3f93Smeem /* 6 */ "allocbw",
224*a45f3f93Smeem /* 7 */ "bcallocb",
225*a45f3f93Smeem /* 8 */ "freeb",
226*a45f3f93Smeem /* 9 */ "dupb",
227*a45f3f93Smeem /* A */ "copyb",
2287c478bd9Sstevel@tonic-gate };
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate #define FTEV_PROC_START FTEV_PUT
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate /* Procedures recorded by flow tracing, starting from 0x100 */
2337c478bd9Sstevel@tonic-gate static const char *ftev_proc[] = {
234*a45f3f93Smeem /* 100 */ "put",
235*a45f3f93Smeem /* 101 */ "0x101",
236*a45f3f93Smeem /* 102 */ "0x102",
237*a45f3f93Smeem /* 103 */ "0x103",
238*a45f3f93Smeem /* 104 */ "0x104",
239*a45f3f93Smeem /* 105 */ "putq",
240*a45f3f93Smeem /* 106 */ "getq",
241*a45f3f93Smeem /* 107 */ "rmvq",
242*a45f3f93Smeem /* 108 */ "insq",
243*a45f3f93Smeem /* 109 */ "putbq",
244*a45f3f93Smeem /* 10A */ "flushq",
245*a45f3f93Smeem /* 10B */ "0x10b",
246*a45f3f93Smeem /* 10C */ "0x10c",
247*a45f3f93Smeem /* 10D */ "putnext",
248*a45f3f93Smeem /* 10E */ "rwnext",
2497c478bd9Sstevel@tonic-gate };
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate static const char *db_control_types[] = {
2527c478bd9Sstevel@tonic-gate /* 00 */ "data",
2537c478bd9Sstevel@tonic-gate /* 01 */ "proto",
2547c478bd9Sstevel@tonic-gate /* 02 */ "multidata",
255*a45f3f93Smeem /* 03 */ "0x03",
256*a45f3f93Smeem /* 04 */ "0x04",
257*a45f3f93Smeem /* 05 */ "0x05",
258*a45f3f93Smeem /* 06 */ "0x06",
259*a45f3f93Smeem /* 07 */ "0x07",
2607c478bd9Sstevel@tonic-gate /* 08 */ "break",
2617c478bd9Sstevel@tonic-gate /* 09 */ "passfp",
2627c478bd9Sstevel@tonic-gate /* 0a */ "event",
2637c478bd9Sstevel@tonic-gate /* 0b */ "sig",
2647c478bd9Sstevel@tonic-gate /* 0c */ "delay",
2657c478bd9Sstevel@tonic-gate /* 0d */ "ctl",
2667c478bd9Sstevel@tonic-gate /* 0e */ "ioctl",
2677c478bd9Sstevel@tonic-gate /* 0f */ "unused",
2687c478bd9Sstevel@tonic-gate /* 10 */ "setopts",
2697c478bd9Sstevel@tonic-gate /* 11 */ "rse",
2707c478bd9Sstevel@tonic-gate };
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate static const char *db_control_hipri_types[] = {
2737c478bd9Sstevel@tonic-gate /* 81 */ "iocack",
2747c478bd9Sstevel@tonic-gate /* 82 */ "iocnak",
2757c478bd9Sstevel@tonic-gate /* 83 */ "pcproto",
2767c478bd9Sstevel@tonic-gate /* 84 */ "pcsig",
2777c478bd9Sstevel@tonic-gate /* 85 */ "read",
2787c478bd9Sstevel@tonic-gate /* 86 */ "flush",
2797c478bd9Sstevel@tonic-gate /* 87 */ "stop",
2807c478bd9Sstevel@tonic-gate /* 88 */ "start",
2817c478bd9Sstevel@tonic-gate /* 89 */ "hangup",
2827c478bd9Sstevel@tonic-gate /* 8a */ "error",
2837c478bd9Sstevel@tonic-gate /* 8b */ "copyin",
2847c478bd9Sstevel@tonic-gate /* 8c */ "copyout",
2857c478bd9Sstevel@tonic-gate /* 8d */ "iocdata",
2867c478bd9Sstevel@tonic-gate /* 8e */ "pcrse",
2877c478bd9Sstevel@tonic-gate /* 8f */ "stopi",
2887c478bd9Sstevel@tonic-gate /* 90 */ "starti",
2897c478bd9Sstevel@tonic-gate /* 91 */ "pcevent",
2907c478bd9Sstevel@tonic-gate /* 92 */ "unhangup",
291*a45f3f93Smeem /* 93 */ "cmd",
2927c478bd9Sstevel@tonic-gate };
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate #define A_SIZE(a) (sizeof (a) / sizeof (a[0]))
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate static void ft_printevent(ushort_t);
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate static int
streams_parse_flag(const strflags_t ftable[],const char * arg,uint32_t * flag)2997c478bd9Sstevel@tonic-gate streams_parse_flag(const strflags_t ftable[], const char *arg, uint32_t *flag)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate int i;
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate for (i = 0; ftable[i].strf_name != NULL; i++) {
3047c478bd9Sstevel@tonic-gate if (strcasecmp(arg, ftable[i].strf_name) == 0) {
3057c478bd9Sstevel@tonic-gate *flag |= (1 << i);
3067c478bd9Sstevel@tonic-gate return (0);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate return (-1);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate static void
streams_flag_usage(const strflags_t ftable[])3147c478bd9Sstevel@tonic-gate streams_flag_usage(const strflags_t ftable[])
3157c478bd9Sstevel@tonic-gate {
3167c478bd9Sstevel@tonic-gate int i;
3177c478bd9Sstevel@tonic-gate
3187c478bd9Sstevel@tonic-gate for (i = 0; ftable[i].strf_name != NULL; i++)
3197c478bd9Sstevel@tonic-gate mdb_printf("%-14s %s\n",
3207c478bd9Sstevel@tonic-gate ftable[i].strf_name, ftable[i].strf_descr);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate static int
streams_parse_type(const strtypes_t ftable[],const char * arg,uint32_t * flag)3247c478bd9Sstevel@tonic-gate streams_parse_type(const strtypes_t ftable[], const char *arg, uint32_t *flag)
3257c478bd9Sstevel@tonic-gate {
3267c478bd9Sstevel@tonic-gate int i;
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate for (i = 0; ftable[i].strt_name != NULL; i++) {
3297c478bd9Sstevel@tonic-gate if (strcasecmp(arg, ftable[i].strt_name) == 0) {
3307c478bd9Sstevel@tonic-gate *flag = ftable[i].strt_value;
3317c478bd9Sstevel@tonic-gate return (0);
3327c478bd9Sstevel@tonic-gate }
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate return (-1);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate static void
streams_type_usage(const strtypes_t ftable[])3397c478bd9Sstevel@tonic-gate streams_type_usage(const strtypes_t ftable[])
3407c478bd9Sstevel@tonic-gate {
3417c478bd9Sstevel@tonic-gate int i;
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate for (i = 0; ftable[i].strt_name != NULL; i++)
3447c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
3457c478bd9Sstevel@tonic-gate ftable[i].strt_name, ftable[i].strt_descr);
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate int
queue(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)3497c478bd9Sstevel@tonic-gate queue(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate const int QUEUE_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 15);
3527c478bd9Sstevel@tonic-gate
3537c478bd9Sstevel@tonic-gate char name[MODMAXNAMELEN];
3547c478bd9Sstevel@tonic-gate int nblks = 0;
3557c478bd9Sstevel@tonic-gate uintptr_t maddr;
3567c478bd9Sstevel@tonic-gate mblk_t mblk;
3577c478bd9Sstevel@tonic-gate queue_t q;
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate const char *mod = NULL, *flag = NULL, *not_flag = NULL;
3607c478bd9Sstevel@tonic-gate uint_t quiet = FALSE;
3617c478bd9Sstevel@tonic-gate uint_t verbose = FALSE;
3627c478bd9Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0;
3637c478bd9Sstevel@tonic-gate uintptr_t syncq = 0;
3647c478bd9Sstevel@tonic-gate
3657c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
3667c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`queue_cache", "genunix`queue",
3677c478bd9Sstevel@tonic-gate argc, argv) == -1) {
3687c478bd9Sstevel@tonic-gate mdb_warn("failed to walk queue cache");
3697c478bd9Sstevel@tonic-gate return (DCMD_ERR);
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate return (DCMD_OK);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT)
3757c478bd9Sstevel@tonic-gate quiet = TRUE;
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
3787c478bd9Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
3797c478bd9Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet,
3807c478bd9Sstevel@tonic-gate 'm', MDB_OPT_STR, &mod,
3817c478bd9Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag,
3827c478bd9Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag,
3837c478bd9Sstevel@tonic-gate 's', MDB_OPT_UINTPTR, &syncq,
3847c478bd9Sstevel@tonic-gate NULL) != argc)
3857c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
3867c478bd9Sstevel@tonic-gate
3877c478bd9Sstevel@tonic-gate /*
3887c478bd9Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything
3897c478bd9Sstevel@tonic-gate * except the matching pointer.
3907c478bd9Sstevel@tonic-gate */
3917c478bd9Sstevel@tonic-gate if (flag != NULL || not_flag != NULL || mod != NULL || syncq != NULL)
3927c478bd9Sstevel@tonic-gate quiet = TRUE;
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) {
3957c478bd9Sstevel@tonic-gate mdb_printf("%?s %-13s %6s %4s\n",
3967c478bd9Sstevel@tonic-gate "ADDR", "MODULE", "FLAGS", "NBLK");
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(qf, flag, &mask) == -1) {
4007c478bd9Sstevel@tonic-gate mdb_warn("unrecognized queue flag '%s'\n", flag);
4017c478bd9Sstevel@tonic-gate streams_flag_usage(qf);
4027c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate if (not_flag != NULL &&
4067c478bd9Sstevel@tonic-gate streams_parse_flag(qf, not_flag, ¬_mask) == -1) {
4077c478bd9Sstevel@tonic-gate mdb_warn("unrecognized queue flag '%s'\n", flag);
4087c478bd9Sstevel@tonic-gate streams_flag_usage(qf);
4097c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate if (mdb_vread(&q, sizeof (q), addr) == -1) {
4137c478bd9Sstevel@tonic-gate mdb_warn("couldn't read queue at %p", addr);
4147c478bd9Sstevel@tonic-gate return (DCMD_ERR);
4157c478bd9Sstevel@tonic-gate }
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate for (maddr = (uintptr_t)q.q_first; maddr != NULL; nblks++) {
4187c478bd9Sstevel@tonic-gate if (mdb_vread(&mblk, sizeof (mblk), maddr) == -1) {
4197c478bd9Sstevel@tonic-gate mdb_warn("couldn't read mblk %p for queue %p",
4207c478bd9Sstevel@tonic-gate maddr, addr);
4217c478bd9Sstevel@tonic-gate break;
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate maddr = (uintptr_t)mblk.b_next;
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate (void) mdb_qname(&q, name, sizeof (name));
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate /*
4297c478bd9Sstevel@tonic-gate * If queue doesn't pass filtering criteria, don't print anything and
4307c478bd9Sstevel@tonic-gate * just return.
4317c478bd9Sstevel@tonic-gate */
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate if (mod != NULL && strcmp(mod, name) != 0)
4347c478bd9Sstevel@tonic-gate return (DCMD_OK);
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate if (mask != 0 && !(q.q_flag & mask))
4377c478bd9Sstevel@tonic-gate return (DCMD_OK);
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate if (not_mask != 0 && (q.q_flag & not_mask))
4407c478bd9Sstevel@tonic-gate return (DCMD_OK);
4417c478bd9Sstevel@tonic-gate
4427c478bd9Sstevel@tonic-gate if (syncq != 0 && q.q_syncq != (syncq_t *)syncq)
4437c478bd9Sstevel@tonic-gate return (DCMD_OK);
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate /*
4467c478bd9Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on
4477c478bd9Sstevel@tonic-gate * the command line, just print address and exit.
4487c478bd9Sstevel@tonic-gate */
4497c478bd9Sstevel@tonic-gate if (quiet) {
4507c478bd9Sstevel@tonic-gate mdb_printf("%0?p\n", addr);
4517c478bd9Sstevel@tonic-gate return (DCMD_OK);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate mdb_printf("%0?p %-13s %06x %4d %0?p\n",
4557c478bd9Sstevel@tonic-gate addr, name, q.q_flag, nblks, q.q_first);
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate if (verbose) {
4587c478bd9Sstevel@tonic-gate int i, arm = 0;
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate for (i = 0; qf[i].strf_name != NULL; i++) {
4617c478bd9Sstevel@tonic-gate if (!(q.q_flag & (1 << i)))
4627c478bd9Sstevel@tonic-gate continue;
4637c478bd9Sstevel@tonic-gate if (!arm) {
4647c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ",
4657c478bd9Sstevel@tonic-gate QUEUE_FLGDELT, "", QUEUE_FLGDELT, "");
4667c478bd9Sstevel@tonic-gate arm = 1;
4677c478bd9Sstevel@tonic-gate } else
4687c478bd9Sstevel@tonic-gate mdb_printf("%*s ", QUEUE_FLGDELT, "");
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
4717c478bd9Sstevel@tonic-gate qf[i].strf_name, qf[i].strf_descr);
4727c478bd9Sstevel@tonic-gate }
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate return (DCMD_OK);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate int
syncq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4797c478bd9Sstevel@tonic-gate syncq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate const int SYNC_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 1);
4827c478bd9Sstevel@tonic-gate const int SYNC_TYPDELT = (int)(sizeof (uintptr_t) * 2 + 5);
4837c478bd9Sstevel@tonic-gate syncq_t sq;
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL;
4867c478bd9Sstevel@tonic-gate const char *typ = NULL, *not_typ = NULL;
4877c478bd9Sstevel@tonic-gate uint_t verbose = FALSE;
4887c478bd9Sstevel@tonic-gate uint_t quiet = FALSE;
4897c478bd9Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0;
4907c478bd9Sstevel@tonic-gate uint32_t tmask = 0, not_tmask = 0;
4917c478bd9Sstevel@tonic-gate uint8_t sqtype = 0;
4927c478bd9Sstevel@tonic-gate
4937c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
4947c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`syncq_cache", "genunix`syncq",
4957c478bd9Sstevel@tonic-gate argc, argv) == -1) {
4967c478bd9Sstevel@tonic-gate mdb_warn("failed to walk syncq cache");
4977c478bd9Sstevel@tonic-gate return (DCMD_ERR);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate return (DCMD_OK);
5007c478bd9Sstevel@tonic-gate }
5017c478bd9Sstevel@tonic-gate
5027c478bd9Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT)
5037c478bd9Sstevel@tonic-gate quiet = TRUE;
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
5067c478bd9Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
5077c478bd9Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet,
5087c478bd9Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag,
5097c478bd9Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag,
5107c478bd9Sstevel@tonic-gate 't', MDB_OPT_STR, &typ,
5117c478bd9Sstevel@tonic-gate 'T', MDB_OPT_STR, ¬_typ,
5127c478bd9Sstevel@tonic-gate NULL) != argc)
5137c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate /*
5167c478bd9Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything
5177c478bd9Sstevel@tonic-gate * except the matching pointer.
5187c478bd9Sstevel@tonic-gate */
5197c478bd9Sstevel@tonic-gate if (flag != NULL || not_flag != NULL || typ != NULL || not_typ != NULL)
5207c478bd9Sstevel@tonic-gate quiet = TRUE;
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) {
5237c478bd9Sstevel@tonic-gate mdb_printf("%?s %s %s %s %s %?s %s %s\n",
5247c478bd9Sstevel@tonic-gate "ADDR", "FLG", "TYP", "CNT", "NQS", "OUTER", "SF", "PRI");
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(sqf, flag, &mask) == -1) {
5287c478bd9Sstevel@tonic-gate mdb_warn("unrecognized syncq flag '%s'\n", flag);
5297c478bd9Sstevel@tonic-gate streams_flag_usage(sqf);
5307c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate if (typ != NULL && streams_parse_flag(sqt, typ, &tmask) == -1) {
5347c478bd9Sstevel@tonic-gate mdb_warn("unrecognized syncq type '%s'\n", typ);
5357c478bd9Sstevel@tonic-gate streams_flag_usage(sqt);
5367c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate if (not_flag != NULL && streams_parse_flag(sqf, not_flag, ¬_mask)
5407c478bd9Sstevel@tonic-gate == -1) {
5417c478bd9Sstevel@tonic-gate mdb_warn("unrecognized syncq flag '%s'\n", not_flag);
5427c478bd9Sstevel@tonic-gate streams_flag_usage(sqf);
5437c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate
5467c478bd9Sstevel@tonic-gate if (not_typ != NULL && streams_parse_flag(sqt, not_typ, ¬_tmask)
5477c478bd9Sstevel@tonic-gate == -1) {
5487c478bd9Sstevel@tonic-gate mdb_warn("unrecognized syncq type '%s'\n", not_typ);
5497c478bd9Sstevel@tonic-gate streams_flag_usage(sqt);
5507c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate
5537c478bd9Sstevel@tonic-gate if (mdb_vread(&sq, sizeof (sq), addr) == -1) {
5547c478bd9Sstevel@tonic-gate mdb_warn("couldn't read syncq at %p", addr);
5557c478bd9Sstevel@tonic-gate return (DCMD_ERR);
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate if (mask != 0 && !(sq.sq_flags & mask))
5597c478bd9Sstevel@tonic-gate return (DCMD_OK);
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate if (not_mask != 0 && (sq.sq_flags & not_mask))
5627c478bd9Sstevel@tonic-gate return (DCMD_OK);
5637c478bd9Sstevel@tonic-gate
5647c478bd9Sstevel@tonic-gate sqtype = (sq.sq_type >> 8) & 0xff;
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate if (tmask != 0 && !(sqtype & tmask))
5677c478bd9Sstevel@tonic-gate return (DCMD_OK);
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate if (not_tmask != 0 && (sqtype & not_tmask))
5707c478bd9Sstevel@tonic-gate return (DCMD_OK);
5717c478bd9Sstevel@tonic-gate
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on
5747c478bd9Sstevel@tonic-gate * the command line, just print address and exit.
5757c478bd9Sstevel@tonic-gate */
5767c478bd9Sstevel@tonic-gate if (quiet) {
5777c478bd9Sstevel@tonic-gate mdb_printf("%0?p\n", addr);
5787c478bd9Sstevel@tonic-gate return (DCMD_OK);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate mdb_printf("%0?p %02x %02x %-3u %-3u %0?p %1x %-3d\n",
5827c478bd9Sstevel@tonic-gate addr, sq.sq_flags & 0xff, sqtype, sq.sq_count,
5837c478bd9Sstevel@tonic-gate sq.sq_nqueues, sq.sq_outer, sq.sq_svcflags, sq.sq_pri);
5847c478bd9Sstevel@tonic-gate
5857c478bd9Sstevel@tonic-gate if (verbose) {
5867c478bd9Sstevel@tonic-gate int i, arm = 0;
5877c478bd9Sstevel@tonic-gate
5887c478bd9Sstevel@tonic-gate for (i = 0; sqf[i].strf_name != NULL; i++) {
5897c478bd9Sstevel@tonic-gate if (!(sq.sq_flags & (1 << i)))
5907c478bd9Sstevel@tonic-gate continue;
5917c478bd9Sstevel@tonic-gate if (!arm) {
5927c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ",
5937c478bd9Sstevel@tonic-gate SYNC_FLGDELT, "", SYNC_FLGDELT, "");
5947c478bd9Sstevel@tonic-gate arm = 1;
5957c478bd9Sstevel@tonic-gate } else
5967c478bd9Sstevel@tonic-gate mdb_printf("%*s ", SYNC_FLGDELT, "");
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
5997c478bd9Sstevel@tonic-gate sqf[i].strf_name, sqf[i].strf_descr);
6007c478bd9Sstevel@tonic-gate }
6017c478bd9Sstevel@tonic-gate
6027c478bd9Sstevel@tonic-gate for (i = 0; sqt[i].strf_name != NULL; i++) {
6037c478bd9Sstevel@tonic-gate if (!(sqtype & (1 << i)))
6047c478bd9Sstevel@tonic-gate continue;
6057c478bd9Sstevel@tonic-gate if (!arm) {
6067c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ",
6077c478bd9Sstevel@tonic-gate SYNC_TYPDELT, "", SYNC_TYPDELT, "");
6087c478bd9Sstevel@tonic-gate arm = 1;
6097c478bd9Sstevel@tonic-gate } else
6107c478bd9Sstevel@tonic-gate mdb_printf("%*s ", SYNC_TYPDELT, "");
6117c478bd9Sstevel@tonic-gate
6127c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
6137c478bd9Sstevel@tonic-gate sqt[i].strf_name, sqt[i].strf_descr);
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate }
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate return (DCMD_OK);
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate int
stdata(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)6217c478bd9Sstevel@tonic-gate stdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
6227c478bd9Sstevel@tonic-gate {
6237c478bd9Sstevel@tonic-gate const int STREAM_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 10);
6247c478bd9Sstevel@tonic-gate
6257c478bd9Sstevel@tonic-gate stdata_t sd;
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL;
6287c478bd9Sstevel@tonic-gate uint_t verbose = FALSE;
6297c478bd9Sstevel@tonic-gate uint_t quiet = FALSE;
6307c478bd9Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0;
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
6337c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`stream_head_cache",
6347c478bd9Sstevel@tonic-gate "genunix`stdata", argc, argv) == -1) {
6357c478bd9Sstevel@tonic-gate mdb_warn("failed to walk stream head cache");
6367c478bd9Sstevel@tonic-gate return (DCMD_ERR);
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate return (DCMD_OK);
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT)
6427c478bd9Sstevel@tonic-gate quiet = TRUE;
6437c478bd9Sstevel@tonic-gate
6447c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
6457c478bd9Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
6467c478bd9Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet,
6477c478bd9Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag,
6487c478bd9Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag,
6497c478bd9Sstevel@tonic-gate NULL) != argc)
6507c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
6517c478bd9Sstevel@tonic-gate
6527c478bd9Sstevel@tonic-gate /*
6537c478bd9Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything
6547c478bd9Sstevel@tonic-gate * except the matching pointer.
6557c478bd9Sstevel@tonic-gate */
6567c478bd9Sstevel@tonic-gate if (flag != NULL || not_flag != NULL)
6577c478bd9Sstevel@tonic-gate quiet = TRUE;
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) {
6607c478bd9Sstevel@tonic-gate mdb_printf("%?s %?s %8s %?s %s %s\n",
6617c478bd9Sstevel@tonic-gate "ADDR", "WRQ", "FLAGS", "VNODE", "N/A", "REF");
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(stdf, flag, &mask) == -1) {
6657c478bd9Sstevel@tonic-gate mdb_warn("unrecognized stream flag '%s'\n", flag);
6667c478bd9Sstevel@tonic-gate streams_flag_usage(stdf);
6677c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
6687c478bd9Sstevel@tonic-gate }
6697c478bd9Sstevel@tonic-gate
6707c478bd9Sstevel@tonic-gate if (not_flag != NULL &&
6717c478bd9Sstevel@tonic-gate streams_parse_flag(stdf, not_flag, ¬_mask) == -1) {
6727c478bd9Sstevel@tonic-gate mdb_warn("unrecognized stream flag '%s'\n", flag);
6737c478bd9Sstevel@tonic-gate streams_flag_usage(stdf);
6747c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate
6777c478bd9Sstevel@tonic-gate if (mdb_vread(&sd, sizeof (sd), addr) == -1) {
6787c478bd9Sstevel@tonic-gate mdb_warn("couldn't read stdata at %p", addr);
6797c478bd9Sstevel@tonic-gate return (DCMD_ERR);
6807c478bd9Sstevel@tonic-gate }
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate /*
6837c478bd9Sstevel@tonic-gate * If stream doesn't pass filtering criteria, don't print anything and
6847c478bd9Sstevel@tonic-gate * just return.
6857c478bd9Sstevel@tonic-gate */
6867c478bd9Sstevel@tonic-gate
6877c478bd9Sstevel@tonic-gate if (mask != 0 && !(sd.sd_flag & mask))
6887c478bd9Sstevel@tonic-gate return (DCMD_OK);
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate if (not_mask != 0 && (sd.sd_flag & not_mask))
6917c478bd9Sstevel@tonic-gate return (DCMD_OK);
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate /*
6947c478bd9Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on
6957c478bd9Sstevel@tonic-gate * the command line, just print address and exit.
6967c478bd9Sstevel@tonic-gate */
6977c478bd9Sstevel@tonic-gate if (quiet) {
6987c478bd9Sstevel@tonic-gate mdb_printf("%0?p\n", addr);
6997c478bd9Sstevel@tonic-gate return (DCMD_OK);
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate
7027c478bd9Sstevel@tonic-gate mdb_printf("%0?p %0?p %08x %0?p %d/%d %d\n",
7037c478bd9Sstevel@tonic-gate addr, sd.sd_wrq, sd.sd_flag, sd.sd_vnode,
7047c478bd9Sstevel@tonic-gate sd.sd_pushcnt, sd.sd_anchor, sd.sd_refcnt);
7057c478bd9Sstevel@tonic-gate
7067c478bd9Sstevel@tonic-gate if (verbose) {
7077c478bd9Sstevel@tonic-gate int i, arm = 0;
7087c478bd9Sstevel@tonic-gate
7097c478bd9Sstevel@tonic-gate for (i = 0; stdf[i].strf_name != NULL; i++) {
7107c478bd9Sstevel@tonic-gate if (!(sd.sd_flag & (1 << i)))
7117c478bd9Sstevel@tonic-gate continue;
7127c478bd9Sstevel@tonic-gate if (!arm) {
7137c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ",
7147c478bd9Sstevel@tonic-gate STREAM_FLGDELT, "", STREAM_FLGDELT, "");
7157c478bd9Sstevel@tonic-gate arm = 1;
7167c478bd9Sstevel@tonic-gate } else
7177c478bd9Sstevel@tonic-gate mdb_printf("%*s ", STREAM_FLGDELT, "");
7187c478bd9Sstevel@tonic-gate
7197c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
7207c478bd9Sstevel@tonic-gate stdf[i].strf_name, stdf[i].strf_descr);
7217c478bd9Sstevel@tonic-gate }
7227c478bd9Sstevel@tonic-gate }
7237c478bd9Sstevel@tonic-gate
7247c478bd9Sstevel@tonic-gate return (DCMD_OK);
7257c478bd9Sstevel@tonic-gate }
7267c478bd9Sstevel@tonic-gate
7277c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7287c478bd9Sstevel@tonic-gate static void
qprint_syncq(queue_t * addr,queue_t * q)7297c478bd9Sstevel@tonic-gate qprint_syncq(queue_t *addr, queue_t *q)
7307c478bd9Sstevel@tonic-gate {
7317c478bd9Sstevel@tonic-gate mdb_printf("%p\n", q->q_syncq);
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7357c478bd9Sstevel@tonic-gate static void
qprint_stream(queue_t * addr,queue_t * q)7367c478bd9Sstevel@tonic-gate qprint_stream(queue_t *addr, queue_t *q)
7377c478bd9Sstevel@tonic-gate {
7387c478bd9Sstevel@tonic-gate mdb_printf("%p\n", q->q_stream);
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate static void
qprint_wrq(queue_t * addr,queue_t * q)7427c478bd9Sstevel@tonic-gate qprint_wrq(queue_t *addr, queue_t *q)
7437c478bd9Sstevel@tonic-gate {
7447c478bd9Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr)+1: (addr)));
7457c478bd9Sstevel@tonic-gate }
7467c478bd9Sstevel@tonic-gate
7477c478bd9Sstevel@tonic-gate static void
qprint_rdq(queue_t * addr,queue_t * q)7487c478bd9Sstevel@tonic-gate qprint_rdq(queue_t *addr, queue_t *q)
7497c478bd9Sstevel@tonic-gate {
7507c478bd9Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr): (addr)-1));
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate
7537c478bd9Sstevel@tonic-gate static void
qprint_otherq(queue_t * addr,queue_t * q)7547c478bd9Sstevel@tonic-gate qprint_otherq(queue_t *addr, queue_t *q)
7557c478bd9Sstevel@tonic-gate {
7567c478bd9Sstevel@tonic-gate mdb_printf("%p\n", ((q)->q_flag & QREADR? (addr)+1: (addr)-1));
7577c478bd9Sstevel@tonic-gate }
7587c478bd9Sstevel@tonic-gate
7597c478bd9Sstevel@tonic-gate static int
q2x(uintptr_t addr,int argc,qprint_func prfunc)7607c478bd9Sstevel@tonic-gate q2x(uintptr_t addr, int argc, qprint_func prfunc)
7617c478bd9Sstevel@tonic-gate {
7627c478bd9Sstevel@tonic-gate queue_t q;
7637c478bd9Sstevel@tonic-gate
7647c478bd9Sstevel@tonic-gate if (argc != 0)
7657c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
7667c478bd9Sstevel@tonic-gate
7677c478bd9Sstevel@tonic-gate if (mdb_vread(&q, sizeof (q), addr) == -1) {
7687c478bd9Sstevel@tonic-gate mdb_warn("couldn't read queue at %p", addr);
7697c478bd9Sstevel@tonic-gate return (DCMD_ERR);
7707c478bd9Sstevel@tonic-gate }
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gate prfunc((queue_t *)addr, &q);
7737c478bd9Sstevel@tonic-gate
7747c478bd9Sstevel@tonic-gate return (DCMD_OK);
7757c478bd9Sstevel@tonic-gate }
7767c478bd9Sstevel@tonic-gate
7777c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7787c478bd9Sstevel@tonic-gate int
q2syncq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7797c478bd9Sstevel@tonic-gate q2syncq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7807c478bd9Sstevel@tonic-gate {
7817c478bd9Sstevel@tonic-gate return (q2x(addr, argc, qprint_syncq));
7827c478bd9Sstevel@tonic-gate }
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7857c478bd9Sstevel@tonic-gate int
q2stream(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7867c478bd9Sstevel@tonic-gate q2stream(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7877c478bd9Sstevel@tonic-gate {
7887c478bd9Sstevel@tonic-gate return (q2x(addr, argc, qprint_stream));
7897c478bd9Sstevel@tonic-gate }
7907c478bd9Sstevel@tonic-gate
7917c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7927c478bd9Sstevel@tonic-gate int
q2rdq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)7937c478bd9Sstevel@tonic-gate q2rdq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
7947c478bd9Sstevel@tonic-gate {
7957c478bd9Sstevel@tonic-gate return (q2x(addr, argc, qprint_rdq));
7967c478bd9Sstevel@tonic-gate }
7977c478bd9Sstevel@tonic-gate
7987c478bd9Sstevel@tonic-gate /*ARGSUSED*/
7997c478bd9Sstevel@tonic-gate int
q2wrq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8007c478bd9Sstevel@tonic-gate q2wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8017c478bd9Sstevel@tonic-gate {
8027c478bd9Sstevel@tonic-gate return (q2x(addr, argc, qprint_wrq));
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate
8057c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8067c478bd9Sstevel@tonic-gate int
q2otherq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8077c478bd9Sstevel@tonic-gate q2otherq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8087c478bd9Sstevel@tonic-gate {
8097c478bd9Sstevel@tonic-gate return (q2x(addr, argc, qprint_otherq));
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate static int
sd2x(uintptr_t addr,int argc,sdprint_func prfunc)8137c478bd9Sstevel@tonic-gate sd2x(uintptr_t addr, int argc, sdprint_func prfunc)
8147c478bd9Sstevel@tonic-gate {
8157c478bd9Sstevel@tonic-gate stdata_t sd;
8167c478bd9Sstevel@tonic-gate
8177c478bd9Sstevel@tonic-gate if (argc != 0)
8187c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate if (mdb_vread(&sd, sizeof (sd), addr) == -1) {
8217c478bd9Sstevel@tonic-gate mdb_warn("couldn't read stream head at %p", addr);
8227c478bd9Sstevel@tonic-gate return (DCMD_ERR);
8237c478bd9Sstevel@tonic-gate }
8247c478bd9Sstevel@tonic-gate
8257c478bd9Sstevel@tonic-gate prfunc((stdata_t *)addr, &sd);
8267c478bd9Sstevel@tonic-gate
8277c478bd9Sstevel@tonic-gate return (DCMD_OK);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8317c478bd9Sstevel@tonic-gate static void
sdprint_wrq(stdata_t * addr,stdata_t * sd)8327c478bd9Sstevel@tonic-gate sdprint_wrq(stdata_t *addr, stdata_t *sd)
8337c478bd9Sstevel@tonic-gate {
8347c478bd9Sstevel@tonic-gate mdb_printf("%p\n", sd->sd_wrq);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate
8377c478bd9Sstevel@tonic-gate static void
sdprint_mate(stdata_t * addr,stdata_t * sd)8387c478bd9Sstevel@tonic-gate sdprint_mate(stdata_t *addr, stdata_t *sd)
8397c478bd9Sstevel@tonic-gate {
8407c478bd9Sstevel@tonic-gate mdb_printf("%p\n", sd->sd_mate ? sd->sd_mate : addr);
8417c478bd9Sstevel@tonic-gate }
8427c478bd9Sstevel@tonic-gate
8437c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8447c478bd9Sstevel@tonic-gate int
str2mate(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8457c478bd9Sstevel@tonic-gate str2mate(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8467c478bd9Sstevel@tonic-gate {
8477c478bd9Sstevel@tonic-gate return (sd2x(addr, argc, sdprint_mate));
8487c478bd9Sstevel@tonic-gate }
8497c478bd9Sstevel@tonic-gate
8507c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8517c478bd9Sstevel@tonic-gate int
str2wrq(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8527c478bd9Sstevel@tonic-gate str2wrq(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8537c478bd9Sstevel@tonic-gate {
8547c478bd9Sstevel@tonic-gate return (sd2x(addr, argc, sdprint_wrq));
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate
8577c478bd9Sstevel@tonic-gate /*
8587c478bd9Sstevel@tonic-gate * If this syncq is a part of the queue pair structure, find the queue for it.
8597c478bd9Sstevel@tonic-gate */
8607c478bd9Sstevel@tonic-gate /*ARGSUSED*/
8617c478bd9Sstevel@tonic-gate int
syncq2q(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)8627c478bd9Sstevel@tonic-gate syncq2q(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
8637c478bd9Sstevel@tonic-gate {
8647c478bd9Sstevel@tonic-gate syncq_t sq;
8657c478bd9Sstevel@tonic-gate queue_t q;
8667c478bd9Sstevel@tonic-gate queue_t *qp;
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate if (argc != 0)
8697c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
8707c478bd9Sstevel@tonic-gate
8717c478bd9Sstevel@tonic-gate if (mdb_vread(&sq, sizeof (sq), addr) == -1) {
8727c478bd9Sstevel@tonic-gate mdb_warn("couldn't read syncq at %p", addr);
8737c478bd9Sstevel@tonic-gate return (DCMD_ERR);
8747c478bd9Sstevel@tonic-gate }
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate /* Try to find its queue */
8777c478bd9Sstevel@tonic-gate qp = (queue_t *)addr - 2;
8787c478bd9Sstevel@tonic-gate
8797c478bd9Sstevel@tonic-gate if ((mdb_vread(&q, sizeof (q), (uintptr_t)qp) == -1) ||
8807c478bd9Sstevel@tonic-gate (q.q_syncq != (syncq_t *)addr)) {
8817c478bd9Sstevel@tonic-gate mdb_warn("syncq2q: %p is not part of any queue\n", addr);
8827c478bd9Sstevel@tonic-gate return (DCMD_ERR);
8837c478bd9Sstevel@tonic-gate } else
8847c478bd9Sstevel@tonic-gate mdb_printf("%p\n", qp);
8857c478bd9Sstevel@tonic-gate
8867c478bd9Sstevel@tonic-gate return (DCMD_OK);
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate int
queue_walk_init(mdb_walk_state_t * wsp)8907c478bd9Sstevel@tonic-gate queue_walk_init(mdb_walk_state_t *wsp)
8917c478bd9Sstevel@tonic-gate {
8927c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL &&
8937c478bd9Sstevel@tonic-gate mdb_readvar(&wsp->walk_addr, "qhead") == -1) {
8947c478bd9Sstevel@tonic-gate mdb_warn("failed to read 'qhead'");
8957c478bd9Sstevel@tonic-gate return (WALK_ERR);
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate
8987c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (queue_t), UM_SLEEP);
8997c478bd9Sstevel@tonic-gate return (WALK_NEXT);
9007c478bd9Sstevel@tonic-gate }
9017c478bd9Sstevel@tonic-gate
9027c478bd9Sstevel@tonic-gate int
queue_link_step(mdb_walk_state_t * wsp)9037c478bd9Sstevel@tonic-gate queue_link_step(mdb_walk_state_t *wsp)
9047c478bd9Sstevel@tonic-gate {
9057c478bd9Sstevel@tonic-gate int status;
9067c478bd9Sstevel@tonic-gate
9077c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
9087c478bd9Sstevel@tonic-gate return (WALK_DONE);
9097c478bd9Sstevel@tonic-gate
9107c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t), wsp->walk_addr) == -1) {
9117c478bd9Sstevel@tonic-gate mdb_warn("failed to read queue at %p", wsp->walk_addr);
9127c478bd9Sstevel@tonic-gate return (WALK_DONE);
9137c478bd9Sstevel@tonic-gate }
9147c478bd9Sstevel@tonic-gate
9157c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
9167c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
9177c478bd9Sstevel@tonic-gate
9187c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((queue_t *)wsp->walk_data)->q_link);
9197c478bd9Sstevel@tonic-gate return (status);
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate
9227c478bd9Sstevel@tonic-gate int
queue_next_step(mdb_walk_state_t * wsp)9237c478bd9Sstevel@tonic-gate queue_next_step(mdb_walk_state_t *wsp)
9247c478bd9Sstevel@tonic-gate {
9257c478bd9Sstevel@tonic-gate int status;
9267c478bd9Sstevel@tonic-gate
9277c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
9287c478bd9Sstevel@tonic-gate return (WALK_DONE);
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t), wsp->walk_addr) == -1) {
9317c478bd9Sstevel@tonic-gate mdb_warn("failed to read queue at %p", wsp->walk_addr);
9327c478bd9Sstevel@tonic-gate return (WALK_DONE);
9337c478bd9Sstevel@tonic-gate }
9347c478bd9Sstevel@tonic-gate
9357c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
9367c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
9377c478bd9Sstevel@tonic-gate
9387c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((queue_t *)wsp->walk_data)->q_next);
9397c478bd9Sstevel@tonic-gate return (status);
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate void
queue_walk_fini(mdb_walk_state_t * wsp)9437c478bd9Sstevel@tonic-gate queue_walk_fini(mdb_walk_state_t *wsp)
9447c478bd9Sstevel@tonic-gate {
9457c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (queue_t));
9467c478bd9Sstevel@tonic-gate }
9477c478bd9Sstevel@tonic-gate
9487c478bd9Sstevel@tonic-gate int
str_walk_init(mdb_walk_state_t * wsp)9497c478bd9Sstevel@tonic-gate str_walk_init(mdb_walk_state_t *wsp)
9507c478bd9Sstevel@tonic-gate {
9517c478bd9Sstevel@tonic-gate stdata_t s;
9527c478bd9Sstevel@tonic-gate
9537c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) {
9547c478bd9Sstevel@tonic-gate mdb_warn("walk must begin at address of stdata_t\n");
9557c478bd9Sstevel@tonic-gate return (WALK_ERR);
9567c478bd9Sstevel@tonic-gate }
9577c478bd9Sstevel@tonic-gate
9587c478bd9Sstevel@tonic-gate if (mdb_vread(&s, sizeof (s), wsp->walk_addr) == -1) {
9597c478bd9Sstevel@tonic-gate mdb_warn("failed to read stdata at %p", wsp->walk_addr);
9607c478bd9Sstevel@tonic-gate return (WALK_ERR);
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)s.sd_wrq;
9647c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (queue_t) * 2, UM_SLEEP);
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate return (WALK_NEXT);
9677c478bd9Sstevel@tonic-gate }
9687c478bd9Sstevel@tonic-gate
9697c478bd9Sstevel@tonic-gate int
strr_walk_step(mdb_walk_state_t * wsp)9707c478bd9Sstevel@tonic-gate strr_walk_step(mdb_walk_state_t *wsp)
9717c478bd9Sstevel@tonic-gate {
9727c478bd9Sstevel@tonic-gate queue_t *rq = wsp->walk_data, *wq = rq + 1;
9737c478bd9Sstevel@tonic-gate int status;
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
9767c478bd9Sstevel@tonic-gate return (WALK_DONE);
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t) * 2,
9797c478bd9Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)) == -1) {
9807c478bd9Sstevel@tonic-gate mdb_warn("failed to read queue pair at %p",
9817c478bd9Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t));
9827c478bd9Sstevel@tonic-gate return (WALK_DONE);
9837c478bd9Sstevel@tonic-gate }
9847c478bd9Sstevel@tonic-gate
9857c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr - sizeof (queue_t),
9867c478bd9Sstevel@tonic-gate rq, wsp->walk_cbdata);
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate if (wq->q_next != NULL)
9897c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)wq->q_next;
9907c478bd9Sstevel@tonic-gate else
9917c478bd9Sstevel@tonic-gate wsp->walk_addr = mdb_qwnext(wq);
9927c478bd9Sstevel@tonic-gate
9937c478bd9Sstevel@tonic-gate return (status);
9947c478bd9Sstevel@tonic-gate }
9957c478bd9Sstevel@tonic-gate
9967c478bd9Sstevel@tonic-gate int
strw_walk_step(mdb_walk_state_t * wsp)9977c478bd9Sstevel@tonic-gate strw_walk_step(mdb_walk_state_t *wsp)
9987c478bd9Sstevel@tonic-gate {
9997c478bd9Sstevel@tonic-gate queue_t *rq = wsp->walk_data, *wq = rq + 1;
10007c478bd9Sstevel@tonic-gate int status;
10017c478bd9Sstevel@tonic-gate
10027c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
10037c478bd9Sstevel@tonic-gate return (WALK_DONE);
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (queue_t) * 2,
10067c478bd9Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t)) == -1) {
10077c478bd9Sstevel@tonic-gate mdb_warn("failed to read queue pair at %p",
10087c478bd9Sstevel@tonic-gate wsp->walk_addr - sizeof (queue_t));
10097c478bd9Sstevel@tonic-gate return (WALK_DONE);
10107c478bd9Sstevel@tonic-gate }
10117c478bd9Sstevel@tonic-gate
10127c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wq, wsp->walk_cbdata);
10137c478bd9Sstevel@tonic-gate
10147c478bd9Sstevel@tonic-gate if (wq->q_next != NULL)
10157c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)wq->q_next;
10167c478bd9Sstevel@tonic-gate else
10177c478bd9Sstevel@tonic-gate wsp->walk_addr = mdb_qwnext(wq);
10187c478bd9Sstevel@tonic-gate
10197c478bd9Sstevel@tonic-gate return (status);
10207c478bd9Sstevel@tonic-gate }
10217c478bd9Sstevel@tonic-gate
10227c478bd9Sstevel@tonic-gate void
str_walk_fini(mdb_walk_state_t * wsp)10237c478bd9Sstevel@tonic-gate str_walk_fini(mdb_walk_state_t *wsp)
10247c478bd9Sstevel@tonic-gate {
10257c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (queue_t) * 2);
10267c478bd9Sstevel@tonic-gate }
10277c478bd9Sstevel@tonic-gate
10287c478bd9Sstevel@tonic-gate static int
print_qpair(uintptr_t addr,const queue_t * q,uint_t * depth)10297c478bd9Sstevel@tonic-gate print_qpair(uintptr_t addr, const queue_t *q, uint_t *depth)
10307c478bd9Sstevel@tonic-gate {
10317c478bd9Sstevel@tonic-gate static const char box_lid[] =
10327c478bd9Sstevel@tonic-gate "+-----------------------+-----------------------+\n";
10337c478bd9Sstevel@tonic-gate static const char box_sep[] =
10347c478bd9Sstevel@tonic-gate "| | |\n";
10357c478bd9Sstevel@tonic-gate
10367c478bd9Sstevel@tonic-gate char wname[32], rname[32], info1[256], *info2;
10377c478bd9Sstevel@tonic-gate
10387c478bd9Sstevel@tonic-gate if (*depth != 0) {
10397c478bd9Sstevel@tonic-gate mdb_printf(" | ^\n");
10407c478bd9Sstevel@tonic-gate mdb_printf(" v |\n");
10417c478bd9Sstevel@tonic-gate } else
10427c478bd9Sstevel@tonic-gate mdb_printf("\n");
10437c478bd9Sstevel@tonic-gate
10447c478bd9Sstevel@tonic-gate (void) mdb_qname(_WR(q), wname, sizeof (wname));
10457c478bd9Sstevel@tonic-gate (void) mdb_qname(_RD(q), rname, sizeof (rname));
10467c478bd9Sstevel@tonic-gate
10477c478bd9Sstevel@tonic-gate mdb_qinfo(_WR(q), info1, sizeof (info1));
10487c478bd9Sstevel@tonic-gate if ((info2 = strchr(info1, '\n')) != NULL)
10497c478bd9Sstevel@tonic-gate *info2++ = '\0';
10507c478bd9Sstevel@tonic-gate else
10517c478bd9Sstevel@tonic-gate info2 = "";
10527c478bd9Sstevel@tonic-gate
10537c478bd9Sstevel@tonic-gate mdb_printf(box_lid);
10547c478bd9Sstevel@tonic-gate mdb_printf("| 0x%-19p | 0x%-19p | %s\n",
10557c478bd9Sstevel@tonic-gate addr, addr - sizeof (queue_t), info1);
10567c478bd9Sstevel@tonic-gate
10577c478bd9Sstevel@tonic-gate mdb_printf("| %<b>%-21s%</b> | %<b>%-21s%</b> |", wname, rname);
10587c478bd9Sstevel@tonic-gate mdb_flush(); /* Account for buffered terminal sequences */
10597c478bd9Sstevel@tonic-gate
10607c478bd9Sstevel@tonic-gate mdb_printf(" %s\n", info2);
10617c478bd9Sstevel@tonic-gate mdb_printf(box_sep);
10627c478bd9Sstevel@tonic-gate
10637c478bd9Sstevel@tonic-gate mdb_qinfo(_RD(q), info1, sizeof (info1));
10647c478bd9Sstevel@tonic-gate if ((info2 = strchr(info1, '\n')) != NULL)
10657c478bd9Sstevel@tonic-gate *info2++ = '\0';
10667c478bd9Sstevel@tonic-gate else
10677c478bd9Sstevel@tonic-gate info2 = "";
10687c478bd9Sstevel@tonic-gate
10697c478bd9Sstevel@tonic-gate mdb_printf("| cnt = 0t%-13lu | cnt = 0t%-13lu | %s\n",
10707c478bd9Sstevel@tonic-gate _WR(q)->q_count, _RD(q)->q_count, info1);
10717c478bd9Sstevel@tonic-gate
10727c478bd9Sstevel@tonic-gate mdb_printf("| flg = 0x%08x | flg = 0x%08x | %s\n",
10737c478bd9Sstevel@tonic-gate _WR(q)->q_flag, _RD(q)->q_flag, info2);
10747c478bd9Sstevel@tonic-gate
10757c478bd9Sstevel@tonic-gate mdb_printf(box_lid);
10767c478bd9Sstevel@tonic-gate *depth += 1;
10777c478bd9Sstevel@tonic-gate return (0);
10787c478bd9Sstevel@tonic-gate }
10797c478bd9Sstevel@tonic-gate
10807c478bd9Sstevel@tonic-gate /*ARGSUSED*/
10817c478bd9Sstevel@tonic-gate int
stream(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)10827c478bd9Sstevel@tonic-gate stream(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
10837c478bd9Sstevel@tonic-gate {
10847c478bd9Sstevel@tonic-gate uint_t d = 0; /* Depth counter for print_qpair */
10857c478bd9Sstevel@tonic-gate
10867c478bd9Sstevel@tonic-gate if (argc != 0 || !(flags & DCMD_ADDRSPEC))
10877c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
10887c478bd9Sstevel@tonic-gate
10897c478bd9Sstevel@tonic-gate if (mdb_pwalk("writeq", (mdb_walk_cb_t)print_qpair, &d, addr) == -1) {
10907c478bd9Sstevel@tonic-gate mdb_warn("failed to walk writeq");
10917c478bd9Sstevel@tonic-gate return (DCMD_ERR);
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate
10947c478bd9Sstevel@tonic-gate return (DCMD_OK);
10957c478bd9Sstevel@tonic-gate }
10967c478bd9Sstevel@tonic-gate
10977c478bd9Sstevel@tonic-gate int
mblk_walk_init(mdb_walk_state_t * wsp)10987c478bd9Sstevel@tonic-gate mblk_walk_init(mdb_walk_state_t *wsp)
10997c478bd9Sstevel@tonic-gate {
11007c478bd9Sstevel@tonic-gate wsp->walk_data = mdb_alloc(sizeof (mblk_t), UM_SLEEP);
11017c478bd9Sstevel@tonic-gate return (WALK_NEXT);
11027c478bd9Sstevel@tonic-gate }
11037c478bd9Sstevel@tonic-gate
11047c478bd9Sstevel@tonic-gate int
b_cont_step(mdb_walk_state_t * wsp)11057c478bd9Sstevel@tonic-gate b_cont_step(mdb_walk_state_t *wsp)
11067c478bd9Sstevel@tonic-gate {
11077c478bd9Sstevel@tonic-gate int status;
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
11107c478bd9Sstevel@tonic-gate return (WALK_DONE);
11117c478bd9Sstevel@tonic-gate
11127c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (mblk_t), wsp->walk_addr) == -1) {
11137c478bd9Sstevel@tonic-gate mdb_warn("failed to read mblk at %p", wsp->walk_addr);
11147c478bd9Sstevel@tonic-gate return (WALK_DONE);
11157c478bd9Sstevel@tonic-gate }
11167c478bd9Sstevel@tonic-gate
11177c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
11187c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
11197c478bd9Sstevel@tonic-gate
11207c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((mblk_t *)wsp->walk_data)->b_cont);
11217c478bd9Sstevel@tonic-gate return (status);
11227c478bd9Sstevel@tonic-gate }
11237c478bd9Sstevel@tonic-gate
11247c478bd9Sstevel@tonic-gate int
b_next_step(mdb_walk_state_t * wsp)11257c478bd9Sstevel@tonic-gate b_next_step(mdb_walk_state_t *wsp)
11267c478bd9Sstevel@tonic-gate {
11277c478bd9Sstevel@tonic-gate int status;
11287c478bd9Sstevel@tonic-gate
11297c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
11307c478bd9Sstevel@tonic-gate return (WALK_DONE);
11317c478bd9Sstevel@tonic-gate
11327c478bd9Sstevel@tonic-gate if (mdb_vread(wsp->walk_data, sizeof (mblk_t), wsp->walk_addr) == -1) {
11337c478bd9Sstevel@tonic-gate mdb_warn("failed to read mblk at %p", wsp->walk_addr);
11347c478bd9Sstevel@tonic-gate return (WALK_DONE);
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate
11377c478bd9Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
11387c478bd9Sstevel@tonic-gate wsp->walk_cbdata);
11397c478bd9Sstevel@tonic-gate
11407c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)(((mblk_t *)wsp->walk_data)->b_next);
11417c478bd9Sstevel@tonic-gate return (status);
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate
11447c478bd9Sstevel@tonic-gate void
mblk_walk_fini(mdb_walk_state_t * wsp)11457c478bd9Sstevel@tonic-gate mblk_walk_fini(mdb_walk_state_t *wsp)
11467c478bd9Sstevel@tonic-gate {
11477c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (mblk_t));
11487c478bd9Sstevel@tonic-gate }
11497c478bd9Sstevel@tonic-gate
11507c478bd9Sstevel@tonic-gate /* ARGSUSED */
11517c478bd9Sstevel@tonic-gate int
mblk2dblk(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11527c478bd9Sstevel@tonic-gate mblk2dblk(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11537c478bd9Sstevel@tonic-gate {
11547c478bd9Sstevel@tonic-gate mblk_t mb;
11557c478bd9Sstevel@tonic-gate
11567c478bd9Sstevel@tonic-gate if (argc != 0)
11577c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
11587c478bd9Sstevel@tonic-gate
11597c478bd9Sstevel@tonic-gate if (mdb_vread(&mb, sizeof (mb), addr) == -1) {
11607c478bd9Sstevel@tonic-gate mdb_warn("couldn't read mblk at %p", addr);
11617c478bd9Sstevel@tonic-gate return (DCMD_ERR);
11627c478bd9Sstevel@tonic-gate }
11637c478bd9Sstevel@tonic-gate
11647c478bd9Sstevel@tonic-gate mdb_printf("%p\n", mb.b_datap);
11657c478bd9Sstevel@tonic-gate return (DCMD_OK);
11667c478bd9Sstevel@tonic-gate }
11677c478bd9Sstevel@tonic-gate
11687c478bd9Sstevel@tonic-gate static void
mblk_error(int * error,uintptr_t addr,char * message)11697c478bd9Sstevel@tonic-gate mblk_error(int *error, uintptr_t addr, char *message)
11707c478bd9Sstevel@tonic-gate {
11717c478bd9Sstevel@tonic-gate if (!*error)
11727c478bd9Sstevel@tonic-gate mdb_printf("%?lx: ", addr);
11737c478bd9Sstevel@tonic-gate else
11747c478bd9Sstevel@tonic-gate mdb_printf(", ");
11757c478bd9Sstevel@tonic-gate mdb_printf("%s", message);
11767c478bd9Sstevel@tonic-gate *error = 1;
11777c478bd9Sstevel@tonic-gate }
11787c478bd9Sstevel@tonic-gate
11797c478bd9Sstevel@tonic-gate int
mblk_verify(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)11807c478bd9Sstevel@tonic-gate mblk_verify(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
11817c478bd9Sstevel@tonic-gate {
11827c478bd9Sstevel@tonic-gate mblk_t mb;
11837c478bd9Sstevel@tonic-gate dblk_t db;
11847c478bd9Sstevel@tonic-gate int error = 0;
11857c478bd9Sstevel@tonic-gate
11867c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
11877c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("streams_mblk", "mblk_verify", argc, argv) ==
11887c478bd9Sstevel@tonic-gate -1) {
11897c478bd9Sstevel@tonic-gate mdb_warn("can't walk mblk cache");
11907c478bd9Sstevel@tonic-gate return (DCMD_ERR);
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate return (DCMD_OK);
11937c478bd9Sstevel@tonic-gate }
11947c478bd9Sstevel@tonic-gate
11957c478bd9Sstevel@tonic-gate if (mdb_vread(&mb, sizeof (mblk_t), addr) == -1) {
11967c478bd9Sstevel@tonic-gate mdb_warn("can't read mblk_t at 0x%lx", addr);
11977c478bd9Sstevel@tonic-gate return (DCMD_ERR);
11987c478bd9Sstevel@tonic-gate }
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate if (mdb_vread(&db, sizeof (dblk_t), (uintptr_t)mb.b_datap) == -1) {
12017c478bd9Sstevel@tonic-gate mdb_warn("%?lx: invalid b_datap pointer\n", addr);
12027c478bd9Sstevel@tonic-gate return (DCMD_ERR);
12037c478bd9Sstevel@tonic-gate }
12047c478bd9Sstevel@tonic-gate
12057c478bd9Sstevel@tonic-gate if (mb.b_rptr < db.db_base || mb.b_rptr > db.db_lim)
12067c478bd9Sstevel@tonic-gate mblk_error(&error, addr, "b_rptr out of range");
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate if (mb.b_wptr < db.db_base || mb.b_wptr > db.db_lim)
12097c478bd9Sstevel@tonic-gate mblk_error(&error, addr, "b_wptr out of range");
12107c478bd9Sstevel@tonic-gate
12117c478bd9Sstevel@tonic-gate if (error)
12127c478bd9Sstevel@tonic-gate mdb_printf("\n");
12137c478bd9Sstevel@tonic-gate
12147c478bd9Sstevel@tonic-gate return (error ? DCMD_ERR : DCMD_OK);
12157c478bd9Sstevel@tonic-gate }
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate int
mblk_prt(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)12187c478bd9Sstevel@tonic-gate mblk_prt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
12197c478bd9Sstevel@tonic-gate {
12207c478bd9Sstevel@tonic-gate const int MBLK_FLGDELT = (int)(sizeof (uintptr_t) * 2 + 15);
12217c478bd9Sstevel@tonic-gate mblk_t mblk;
12227c478bd9Sstevel@tonic-gate dblk_t dblk;
12237c478bd9Sstevel@tonic-gate int b_flag;
12247c478bd9Sstevel@tonic-gate int db_type;
12257c478bd9Sstevel@tonic-gate int mblklen;
12267c478bd9Sstevel@tonic-gate uint64_t len = ~0UL;
12277c478bd9Sstevel@tonic-gate uint64_t glen = ~0UL;
12287c478bd9Sstevel@tonic-gate uint64_t llen = ~0UL;
12297c478bd9Sstevel@tonic-gate uint64_t blen = ~0UL;
12307c478bd9Sstevel@tonic-gate const char *dbtype;
12317c478bd9Sstevel@tonic-gate const char *flag = NULL, *not_flag = NULL;
12327c478bd9Sstevel@tonic-gate const char *typ = NULL, *not_typ = NULL;
12337c478bd9Sstevel@tonic-gate uintptr_t dbaddr = 0;
12347c478bd9Sstevel@tonic-gate uint32_t tmask = 0, not_tmask = 0;
12357c478bd9Sstevel@tonic-gate uint32_t mask = 0, not_mask = 0;
12367c478bd9Sstevel@tonic-gate uint_t quiet = FALSE;
12377c478bd9Sstevel@tonic-gate uint_t verbose = FALSE;
12387c478bd9Sstevel@tonic-gate
12397c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
12407c478bd9Sstevel@tonic-gate if (mdb_walk_dcmd("genunix`streams_mblk", "genunix`mblk",
12417c478bd9Sstevel@tonic-gate argc, argv) == -1) {
12427c478bd9Sstevel@tonic-gate mdb_warn("failed to walk mblk cache");
12437c478bd9Sstevel@tonic-gate return (DCMD_ERR);
12447c478bd9Sstevel@tonic-gate }
12457c478bd9Sstevel@tonic-gate return (DCMD_OK);
12467c478bd9Sstevel@tonic-gate }
12477c478bd9Sstevel@tonic-gate
12487c478bd9Sstevel@tonic-gate if (flags & DCMD_PIPE_OUT)
12497c478bd9Sstevel@tonic-gate quiet = TRUE;
12507c478bd9Sstevel@tonic-gate
12517c478bd9Sstevel@tonic-gate if (mdb_getopts(argc, argv,
12527c478bd9Sstevel@tonic-gate 'v', MDB_OPT_SETBITS, TRUE, &verbose,
12537c478bd9Sstevel@tonic-gate 'q', MDB_OPT_SETBITS, TRUE, &quiet,
12547c478bd9Sstevel@tonic-gate 'f', MDB_OPT_STR, &flag,
12557c478bd9Sstevel@tonic-gate 'F', MDB_OPT_STR, ¬_flag,
12567c478bd9Sstevel@tonic-gate 't', MDB_OPT_STR, &typ,
12577c478bd9Sstevel@tonic-gate 'T', MDB_OPT_STR, ¬_typ,
12587c478bd9Sstevel@tonic-gate 'l', MDB_OPT_UINT64, &len,
12597c478bd9Sstevel@tonic-gate 'L', MDB_OPT_UINT64, &llen,
12607c478bd9Sstevel@tonic-gate 'G', MDB_OPT_UINT64, &glen,
12617c478bd9Sstevel@tonic-gate 'b', MDB_OPT_UINT64, &blen,
12627c478bd9Sstevel@tonic-gate 'd', MDB_OPT_UINTPTR, &dbaddr,
12637c478bd9Sstevel@tonic-gate NULL) != argc)
12647c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
12657c478bd9Sstevel@tonic-gate
12667c478bd9Sstevel@tonic-gate /*
12677c478bd9Sstevel@tonic-gate * If any of the filtering flags is specified, don't print anything
12687c478bd9Sstevel@tonic-gate * except the matching pointer.
12697c478bd9Sstevel@tonic-gate */
12707c478bd9Sstevel@tonic-gate if ((flag != NULL) || (not_flag != NULL) || (typ != NULL) ||
12717c478bd9Sstevel@tonic-gate (not_typ != NULL) || (len != ~0UL) || (glen != ~0UL) ||
12727c478bd9Sstevel@tonic-gate (llen != ~0UL) || (blen != ~0UL) || (dbaddr != 0))
12737c478bd9Sstevel@tonic-gate quiet = TRUE;
12747c478bd9Sstevel@tonic-gate
12757c478bd9Sstevel@tonic-gate if (flag != NULL && streams_parse_flag(mbf, flag, &mask) == -1) {
12767c478bd9Sstevel@tonic-gate mdb_warn("unrecognized mblk flag '%s'\n", flag);
12777c478bd9Sstevel@tonic-gate streams_flag_usage(mbf);
12787c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
12797c478bd9Sstevel@tonic-gate }
12807c478bd9Sstevel@tonic-gate
12817c478bd9Sstevel@tonic-gate if (not_flag != NULL &&
12827c478bd9Sstevel@tonic-gate streams_parse_flag(mbf, not_flag, ¬_mask) == -1) {
12837c478bd9Sstevel@tonic-gate mdb_warn("unrecognized mblk flag '%s'\n", flag);
12847c478bd9Sstevel@tonic-gate streams_flag_usage(mbf);
12857c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
12867c478bd9Sstevel@tonic-gate }
12877c478bd9Sstevel@tonic-gate
12887c478bd9Sstevel@tonic-gate if (typ != NULL && streams_parse_type(mbt, typ, &tmask) == -1) {
12897c478bd9Sstevel@tonic-gate mdb_warn("unrecognized dblk type '%s'\n", typ);
12907c478bd9Sstevel@tonic-gate streams_type_usage(mbt);
12917c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
12927c478bd9Sstevel@tonic-gate }
12937c478bd9Sstevel@tonic-gate
12947c478bd9Sstevel@tonic-gate if (not_typ != NULL && streams_parse_type(mbt, not_typ, ¬_tmask)
12957c478bd9Sstevel@tonic-gate == -1) {
12967c478bd9Sstevel@tonic-gate mdb_warn("unrecognized dblk type '%s'\n", not_typ);
12977c478bd9Sstevel@tonic-gate streams_type_usage(mbt);
12987c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
12997c478bd9Sstevel@tonic-gate }
13007c478bd9Sstevel@tonic-gate
13017c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags) && !quiet) {
13027c478bd9Sstevel@tonic-gate mdb_printf("%?s %2s %-7s %-5s %-5s %?s %?s\n",
13037c478bd9Sstevel@tonic-gate "ADDR", "FL", "TYPE", "LEN", "BLEN", "RPTR", "DBLK");
13047c478bd9Sstevel@tonic-gate }
13057c478bd9Sstevel@tonic-gate
13067c478bd9Sstevel@tonic-gate if (mdb_vread(&mblk, sizeof (mblk), addr) == -1) {
13077c478bd9Sstevel@tonic-gate mdb_warn("couldn't read mblk at %p", addr);
13087c478bd9Sstevel@tonic-gate return (DCMD_ERR);
13097c478bd9Sstevel@tonic-gate }
13107c478bd9Sstevel@tonic-gate b_flag = mblk.b_flag;
13117c478bd9Sstevel@tonic-gate
13127c478bd9Sstevel@tonic-gate if (mask != 0 && !(b_flag & mask))
13137c478bd9Sstevel@tonic-gate return (DCMD_OK);
13147c478bd9Sstevel@tonic-gate
13157c478bd9Sstevel@tonic-gate if (not_mask != 0 && (b_flag & not_mask))
13167c478bd9Sstevel@tonic-gate return (DCMD_OK);
13177c478bd9Sstevel@tonic-gate
13187c478bd9Sstevel@tonic-gate if (mdb_vread(&dblk, sizeof (dblk), (uintptr_t)(mblk.b_datap)) == -1) {
13197c478bd9Sstevel@tonic-gate mdb_warn("couldn't read dblk at %p/%p", addr, mblk.b_datap);
13207c478bd9Sstevel@tonic-gate return (DCMD_ERR);
13217c478bd9Sstevel@tonic-gate }
13227c478bd9Sstevel@tonic-gate db_type = dblk.db_type;
13237c478bd9Sstevel@tonic-gate
13247c478bd9Sstevel@tonic-gate /* M_DATA is 0, so tmask has special value 0xff for it */
1325ca9327a6Smeem if (tmask != 0) {
1326ca9327a6Smeem if ((tmask == M_DATA_T && db_type != M_DATA) ||
1327ca9327a6Smeem (tmask != M_DATA_T && db_type != tmask))
13287c478bd9Sstevel@tonic-gate return (DCMD_OK);
1329ca9327a6Smeem }
13307c478bd9Sstevel@tonic-gate
1331ca9327a6Smeem if (not_tmask != 0) {
1332ca9327a6Smeem if ((not_tmask == M_DATA_T && db_type == M_DATA) ||
1333ca9327a6Smeem (db_type == not_tmask))
13347c478bd9Sstevel@tonic-gate return (DCMD_OK);
1335ca9327a6Smeem }
13367c478bd9Sstevel@tonic-gate
13377c478bd9Sstevel@tonic-gate if (dbaddr != 0 && (uintptr_t)mblk.b_datap != dbaddr)
13387c478bd9Sstevel@tonic-gate return (DCMD_OK);
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate mblklen = MBLKL(&mblk);
13417c478bd9Sstevel@tonic-gate
13427c478bd9Sstevel@tonic-gate if ((len != ~0UL) && (len != mblklen))
13437c478bd9Sstevel@tonic-gate return (DCMD_OK);
13447c478bd9Sstevel@tonic-gate
13457c478bd9Sstevel@tonic-gate if ((llen != ~0Ul) && (mblklen > (int)llen))
13467c478bd9Sstevel@tonic-gate return (DCMD_OK);
13477c478bd9Sstevel@tonic-gate
13487c478bd9Sstevel@tonic-gate if ((glen != ~0Ul) && (mblklen < (int)glen))
13497c478bd9Sstevel@tonic-gate return (DCMD_OK);
13507c478bd9Sstevel@tonic-gate
13517c478bd9Sstevel@tonic-gate if ((blen != ~0UL) && (blen != (dblk.db_lim - dblk.db_base)))
13527c478bd9Sstevel@tonic-gate return (DCMD_OK);
13537c478bd9Sstevel@tonic-gate
13547c478bd9Sstevel@tonic-gate /*
13557c478bd9Sstevel@tonic-gate * Options are specified for filtering, so If any option is specified on
13567c478bd9Sstevel@tonic-gate * the command line, just print address and exit.
13577c478bd9Sstevel@tonic-gate */
13587c478bd9Sstevel@tonic-gate if (quiet) {
13597c478bd9Sstevel@tonic-gate mdb_printf("%0?p\n", addr);
13607c478bd9Sstevel@tonic-gate return (DCMD_OK);
13617c478bd9Sstevel@tonic-gate }
13627c478bd9Sstevel@tonic-gate
13637c478bd9Sstevel@tonic-gate /* Figure out symbolic DB_TYPE */
13647c478bd9Sstevel@tonic-gate if (db_type < A_SIZE(db_control_types)) {
13657c478bd9Sstevel@tonic-gate dbtype = db_control_types[db_type];
13667c478bd9Sstevel@tonic-gate } else {
13677c478bd9Sstevel@tonic-gate /*
13687c478bd9Sstevel@tonic-gate * Must be a high-priority message -- adjust so that
13697c478bd9Sstevel@tonic-gate * "QPCTL + 1" corresponds to db_control_hipri_types[0]
13707c478bd9Sstevel@tonic-gate */
13717c478bd9Sstevel@tonic-gate db_type -= (QPCTL + 1);
13727c478bd9Sstevel@tonic-gate if (db_type >= 0 && db_type < A_SIZE(db_control_hipri_types))
13737c478bd9Sstevel@tonic-gate dbtype = db_control_hipri_types[db_type];
13747c478bd9Sstevel@tonic-gate else
13757c478bd9Sstevel@tonic-gate dbtype = "UNKNOWN";
13767c478bd9Sstevel@tonic-gate }
13777c478bd9Sstevel@tonic-gate
13787c478bd9Sstevel@tonic-gate mdb_printf("%0?p %-2x %-7s %-5d %-5d %0?p %0?p\n",
13797c478bd9Sstevel@tonic-gate addr, b_flag, dbtype, mblklen, dblk.db_lim - dblk.db_base,
13807c478bd9Sstevel@tonic-gate mblk.b_rptr, mblk.b_datap);
13817c478bd9Sstevel@tonic-gate
13827c478bd9Sstevel@tonic-gate if (verbose) {
13837c478bd9Sstevel@tonic-gate int i, arm = 0;
13847c478bd9Sstevel@tonic-gate
13857c478bd9Sstevel@tonic-gate for (i = 0; mbf[i].strf_name != NULL; i++) {
13867c478bd9Sstevel@tonic-gate if (!(b_flag & (1 << i)))
13877c478bd9Sstevel@tonic-gate continue;
13887c478bd9Sstevel@tonic-gate if (!arm) {
13897c478bd9Sstevel@tonic-gate mdb_printf("%*s|\n%*s+--> ",
13907c478bd9Sstevel@tonic-gate MBLK_FLGDELT, "", MBLK_FLGDELT, "");
13917c478bd9Sstevel@tonic-gate arm = 1;
13927c478bd9Sstevel@tonic-gate } else
13937c478bd9Sstevel@tonic-gate mdb_printf("%*s ", MBLK_FLGDELT, "");
13947c478bd9Sstevel@tonic-gate
13957c478bd9Sstevel@tonic-gate mdb_printf("%-12s %s\n",
13967c478bd9Sstevel@tonic-gate mbf[i].strf_name, mbf[i].strf_descr);
13977c478bd9Sstevel@tonic-gate }
13987c478bd9Sstevel@tonic-gate }
13997c478bd9Sstevel@tonic-gate return (DCMD_OK);
14007c478bd9Sstevel@tonic-gate }
14017c478bd9Sstevel@tonic-gate
14027c478bd9Sstevel@tonic-gate /*
14037c478bd9Sstevel@tonic-gate * Streams flow trace walkers.
14047c478bd9Sstevel@tonic-gate */
14057c478bd9Sstevel@tonic-gate
14067c478bd9Sstevel@tonic-gate int
strftblk_walk_init(mdb_walk_state_t * wsp)14077c478bd9Sstevel@tonic-gate strftblk_walk_init(mdb_walk_state_t *wsp)
14087c478bd9Sstevel@tonic-gate {
14097c478bd9Sstevel@tonic-gate ftblkdata_t *ftd;
14107c478bd9Sstevel@tonic-gate dblk_t db;
14117c478bd9Sstevel@tonic-gate
14127c478bd9Sstevel@tonic-gate /* Get the dblock from the address */
14137c478bd9Sstevel@tonic-gate if (mdb_vread(&db, sizeof (dblk_t), wsp->walk_addr) == -1) {
14147c478bd9Sstevel@tonic-gate mdb_warn("failed to read dblk at %p", wsp->walk_addr);
14157c478bd9Sstevel@tonic-gate return (WALK_ERR);
14167c478bd9Sstevel@tonic-gate }
14177c478bd9Sstevel@tonic-gate
14187c478bd9Sstevel@tonic-gate /* Is there any flow trace data? */
14197c478bd9Sstevel@tonic-gate if (db.db_fthdr == NULL) {
14207c478bd9Sstevel@tonic-gate return (WALK_DONE);
14217c478bd9Sstevel@tonic-gate }
14227c478bd9Sstevel@tonic-gate
14237c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)((char *)db.db_fthdr +
14247c478bd9Sstevel@tonic-gate offsetof(fthdr_t, first));
14257c478bd9Sstevel@tonic-gate
14267c478bd9Sstevel@tonic-gate ftd = mdb_alloc(sizeof (ftblkdata_t), UM_SLEEP);
14277c478bd9Sstevel@tonic-gate ftd->ft_ix = 0;
14287c478bd9Sstevel@tonic-gate ftd->ft_in_evlist = B_FALSE;
14297c478bd9Sstevel@tonic-gate wsp->walk_data = ftd;
14307c478bd9Sstevel@tonic-gate
14317c478bd9Sstevel@tonic-gate return (WALK_NEXT);
14327c478bd9Sstevel@tonic-gate }
14337c478bd9Sstevel@tonic-gate
14347c478bd9Sstevel@tonic-gate int
strftblk_step(mdb_walk_state_t * wsp)14357c478bd9Sstevel@tonic-gate strftblk_step(mdb_walk_state_t *wsp)
14367c478bd9Sstevel@tonic-gate {
14377c478bd9Sstevel@tonic-gate ftblkdata_t *ftd;
14387c478bd9Sstevel@tonic-gate ftblk_t *ftbp;
14397c478bd9Sstevel@tonic-gate int status = WALK_NEXT;
14407c478bd9Sstevel@tonic-gate
14417c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL)
14427c478bd9Sstevel@tonic-gate return (WALK_DONE);
14437c478bd9Sstevel@tonic-gate
14447c478bd9Sstevel@tonic-gate ftd = (ftblkdata_t *)wsp->walk_data;
14457c478bd9Sstevel@tonic-gate ftbp = &(ftd->ft_data);
14467c478bd9Sstevel@tonic-gate
14477c478bd9Sstevel@tonic-gate if (! ftd->ft_in_evlist) {
14487c478bd9Sstevel@tonic-gate /* Read a new ft block */
14497c478bd9Sstevel@tonic-gate if (mdb_vread(ftbp, sizeof (ftblk_t),
14507c478bd9Sstevel@tonic-gate wsp->walk_addr) == -1) {
14517c478bd9Sstevel@tonic-gate mdb_warn("failed to read ftblk at %p", wsp->walk_addr);
14527c478bd9Sstevel@tonic-gate return (WALK_ERR);
14537c478bd9Sstevel@tonic-gate }
14547c478bd9Sstevel@tonic-gate /*
14557c478bd9Sstevel@tonic-gate * Check correctness of the index field.
14567c478bd9Sstevel@tonic-gate */
14577c478bd9Sstevel@tonic-gate if (ftbp->ix < 0 || ftbp->ix > FTBLK_EVNTS) {
14587c478bd9Sstevel@tonic-gate mdb_warn("ftblk: incorrect index value %i\n", ftbp->ix);
14597c478bd9Sstevel@tonic-gate return (WALK_ERR);
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate ftd->ft_ix = 1;
14627c478bd9Sstevel@tonic-gate ftd->ft_in_evlist = B_TRUE;
14637c478bd9Sstevel@tonic-gate }
14647c478bd9Sstevel@tonic-gate
14657c478bd9Sstevel@tonic-gate if (ftd->ft_ix > ftbp->ix) {
14667c478bd9Sstevel@tonic-gate ftd->ft_in_evlist = B_FALSE;
14677c478bd9Sstevel@tonic-gate /* End of event list reached - move to the next event block */
14687c478bd9Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)ftbp->nxt;
14697c478bd9Sstevel@tonic-gate } else {
14707c478bd9Sstevel@tonic-gate /* Print event address */
14717c478bd9Sstevel@tonic-gate status = wsp->walk_callback((uintptr_t)((char *)wsp->walk_addr +
14727c478bd9Sstevel@tonic-gate offsetof(ftblk_t, ev) +
14737c478bd9Sstevel@tonic-gate (ftd->ft_ix - 1) * sizeof (struct ftevnt)),
14747c478bd9Sstevel@tonic-gate wsp->walk_data, wsp->walk_cbdata);
14757c478bd9Sstevel@tonic-gate ftd->ft_ix++;
14767c478bd9Sstevel@tonic-gate }
14777c478bd9Sstevel@tonic-gate
14787c478bd9Sstevel@tonic-gate return (status);
14797c478bd9Sstevel@tonic-gate }
14807c478bd9Sstevel@tonic-gate
14817c478bd9Sstevel@tonic-gate void
strftblk_walk_fini(mdb_walk_state_t * wsp)14827c478bd9Sstevel@tonic-gate strftblk_walk_fini(mdb_walk_state_t *wsp)
14837c478bd9Sstevel@tonic-gate {
14847c478bd9Sstevel@tonic-gate mdb_free(wsp->walk_data, sizeof (ftblkdata_t));
14857c478bd9Sstevel@tonic-gate }
14867c478bd9Sstevel@tonic-gate
1487*a45f3f93Smeem static const char *
getqname(const void * nameptr,char * buf,uint_t bufsize)1488*a45f3f93Smeem getqname(const void *nameptr, char *buf, uint_t bufsize)
1489*a45f3f93Smeem {
1490*a45f3f93Smeem char *cp;
1491*a45f3f93Smeem
1492*a45f3f93Smeem if (mdb_readstr(buf, bufsize, (uintptr_t)nameptr) == -1)
1493*a45f3f93Smeem goto fail;
1494*a45f3f93Smeem
1495*a45f3f93Smeem /*
1496*a45f3f93Smeem * Sanity-check the name we read. This is needed because the pointer
1497*a45f3f93Smeem * value may have been recycled for some other purpose in the kernel
1498*a45f3f93Smeem * (e.g., if the STREAMS module was unloaded).
1499*a45f3f93Smeem */
1500*a45f3f93Smeem for (cp = buf; *cp != '\0'; cp++) {
1501*a45f3f93Smeem if (!isprint(*cp))
1502*a45f3f93Smeem goto fail;
1503*a45f3f93Smeem }
1504*a45f3f93Smeem return (buf);
1505*a45f3f93Smeem fail:
1506*a45f3f93Smeem return (strncpy(buf, "?", bufsize));
1507*a45f3f93Smeem }
1508*a45f3f93Smeem
15097c478bd9Sstevel@tonic-gate /*ARGSUSED*/
15107c478bd9Sstevel@tonic-gate int
strftevent(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)15117c478bd9Sstevel@tonic-gate strftevent(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
15127c478bd9Sstevel@tonic-gate {
1513*a45f3f93Smeem int i;
1514*a45f3f93Smeem struct ftstk stk;
15157c478bd9Sstevel@tonic-gate struct ftevnt ev;
1516*a45f3f93Smeem char name[FMNAMESZ + 1];
1517*a45f3f93Smeem boolean_t havestk = B_FALSE;
15187c478bd9Sstevel@tonic-gate
15197c478bd9Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC))
15207c478bd9Sstevel@tonic-gate return (DCMD_USAGE);
15217c478bd9Sstevel@tonic-gate
15227c478bd9Sstevel@tonic-gate if (DCMD_HDRSPEC(flags)) {
1523*a45f3f93Smeem mdb_printf("%?s %-18s %-9s %-18s %4s %s\n",
1524*a45f3f93Smeem "ADDR", "Q/CALLER", "QNEXT", "STACK", "DATA", "EVENT");
15257c478bd9Sstevel@tonic-gate }
15267c478bd9Sstevel@tonic-gate
15277c478bd9Sstevel@tonic-gate if (mdb_vread(&ev, sizeof (ev), addr) == -1) {
1528*a45f3f93Smeem mdb_warn("couldn't read struct ftevnt at %p", addr);
15297c478bd9Sstevel@tonic-gate return (DCMD_ERR);
15307c478bd9Sstevel@tonic-gate }
15317c478bd9Sstevel@tonic-gate
1532*a45f3f93Smeem mdb_printf("%0?p", addr);
15337c478bd9Sstevel@tonic-gate
1534*a45f3f93Smeem if (ev.evnt & FTEV_QMASK)
1535*a45f3f93Smeem mdb_printf(" %-18s", getqname(ev.mid, name, sizeof (name)));
1536*a45f3f93Smeem else
1537*a45f3f93Smeem mdb_printf(" %-18a", ev.mid);
15387c478bd9Sstevel@tonic-gate
1539*a45f3f93Smeem if ((ev.evnt & FTEV_MASK) == FTEV_PUTNEXT)
1540*a45f3f93Smeem mdb_printf(" %-9s", getqname(ev.midnext, name, sizeof (name)));
1541*a45f3f93Smeem else
1542*a45f3f93Smeem mdb_printf(" %-9s", "--");
1543*a45f3f93Smeem
1544*a45f3f93Smeem if (ev.stk == NULL) {
1545*a45f3f93Smeem mdb_printf(" %-18s", "--");
1546*a45f3f93Smeem } else if (mdb_vread(&stk, sizeof (stk), (uintptr_t)ev.stk) == -1) {
1547*a45f3f93Smeem mdb_printf(" %-18s", "?");
1548*a45f3f93Smeem } else {
1549*a45f3f93Smeem mdb_printf(" %-18a", stk.fs_stk[0]);
1550*a45f3f93Smeem havestk = B_TRUE;
1551*a45f3f93Smeem }
1552*a45f3f93Smeem
1553*a45f3f93Smeem mdb_printf(" %4x", ev.data);
15547c478bd9Sstevel@tonic-gate ft_printevent(ev.evnt);
15557c478bd9Sstevel@tonic-gate mdb_printf("\n");
15567c478bd9Sstevel@tonic-gate
1557*a45f3f93Smeem if (havestk) {
1558*a45f3f93Smeem for (i = 1; i < stk.fs_depth; i++) {
1559*a45f3f93Smeem mdb_printf("%?s %-18s %-9s %-18a\n", "", "", "",
1560*a45f3f93Smeem stk.fs_stk[i]);
1561*a45f3f93Smeem }
1562*a45f3f93Smeem }
1563*a45f3f93Smeem
15647c478bd9Sstevel@tonic-gate return (DCMD_OK);
15657c478bd9Sstevel@tonic-gate }
15667c478bd9Sstevel@tonic-gate
15677c478bd9Sstevel@tonic-gate static void
ft_printevent(ushort_t ev)15687c478bd9Sstevel@tonic-gate ft_printevent(ushort_t ev)
15697c478bd9Sstevel@tonic-gate {
15707c478bd9Sstevel@tonic-gate ushort_t proc_ev = (ev & (FTEV_PROC_START | 0xFF)) - FTEV_PROC_START;
15717c478bd9Sstevel@tonic-gate ushort_t alloc_ev = ev & FTEV_CALLER;
15727c478bd9Sstevel@tonic-gate
15737c478bd9Sstevel@tonic-gate /* Get event class first */
15747c478bd9Sstevel@tonic-gate if (ev & FTEV_PROC_START) {
15757c478bd9Sstevel@tonic-gate if (proc_ev >= A_SIZE(ftev_proc))
15767c478bd9Sstevel@tonic-gate mdb_printf(" undefined");
15777c478bd9Sstevel@tonic-gate else
15787c478bd9Sstevel@tonic-gate mdb_printf(" %s", ftev_proc[proc_ev]);
1579*a45f3f93Smeem } else if (alloc_ev >= A_SIZE(ftev_alloc)) {
15807c478bd9Sstevel@tonic-gate mdb_printf(" undefined");
1581*a45f3f93Smeem } else {
15827c478bd9Sstevel@tonic-gate mdb_printf(" %s", ftev_alloc[alloc_ev]);
1583*a45f3f93Smeem }
15847c478bd9Sstevel@tonic-gate
15857c478bd9Sstevel@tonic-gate /* Print event modifiers, if any */
1586*a45f3f93Smeem if (ev & (FTEV_PS | FTEV_CS | FTEV_ISWR)) {
1587*a45f3f93Smeem mdb_printf("|");
15887c478bd9Sstevel@tonic-gate if (ev & FTEV_ISWR)
1589*a45f3f93Smeem mdb_printf("W");
1590*a45f3f93Smeem if (ev & FTEV_CS)
1591*a45f3f93Smeem mdb_printf("C");
1592*a45f3f93Smeem if (ev & FTEV_PS)
1593*a45f3f93Smeem mdb_printf("P");
1594*a45f3f93Smeem }
15957c478bd9Sstevel@tonic-gate }
15967c478bd9Sstevel@tonic-gate
15977c478bd9Sstevel@tonic-gate /*
15987c478bd9Sstevel@tonic-gate * Help functions for STREAMS debugging facilities.
15997c478bd9Sstevel@tonic-gate */
16007c478bd9Sstevel@tonic-gate void
queue_help(void)16017c478bd9Sstevel@tonic-gate queue_help(void)
16027c478bd9Sstevel@tonic-gate {
16037c478bd9Sstevel@tonic-gate mdb_printf("Print queue information for a given queue pointer.\n"
16047c478bd9Sstevel@tonic-gate "\nWithout the address of a \"queue_t\" structure given, print "
16057c478bd9Sstevel@tonic-gate "information about all\n"
16067c478bd9Sstevel@tonic-gate "queues in the \"queue_cache\".\n\n"
16077c478bd9Sstevel@tonic-gate "Options:\n"
16087c478bd9Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n"
16097c478bd9Sstevel@tonic-gate " -q:\t\tbe quiet - print queue pointer only\n"
16107c478bd9Sstevel@tonic-gate " -f flag:\tprint only queues with flag set\n"
16117c478bd9Sstevel@tonic-gate " -F flag:\tprint only queues with flag NOT set\n"
16127c478bd9Sstevel@tonic-gate " -m modname:\tprint only queues with specified module name\n"
16137c478bd9Sstevel@tonic-gate " -s syncq_addr:\tprint only queues which use specified syncq\n\n"
16147c478bd9Sstevel@tonic-gate "Available conversions:\n"
16157c478bd9Sstevel@tonic-gate " q2rdq: given a queue addr print read queue pointer\n"
16167c478bd9Sstevel@tonic-gate " q2wrq: given a queue addr print write queue pointer\n"
16177c478bd9Sstevel@tonic-gate " q2otherq: given a queue addr print other queue pointer\n"
16187c478bd9Sstevel@tonic-gate " q2syncq: given a queue addr print syncq pointer"
16197c478bd9Sstevel@tonic-gate " (::help syncq)\n"
16207c478bd9Sstevel@tonic-gate " q2stream: given a queue addr print its stream pointer\n"
16217c478bd9Sstevel@tonic-gate "\t\t(see ::help stream and ::help stdata)\n\n"
16227c478bd9Sstevel@tonic-gate "To walk q_next pointer of the queue use\n"
16237c478bd9Sstevel@tonic-gate " queue_addr::walk qnext\n");
16247c478bd9Sstevel@tonic-gate }
16257c478bd9Sstevel@tonic-gate
16267c478bd9Sstevel@tonic-gate void
syncq_help(void)16277c478bd9Sstevel@tonic-gate syncq_help(void)
16287c478bd9Sstevel@tonic-gate {
16297c478bd9Sstevel@tonic-gate mdb_printf("Print syncq information for a given syncq pointer.\n"
16307c478bd9Sstevel@tonic-gate "\nWithout the address of a \"syncq_t\" structure given, print "
16317c478bd9Sstevel@tonic-gate "information about all\n"
16327c478bd9Sstevel@tonic-gate "syncqs in the \"syncq_cache\".\n\n"
16337c478bd9Sstevel@tonic-gate "Options:\n"
16347c478bd9Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n"
16357c478bd9Sstevel@tonic-gate " -q:\t\tbe quiet - print syncq pointer only\n"
16367c478bd9Sstevel@tonic-gate " -f flag:\tprint only syncqs with flag set\n"
16377c478bd9Sstevel@tonic-gate " -F flag:\tprint only syncqs with flag NOT set\n"
16387c478bd9Sstevel@tonic-gate " -t type:\tprint only syncqs with specified type\n"
16397c478bd9Sstevel@tonic-gate " -T type:\tprint only syncqs with do NOT have specified type\n\n"
16407c478bd9Sstevel@tonic-gate "Available conversions:\n"
16417c478bd9Sstevel@tonic-gate " syncq2q:\tgiven a syncq addr print queue address of the\n"
16427c478bd9Sstevel@tonic-gate "\t\t\tenclosing queue, if it is part of a queue\n\n"
16437c478bd9Sstevel@tonic-gate "See also: \"::help queue\" and \"::help stdata\"\n");
16447c478bd9Sstevel@tonic-gate }
16457c478bd9Sstevel@tonic-gate
16467c478bd9Sstevel@tonic-gate void
stdata_help(void)16477c478bd9Sstevel@tonic-gate stdata_help(void)
16487c478bd9Sstevel@tonic-gate {
16497c478bd9Sstevel@tonic-gate mdb_printf("Print stdata information for a given stdata pointer.\n"
16507c478bd9Sstevel@tonic-gate "\nWithout the address of a \"stdata_t\" structure given, print "
16517c478bd9Sstevel@tonic-gate "information about all\n"
16527c478bd9Sstevel@tonic-gate "stream head pointers from the \"stream_head_cache\".\n\n"
16537c478bd9Sstevel@tonic-gate "Fields printed:\n"
16547c478bd9Sstevel@tonic-gate " ADDR:\tstream head address\n"
16557c478bd9Sstevel@tonic-gate " WRQ:\twrite queue pointer\n"
16567c478bd9Sstevel@tonic-gate " FLAGS:\tstream head flags (use -v to show in symbolic form)\n"
16577c478bd9Sstevel@tonic-gate " VNODE:\tstream vnode pointer\n"
16587c478bd9Sstevel@tonic-gate " N/A:\tpushcount and anchor positions\n"
16597c478bd9Sstevel@tonic-gate " REF:\tstream head reference counter\n\n"
16607c478bd9Sstevel@tonic-gate "Options:\n"
16617c478bd9Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n"
16627c478bd9Sstevel@tonic-gate " -q:\t\tbe quiet - print stdata pointer only\n"
16637c478bd9Sstevel@tonic-gate " -f flag:\tprint only stdatas with flag set\n"
16647c478bd9Sstevel@tonic-gate " -F flag:\tprint only stdatas with flag NOT set\n\n"
16657c478bd9Sstevel@tonic-gate "Available conversions:\n"
16667c478bd9Sstevel@tonic-gate " str2mate:\tgiven a stream head addr print its mate\n"
16677c478bd9Sstevel@tonic-gate " str2wrq:\tgiven a stream head addr print its write queue\n\n"
16687c478bd9Sstevel@tonic-gate "See also: \"::help queue\" and \"::help syncq\"\n");
16697c478bd9Sstevel@tonic-gate }
16707c478bd9Sstevel@tonic-gate
16717c478bd9Sstevel@tonic-gate void
mblk_help(void)16727c478bd9Sstevel@tonic-gate mblk_help(void)
16737c478bd9Sstevel@tonic-gate {
16747c478bd9Sstevel@tonic-gate mdb_printf("Print mblock information for a given mblk pointer.\n"
16757c478bd9Sstevel@tonic-gate "Without the address, print information about all mblocks.\n\n"
16767c478bd9Sstevel@tonic-gate "Fields printed:\n"
16777c478bd9Sstevel@tonic-gate " ADDR:\tmblk address\n"
16787c478bd9Sstevel@tonic-gate " FL:\tFlags\n"
16797c478bd9Sstevel@tonic-gate " TYPE:\tType of corresponding dblock\n"
16807c478bd9Sstevel@tonic-gate " LEN:\tData length as b_wptr - b_rptr\n"
16817c478bd9Sstevel@tonic-gate " BLEN:\tDblock space as db_lim - db_base\n"
16827c478bd9Sstevel@tonic-gate " RPTR:\tRead pointer\n"
16837c478bd9Sstevel@tonic-gate " DBLK:\tDblock pointer\n\n"
16847c478bd9Sstevel@tonic-gate "Options:\n"
16857c478bd9Sstevel@tonic-gate " -v:\t\tbe verbose - print symbolic flags falues\n"
16867c478bd9Sstevel@tonic-gate " -q:\t\tbe quiet - print mblk pointer only\n"
16877c478bd9Sstevel@tonic-gate " -d dbaddr:\t\tprint mblks with specified dblk address\n"
16887c478bd9Sstevel@tonic-gate " -f flag:\tprint only mblks with flag set\n"
16897c478bd9Sstevel@tonic-gate " -F flag:\tprint only mblks with flag NOT set\n"
16907c478bd9Sstevel@tonic-gate " -t type:\tprint only mblks of specified db_type\n"
16917c478bd9Sstevel@tonic-gate " -T type:\tprint only mblks other then the specified db_type\n"
16927c478bd9Sstevel@tonic-gate " -l len:\t\ttprint only mblks with MBLKL == len\n"
16937c478bd9Sstevel@tonic-gate " -L len:\t\tprint only mblks with MBLKL <= len \n"
16947c478bd9Sstevel@tonic-gate " -G len:\t\tprint only mblks with MBLKL >= len \n"
16957c478bd9Sstevel@tonic-gate " -b len:\t\tprint only mblks with db_lim - db_base == len\n"
16967c478bd9Sstevel@tonic-gate "\n");
16977c478bd9Sstevel@tonic-gate }
1698