xref: /illumos-gate/usr/src/cmd/mdb/common/modules/mr_sas/mr_sas.c (revision 9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <limits.h>
27 #include <sys/mdb_modapi.h>
28 #include <sys/sysinfo.h>
29 #include <sys/sunmdi.h>
30 #include <sys/scsi/scsi.h>
31 #include "mr_sas.h"
32 
33 int
34 construct_path(uintptr_t addr, char *result)
35 {
36 	struct	dev_info	d;
37 	char	devi_node[PATH_MAX];
38 	char	devi_addr[PATH_MAX];
39 
40 	if (mdb_vread(&d, sizeof (d), addr) == -1) {
41 		mdb_warn("couldn't read dev_info");
42 		return (DCMD_ERR);
43 	}
44 
45 	if (d.devi_parent) {
46 		construct_path((uintptr_t)d.devi_parent, result);
47 		mdb_readstr(devi_node, sizeof (devi_node),
48 		    (uintptr_t)d.devi_node_name);
49 		mdb_readstr(devi_addr, sizeof (devi_addr),
50 		    (uintptr_t)d.devi_addr);
51 		mdb_snprintf(result+strlen(result),
52 		    PATH_MAX-strlen(result),
53 		    "/%s%s%s", devi_node, (*devi_addr ? "@" : ""),
54 		    devi_addr);
55 	}
56 	return (DCMD_OK);
57 }
58 
59 void
60 display_targets(struct mrsas_instance m, int verbose)
61 {
62 	int	tgt;
63 	struct mrsas_ld *mr_ldp;
64 	char	device_path[PATH_MAX];
65 
66 	if (verbose) {
67 		*device_path = 0;
68 		if (construct_path((uintptr_t)m.dip, device_path) != DCMD_OK) {
69 			strcpy(device_path, "couldn't determine device path");
70 		}
71 	}
72 
73 	mdb_printf("\n");
74 	if (verbose)
75 		mdb_printf("%s\n", device_path);
76 	mdb_printf("dev_type target\n");
77 	mdb_printf("----------");
78 	mdb_printf("\n");
79 	for (tgt = 0; tgt < MRDRV_MAX_LD; tgt++) {
80 		mr_ldp = (struct mrsas_ld *)&m.mr_ld_list[tgt];
81 		if ((mr_ldp != NULL) && (mr_ldp->dip != NULL) &&
82 		    (mr_ldp->lun_type == MRSAS_LD_LUN)) {
83 			mdb_printf("sd %d", tgt);
84 			mdb_printf("\n");
85 		}
86 	}
87 	mdb_printf("\n");
88 }
89 
90 void
91 display_deviceinfo(struct mrsas_instance m)
92 {
93 	uint16_t vid, did, svid, sid;
94 
95 	vid = m.vendor_id;
96 	did = m.device_id;
97 	svid = m.subsysvid;
98 	sid = m.subsysid;
99 
100 	mdb_printf("\n");
101 	mdb_printf("vendor_id device_id subsysvid subsysid");
102 	mdb_printf("\n");
103 	mdb_printf("--------------------------------------");
104 	mdb_printf("\n");
105 	mdb_printf("    0x%x   0x%x    0x%x    0x%x",
106 	    vid, did, svid, sid);
107 	mdb_printf("\n");
108 }
109 
110 static int
111 mr_sas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
112 {
113 	struct mrsas_instance m;
114 
115 	int	instance;
116 	uint16_t ncmds;
117 	uint_t	verbose = FALSE;
118 	uint_t	device_info = FALSE;
119 	uint_t	target_info = FALSE;
120 	int	rv = DCMD_OK;
121 	void	*mrsas_state;
122 
123 	if (!(flags & DCMD_ADDRSPEC)) {
124 		mrsas_state = NULL;
125 		if (mdb_readvar(&mrsas_state, "mrsas_state") == -1) {
126 			mdb_warn("can't read mrsas_state");
127 			return (DCMD_ERR);
128 		}
129 		if (mdb_pwalk_dcmd("genunix`softstate", "mr_sas`mr_sas",
130 		    argc, argv, (uintptr_t)mrsas_state) == -1) {
131 			mdb_warn("mdb_pwalk_dcmd failed");
132 			return (DCMD_ERR);
133 		}
134 		return (DCMD_OK);
135 	}
136 
137 	if (mdb_getopts(argc, argv,
138 	    'd', MDB_OPT_SETBITS, TRUE, &device_info,
139 	    't', MDB_OPT_SETBITS, TRUE, &target_info,
140 	    'v', MDB_OPT_SETBITS, TRUE, &verbose,
141 	    NULL) != argc)
142 		return (DCMD_USAGE);
143 
144 	if (mdb_vread(&m, sizeof (m), addr) == -1) {
145 		mdb_warn("couldn't read mrsas_instance struct at 0x%p", addr);
146 		return (DCMD_ERR);
147 	}
148 	instance = m.instance;
149 
150 	/* cmd slot info */
151 	ncmds = m.max_fw_cmds;
152 
153 	/* processing completed */
154 	if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) ||
155 	    (flags & DCMD_LOOPFIRST)) {
156 		if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST))
157 			mdb_printf("\n");
158 		mdb_printf("         mrsas_t inst max_fw_cmds intr_type");
159 		mdb_printf("\n");
160 		mdb_printf("===========================================");
161 		mdb_printf("\n");
162 	}
163 
164 	mdb_printf("%16p %4d      %4d    ", addr, instance, ncmds);
165 	switch (m.intr_type) {
166 		case DDI_INTR_TYPE_MSIX:
167 			mdb_printf("MSI-X");
168 			break;
169 		case DDI_INTR_TYPE_MSI:
170 			mdb_printf("MSI");
171 			break;
172 		case DDI_INTR_TYPE_FIXED:
173 			mdb_printf("FIXED");
174 			break;
175 		default:
176 			mdb_printf("INVALD");
177 	}
178 	mdb_printf("\n");
179 
180 	if (target_info)
181 		display_targets(m, verbose);
182 
183 	if (device_info)
184 		display_deviceinfo(m);
185 
186 	return (rv);
187 }
188 
189 void
190 mr_sas_help(void)
191 {
192 	mdb_printf("Prints summary information about each mr_sas instance, "
193 	    "Without the address of a \"struct mrsas_instance\", prints every "
194 	    "instance.\n\n"
195 	    "Switches:\n"
196 	    "  -t   includes information about targets\n"
197 	    "  -d   includes information about the hardware\n"
198 	    "  -v   displays extra information for some options\n");
199 }
200 
201 static const mdb_dcmd_t dcmds[] = {
202 	{ "mr_sas", "?[-tdv]", "print mr_sas information", mr_sas_dcmd,
203 	    mr_sas_help },
204 	{ NULL }
205 };
206 
207 static const mdb_modinfo_t modinfo = {
208 	MDB_API_VERSION, dcmds, NULL
209 };
210 
211 const mdb_modinfo_t *
212 _mdb_init(void)
213 {
214 	return (&modinfo);
215 }
216