Print this page
4500 mptsas_hash_traverse() is unsafe, leads to missing devices
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
4499 ::mptsas should show slot/enclosure for targets
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c
+++ new/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 +/*
27 + * Copyright 2014 Joyent, Inc. All rights reserved.
28 + */
29 +
26 30 #include <limits.h>
27 31 #include <sys/mdb_modapi.h>
28 32 #include <sys/sysinfo.h>
29 33 #include <sys/sunmdi.h>
34 +#include <sys/list.h>
30 35 #include <sys/scsi/scsi.h>
31 36
32 37 #pragma pack(1)
33 38 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
34 39 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
35 40 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
36 41 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
37 42 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
38 43 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
39 44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
40 45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
41 46 #pragma pack()
42 47
43 48 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
49 +#include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
44 50
45 51 struct {
46 -
47 52 int value;
48 53 char *text;
49 54 } devinfo_array[] = {
50 55 { MPI2_SAS_DEVICE_INFO_SEP, "SEP" },
51 56 { MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE, "ATAPI device" },
52 57 { MPI2_SAS_DEVICE_INFO_LSI_DEVICE, "LSI device" },
53 58 { MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH, "direct attach" },
54 59 { MPI2_SAS_DEVICE_INFO_SSP_TARGET, "SSP tgt" },
55 60 { MPI2_SAS_DEVICE_INFO_STP_TARGET, "STP tgt" },
56 61 { MPI2_SAS_DEVICE_INFO_SMP_TARGET, "SMP tgt" },
57 62 { MPI2_SAS_DEVICE_INFO_SATA_DEVICE, "SATA dev" },
58 63 { MPI2_SAS_DEVICE_INFO_SSP_INITIATOR, "SSP init" },
59 64 { MPI2_SAS_DEVICE_INFO_STP_INITIATOR, "STP init" },
60 65 { MPI2_SAS_DEVICE_INFO_SMP_INITIATOR, "SMP init" },
61 66 { MPI2_SAS_DEVICE_INFO_SATA_HOST, "SATA host" }
62 67 };
63 68
64 -static int
65 -atoi(const char *p)
66 -{
67 - int n;
68 - int c = *p++;
69 -
70 - for (n = 0; c >= '0' && c <= '9'; c = *p++) {
71 - n *= 10; /* two steps to avoid unnecessary overflow */
72 - n += '0' - c; /* accum neg to avoid surprises at MAX */
73 - }
74 - return (-n);
75 -}
76 -
77 69 int
78 70 construct_path(uintptr_t addr, char *result)
79 71 {
80 72 struct dev_info d;
81 73 char devi_node[PATH_MAX];
82 74 char devi_addr[PATH_MAX];
83 75
84 76 if (mdb_vread(&d, sizeof (d), addr) == -1) {
85 77 mdb_warn("couldn't read dev_info");
86 78 return (DCMD_ERR);
87 79 }
88 80
89 81 if (d.devi_parent) {
90 82 construct_path((uintptr_t)d.devi_parent, result);
91 83 mdb_readstr(devi_node, sizeof (devi_node),
92 84 (uintptr_t)d.devi_node_name);
93 85 mdb_readstr(devi_addr, sizeof (devi_addr),
94 86 (uintptr_t)d.devi_addr);
95 87 mdb_snprintf(result+strlen(result),
96 88 PATH_MAX-strlen(result),
97 89 "/%s%s%s", devi_node, (*devi_addr ? "@" : ""),
98 90 devi_addr);
99 91 }
100 92 return (DCMD_OK);
101 93 }
102 94
103 95 /* ARGSUSED */
104 96 int
105 97 mdi_info_cb(uintptr_t addr, const void *data, void *cbdata)
106 98 {
107 99 struct mdi_pathinfo pi;
108 100 struct mdi_client c;
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
109 101 char dev_path[PATH_MAX];
110 102 char string[PATH_MAX];
111 103 int mdi_target = 0, mdi_lun = 0;
112 104 int target = *(int *)cbdata;
113 105
114 106 if (mdb_vread(&pi, sizeof (pi), addr) == -1) {
115 107 mdb_warn("couldn't read mdi_pathinfo");
116 108 return (DCMD_ERR);
117 109 }
118 110 mdb_readstr(string, sizeof (string), (uintptr_t)pi.pi_addr);
119 - mdi_target = atoi(string);
120 - mdi_lun = atoi(strchr(string, ',')+1);
111 + mdi_target = (int)mdb_strtoull(string);
112 + mdi_lun = (int)mdb_strtoull(strchr(string, ',') + 1);
121 113 if (target != mdi_target)
122 114 return (0);
123 115
124 116 if (mdb_vread(&c, sizeof (c), (uintptr_t)pi.pi_client) == -1) {
125 117 mdb_warn("couldn't read mdi_client");
126 118 return (-1);
127 119 }
128 120
129 121 *dev_path = NULL;
130 122 if (construct_path((uintptr_t)c.ct_dip, dev_path) != DCMD_OK)
131 123 strcpy(dev_path, "unknown");
132 124
133 125 mdb_printf("LUN %d: %s\n", mdi_lun, dev_path);
134 126 mdb_printf(" dip: %p %s path", c.ct_dip,
135 127 (pi.pi_preferred ? "preferred" : ""));
136 128 switch (pi.pi_state & MDI_PATHINFO_STATE_MASK) {
137 129 case MDI_PATHINFO_STATE_INIT:
138 130 mdb_printf(" initializing");
139 131 break;
140 132 case MDI_PATHINFO_STATE_ONLINE:
141 133 mdb_printf(" online");
142 134 break;
143 135 case MDI_PATHINFO_STATE_STANDBY:
144 136 mdb_printf(" standby");
145 137 break;
146 138 case MDI_PATHINFO_STATE_FAULT:
147 139 mdb_printf(" fault");
148 140 break;
149 141 case MDI_PATHINFO_STATE_OFFLINE:
150 142 mdb_printf(" offline");
151 143 break;
152 144 default:
153 145 mdb_printf(" invalid state");
154 146 break;
155 147 }
156 148 mdb_printf("\n");
157 149 return (0);
158 150 }
159 151
160 152 void
161 153 mdi_info(struct mptsas m, int target)
162 154 {
163 155 struct dev_info d;
164 156 struct mdi_phci p;
165 157
166 158 if (mdb_vread(&d, sizeof (d), (uintptr_t)m.m_dip) == -1) {
167 159 mdb_warn("couldn't read m_dip");
168 160 return;
169 161 }
170 162
171 163 if (MDI_PHCI(&d)) {
172 164 if (mdb_vread(&p, sizeof (p), (uintptr_t)d.devi_mdi_xhci)
173 165 == -1) {
174 166 mdb_warn("couldn't read m_dip.devi_mdi_xhci");
175 167 return;
176 168 }
177 169 if (p.ph_path_head)
178 170 mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mdi_info_cb,
179 171 &target, (uintptr_t)p.ph_path_head);
180 172 return;
181 173 }
182 174 }
183 175
184 176 void
185 177 print_cdb(mptsas_cmd_t *m)
186 178 {
187 179 struct scsi_pkt pkt;
188 180 uchar_t cdb[512]; /* an arbitrarily large number */
189 181 int j;
190 182
191 183 if (mdb_vread(&pkt, sizeof (pkt), (uintptr_t)m->cmd_pkt) == -1) {
192 184 mdb_warn("couldn't read cmd_pkt");
193 185 return;
194 186 }
195 187
196 188 /*
197 189 * We use cmd_cdblen here because 5.10 doesn't
198 190 * have the cdb length in the pkt
199 191 */
200 192 if (mdb_vread(&cdb, m->cmd_cdblen, (uintptr_t)pkt.pkt_cdbp) == -1) {
201 193 mdb_warn("couldn't read pkt_cdbp");
202 194 return;
203 195 }
204 196
205 197 mdb_printf("%3d,%-3d [ ",
|
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
206 198 pkt.pkt_address.a_target, pkt.pkt_address.a_lun);
207 199
208 200 for (j = 0; j < m->cmd_cdblen; j++)
209 201 mdb_printf("%02x ", cdb[j]);
210 202
211 203 mdb_printf("]\n");
212 204 }
213 205
214 206
215 207 void
216 -display_ports(struct mptsas m)
208 +display_ports(struct mptsas *mp)
217 209 {
218 210 int i;
219 211 mdb_printf("\n");
220 212 mdb_printf("phy number and port mapping table\n");
221 213 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
222 - if (m.m_phy_info[i].attached_devhdl) {
214 + if (mp->m_phy_info[i].attached_devhdl) {
223 215 mdb_printf("phy %x --> port %x, phymask %x,"
224 - "attached_devhdl %x\n", i, m.m_phy_info[i].port_num,
225 - m.m_phy_info[i].phy_mask,
226 - m.m_phy_info[i].attached_devhdl);
216 + "attached_devhdl %x\n", i, mp->m_phy_info[i].port_num,
217 + mp->m_phy_info[i].phy_mask,
218 + mp->m_phy_info[i].attached_devhdl);
227 219 }
228 220 }
229 221 mdb_printf("\n");
230 222 }
223 +
224 +static uintptr_t
225 +klist_head(list_t *lp, uintptr_t klp)
226 +{
227 + if ((uintptr_t)lp->list_head.list_next ==
228 + klp + offsetof(struct list, list_head))
229 + return (NULL);
230 +
231 + return ((uintptr_t)(((char *)lp->list_head.list_next) -
232 + lp->list_offset));
233 +}
234 +
235 +static uintptr_t
236 +klist_next(list_t *lp, uintptr_t klp, void *op)
237 +{
238 + /* LINTED E_BAD_PTR_CAST_ALIG */
239 + struct list_node *np = (struct list_node *)(((char *)op) +
240 + lp->list_offset);
241 +
242 + if ((uintptr_t)np->list_next == klp + offsetof(struct list, list_head))
243 + return (NULL);
244 +
245 + return (((uintptr_t)(np->list_next)) - lp->list_offset);
246 +}
247 +
231 248 static void *
232 -hash_traverse(mptsas_hash_table_t *hashtab, int pos, int alloc_size)
249 +krefhash_first(uintptr_t khp)
233 250 {
234 - mptsas_hash_node_t *this = NULL;
235 - mptsas_hash_node_t h;
236 - void *ret = NULL;
251 + refhash_t mh;
252 + uintptr_t klp;
253 + uintptr_t kop;
254 + void *rp;
237 255
238 - if (pos == MPTSAS_HASH_FIRST) {
239 - hashtab->line = 0;
240 - hashtab->cur = NULL;
241 - this = hashtab->head[0];
242 - } else {
243 - if (hashtab->cur == NULL) {
244 - return (NULL);
245 - } else {
246 - mdb_vread(&h, sizeof (h), (uintptr_t)hashtab->cur);
247 - this = h.next;
248 - }
249 - }
256 + mdb_vread(&mh, sizeof (mh), khp);
257 + klp = klist_head(&mh.rh_objs, khp + offsetof(refhash_t, rh_objs));
258 + if (klp == 0)
259 + return (NULL);
250 260
251 - while (this == NULL) {
252 - hashtab->line++;
253 - if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
254 - /* the traverse reaches the end */
255 - hashtab->cur = NULL;
256 - return (NULL);
257 - } else {
258 - this = hashtab->head[hashtab->line];
259 - }
261 + kop = klp - mh.rh_link_off;
262 + rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
263 + mdb_vread(rp, mh.rh_obj_size, kop);
264 +
265 + return (rp);
266 +}
267 +
268 +static void *
269 +krefhash_next(uintptr_t khp, void *op)
270 +{
271 + refhash_t mh;
272 + void *prev = op;
273 + refhash_link_t *lp;
274 + uintptr_t klp;
275 + uintptr_t kop;
276 + refhash_link_t ml;
277 + void *rp;
278 +
279 + mdb_vread(&mh, sizeof (mh), khp);
280 + /* LINTED E_BAD_PTR_CAST_ALIG */
281 + lp = (refhash_link_t *)(((char *)(op)) + mh.rh_link_off);
282 + ml = *lp;
283 + while ((klp = klist_next(&mh.rh_objs,
284 + khp + offsetof(refhash_t, rh_objs), &ml)) != NULL) {
285 + mdb_vread(&ml, sizeof (ml), klp);
286 + if (!(ml.rhl_flags & RHL_F_DEAD))
287 + break;
260 288 }
261 - hashtab->cur = this;
262 289
263 - if (mdb_vread(&h, sizeof (h), (uintptr_t)this) == -1) {
264 - mdb_warn("couldn't read hashtab");
290 + if (klp == 0) {
291 + mdb_free(prev, mh.rh_obj_size);
265 292 return (NULL);
266 293 }
267 - ret = mdb_alloc(alloc_size, UM_SLEEP);
268 - if (mdb_vread(ret, alloc_size, (uintptr_t)h.data) == -1) {
269 - mdb_warn("couldn't read hashdata");
270 - return (NULL);
271 - }
272 - return (ret);
294 +
295 + kop = klp - mh.rh_link_off;
296 + rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
297 + mdb_vread(rp, mh.rh_obj_size, kop);
298 +
299 + mdb_free(prev, mh.rh_obj_size);
300 + return (rp);
273 301 }
302 +
274 303 void
275 -display_targets(struct mptsas_slots *s)
304 +display_targets(struct mptsas *mp)
276 305 {
277 306 mptsas_target_t *ptgt;
278 307 mptsas_smp_t *psmp;
279 308
280 309 mdb_printf("\n");
281 310 mdb_printf("The SCSI target information\n");
282 - ptgt = (mptsas_target_t *)hash_traverse(&s->m_tgttbl,
283 - MPTSAS_HASH_FIRST, sizeof (mptsas_target_t));
284 - while (ptgt != NULL) {
311 + for (ptgt = (mptsas_target_t *)krefhash_first((uintptr_t)mp->m_targets);
312 + ptgt != NULL;
313 + ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt)) {
285 314 mdb_printf("\n");
286 315 mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x,"
287 - "devinfo %x\n", ptgt->m_devhdl, ptgt->m_sas_wwn,
288 - ptgt->m_phymask, ptgt->m_deviceinfo);
289 - mdb_printf("throttle %x, dr_flag %x, m_t_ncmds %x\n",
290 - ptgt->m_t_throttle, ptgt->m_dr_flag, ptgt->m_t_ncmds);
291 -
292 - mdb_free(ptgt, sizeof (mptsas_target_t));
293 - ptgt = (mptsas_target_t *)hash_traverse(
294 - &s->m_tgttbl, MPTSAS_HASH_NEXT, sizeof (mptsas_target_t));
316 + "devinfo %x\n", ptgt->m_devhdl, ptgt->m_addr.mta_wwn,
317 + ptgt->m_addr.mta_phymask, ptgt->m_deviceinfo);
318 + mdb_printf("throttle %x, dr_flag %x, m_t_ncmds %x, "
319 + "enclosure %x, slot_num %x\n", ptgt->m_t_throttle,
320 + ptgt->m_dr_flag, ptgt->m_t_ncmds, ptgt->m_enclosure,
321 + ptgt->m_slot_num);
295 322 }
323 +
296 324 mdb_printf("\n");
297 325 mdb_printf("The smp child information\n");
298 - psmp = (mptsas_smp_t *)hash_traverse(&s->m_smptbl,
299 - MPTSAS_HASH_FIRST, sizeof (mptsas_smp_t));
300 - while (psmp != NULL) {
326 + for (psmp = (mptsas_smp_t *)krefhash_first(
327 + (uintptr_t)mp->m_smp_targets);
328 + psmp != NULL;
329 + psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp)) {
301 330 mdb_printf("\n");
302 331 mdb_printf("devhdl %x, sasaddress %"PRIx64", phymask %x \n",
303 - psmp->m_devhdl, psmp->m_sasaddr, psmp->m_phymask);
304 -
305 - mdb_free(psmp, sizeof (mptsas_smp_t));
306 - psmp = (mptsas_smp_t *)hash_traverse(
307 - &s->m_smptbl, MPTSAS_HASH_NEXT, sizeof (mptsas_smp_t));
332 + psmp->m_devhdl, psmp->m_addr.mta_wwn,
333 + psmp->m_addr.mta_phymask);
308 334 }
309 335 mdb_printf("\n");
310 336 #if 0
311 337 mdb_printf("targ wwn ncmds throttle "
312 338 "dr_flag timeout dups\n");
313 339 mdb_printf("-------------------------------"
314 340 "--------------------------------\n");
315 341 for (i = 0; i < MPTSAS_MAX_TARGETS; i++) {
316 - if (s->m_target[i].m_sas_wwn || s->m_target[i].m_deviceinfo) {
342 + if (s->m_target[i].m_addr.mta_wwn ||
343 + s->m_target[i].m_deviceinfo) {
317 344 mdb_printf("%4d ", i);
318 - if (s->m_target[i].m_sas_wwn)
345 + if (s->m_target[i].m_addr.mta_wwn)
319 346 mdb_printf("%"PRIx64" ",
320 - s->m_target[i].m_sas_wwn);
347 + s->m_target[i].m_addr.mta_wwn);
321 348 mdb_printf("%3d", s->m_target[i].m_t_ncmds);
322 349 switch (s->m_target[i].m_t_throttle) {
323 350 case QFULL_THROTTLE:
324 351 mdb_printf(" QFULL ");
325 352 break;
326 353 case DRAIN_THROTTLE:
327 354 mdb_printf(" DRAIN ");
328 355 break;
329 356 case HOLD_THROTTLE:
330 357 mdb_printf(" HOLD ");
331 358 break;
332 359 case MAX_THROTTLE:
333 360 mdb_printf(" MAX ");
334 361 break;
335 362 case CHOKE_THROTTLE:
336 363 mdb_printf(" CHOKE ");
337 364 break;
338 365 default:
339 366 mdb_printf("%8d ",
340 367 s->m_target[i].m_t_throttle);
341 368 }
342 369 switch (s->m_target[i].m_dr_flag) {
343 370 case MPTSAS_DR_INACTIVE:
344 371 mdb_printf(" INACTIVE ");
345 372 break;
346 373 case MPTSAS_DR_PRE_OFFLINE_TIMEOUT:
347 374 mdb_printf(" TIMEOUT ");
348 375 break;
349 376 case MPTSAS_DR_PRE_OFFLINE_TIMEOUT_NO_CANCEL:
350 377 mdb_printf("TIMEOUT_NC ");
351 378 break;
352 379 case MPTSAS_DR_OFFLINE_IN_PROGRESS:
353 380 mdb_printf(" OFFLINING ");
354 381 break;
355 382 case MPTSAS_DR_ONLINE_IN_PROGRESS:
356 383 mdb_printf(" ONLINING ");
357 384 break;
358 385 default:
359 386 mdb_printf(" UNKNOWN ");
360 387 break;
361 388 }
362 389 mdb_printf("%3d/%-3d %d/%d\n",
363 390 s->m_target[i].m_dr_timeout, m.m_offline_delay,
364 391 s->m_target[i].m_dr_online_dups,
365 392 s->m_target[i].m_dr_offline_dups);
366 393
367 394 if (verbose) {
368 395 mdb_inc_indent(5);
369 396 if ((s->m_target[i].m_deviceinfo &
370 397 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
371 398 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
372 399 mdb_printf("Fanout expander: ");
373 400 if ((s->m_target[i].m_deviceinfo &
374 401 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
375 402 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
376 403 mdb_printf("Edge expander: ");
377 404 if ((s->m_target[i].m_deviceinfo &
378 405 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
379 406 MPI2_SAS_DEVICE_INFO_END_DEVICE)
380 407 mdb_printf("End device: ");
381 408 if ((s->m_target[i].m_deviceinfo &
382 409 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
383 410 MPI2_SAS_DEVICE_INFO_NO_DEVICE)
384 411 mdb_printf("No device ");
385 412
386 413 for (loop = 0, comma = 0;
387 414 loop < (sizeof (devinfo_array) /
388 415 sizeof (devinfo_array[0])); loop++) {
389 416 if (s->m_target[i].m_deviceinfo &
390 417 devinfo_array[loop].value) {
391 418 mdb_printf("%s%s",
392 419 (comma ? ", " : ""),
393 420 devinfo_array[loop].text);
394 421 comma++;
395 422 }
396 423 }
397 424 mdb_printf("\n");
398 425
399 426 if (s->m_target[i].m_tgt_dip) {
400 427 *target_path = 0;
401 428 if (construct_path((uintptr_t)
402 429 s->m_target[i].m_tgt_dip,
403 430 target_path)
404 431 == DCMD_OK)
405 432 mdb_printf("%s\n", target_path);
406 433 }
407 434 mdi_info(m, i);
408 435 mdb_dec_indent(5);
409 436 }
410 437 }
411 438 }
412 439 #endif
413 440 }
414 441
415 442 int
416 443 display_slotinfo()
417 444 {
418 445 #if 0
419 446 int i, nslots;
|
↓ open down ↓ |
89 lines elided |
↑ open up ↑ |
420 447 struct mptsas_cmd c, *q, *slots;
421 448 int header_output = 0;
422 449 int rv = DCMD_OK;
423 450 int slots_in_use = 0;
424 451 int tcmds = 0;
425 452 int mismatch = 0;
426 453 int wq, dq;
427 454 int ncmds = 0;
428 455 ulong_t saved_indent;
429 456
430 - nslots = s->m_n_slots;
457 + nslots = s->m_n_normal;
431 458
432 459 slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
433 460
434 461 for (i = 0; i < nslots; i++)
435 462 if (s->m_slot[i]) {
436 463 slots_in_use++;
437 464 if (mdb_vread(&slots[i], sizeof (mptsas_cmd_t),
438 465 (uintptr_t)s->m_slot[i]) == -1) {
439 466 mdb_warn("couldn't read slot");
440 467 s->m_slot[i] = NULL;
441 468 }
442 469 if ((slots[i].cmd_flags & CFLAG_CMDIOC) == 0)
443 470 tcmds++;
444 471 if (i != slots[i].cmd_slot)
445 472 mismatch++;
446 473 }
447 474
448 475 for (q = m.m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
449 476 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
450 477 mdb_warn("couldn't follow m_waitq");
451 478 rv = DCMD_ERR;
452 479 goto exit;
453 480 }
454 481
455 482 for (q = m.m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
456 483 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
457 484 mdb_warn("couldn't follow m_doneq");
458 485 rv = DCMD_ERR;
459 486 goto exit;
460 487 }
461 488
462 489 for (i = 0; i < MPTSAS_MAX_TARGETS; i++)
463 490 ncmds += s->m_target[i].m_t_ncmds;
464 491
465 492 mdb_printf("\n");
466 493 mdb_printf(" mpt. slot mptsas_slots slot");
467 494 mdb_printf("\n");
468 495 mdb_printf("m_ncmds total"
469 496 " targ throttle m_t_ncmds targ_tot wq dq");
470 497 mdb_printf("\n");
471 498 mdb_printf("----------------------------------------------------");
472 499 mdb_printf("\n");
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
473 500
474 501 mdb_printf("%7d ", m.m_ncmds);
475 502 mdb_printf("%s", (m.m_ncmds == slots_in_use ? " " : "!="));
476 503 mdb_printf("%3d total %3d ", slots_in_use, ncmds);
477 504 mdb_printf("%s", (tcmds == ncmds ? " " : " !="));
478 505 mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
479 506
480 507 saved_indent = mdb_dec_indent(0);
481 508 mdb_dec_indent(saved_indent);
482 509
483 - for (i = 0; i < s->m_n_slots; i++)
510 + for (i = 0; i < s->m_n_normal; i++)
484 511 if (s->m_slot[i]) {
485 512 if (!header_output) {
486 513 mdb_printf("\n");
487 514 mdb_printf("mptsas_cmd slot cmd_slot "
488 515 "cmd_flags cmd_pkt_flags scsi_pkt "
489 516 " targ,lun [ pkt_cdbp ...\n");
490 517 mdb_printf("-------------------------------"
491 518 "--------------------------------------"
492 519 "--------------------------------------"
493 520 "------\n");
494 521 header_output = 1;
495 522 }
496 523 mdb_printf("%16p %4d %s %4d %8x %8x %16p ",
497 524 s->m_slot[i], i,
498 525 (i == slots[i].cmd_slot?" ":"BAD"),
499 526 slots[i].cmd_slot,
500 527 slots[i].cmd_flags,
501 528 slots[i].cmd_pkt_flags,
502 529 slots[i].cmd_pkt);
503 530 (void) print_cdb(&slots[i]);
504 531 }
505 532
506 533 /* print the wait queue */
507 534
508 535 for (q = m.m_waitq; q; q = c.cmd_linkp) {
509 536 if (q == m.m_waitq)
510 537 mdb_printf("\n");
511 538 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
512 539 == -1) {
513 540 mdb_warn("couldn't follow m_waitq");
514 541 rv = DCMD_ERR;
515 542 goto exit;
516 543 }
517 544 mdb_printf("%16p wait n/a %4d %8x %8x %16p ",
518 545 q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
519 546 c.cmd_pkt);
520 547 print_cdb(&c);
521 548 }
522 549
523 550 /* print the done queue */
524 551
525 552 for (q = m.m_doneq; q; q = c.cmd_linkp) {
526 553 if (q == m.m_doneq)
527 554 mdb_printf("\n");
528 555 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
529 556 == -1) {
530 557 mdb_warn("couldn't follow m_doneq");
531 558 rv = DCMD_ERR;
532 559 goto exit;
533 560 }
534 561 mdb_printf("%16p done n/a %4d %8x %8x %16p ",
535 562 q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
536 563 c.cmd_pkt);
537 564 print_cdb(&c);
538 565 }
539 566
540 567 mdb_inc_indent(saved_indent);
541 568
542 569 if (m.m_ncmds != slots_in_use)
543 570 mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
544 571 "slots in use\n");
545 572
546 573 if (tcmds != ncmds)
547 574 mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
548 575 "not match the slots in use\n");
549 576
550 577 if (mismatch)
551 578 mdb_printf("WARNING: corruption in slot table, "
552 579 "m_slot[].cmd_slot incorrect\n");
553 580
554 581 /* now check for corruptions */
555 582
556 583 for (q = m.m_waitq; q; q = c.cmd_linkp) {
557 584 for (i = 0; i < nslots; i++)
558 585 if (s->m_slot[i] == q)
559 586 mdb_printf("WARNING: m_waitq entry"
560 587 "(mptsas_cmd_t) %p is in m_slot[%i]\n",
561 588 q, i);
562 589
563 590 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
564 591 mdb_warn("couldn't follow m_waitq");
565 592 rv = DCMD_ERR;
566 593 goto exit;
567 594 }
568 595 }
569 596
570 597 for (q = m.m_doneq; q; q = c.cmd_linkp) {
571 598 for (i = 0; i < nslots; i++)
572 599 if (s->m_slot[i] == q)
573 600 mdb_printf("WARNING: m_doneq entry "
574 601 "(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
575 602
576 603 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
577 604 mdb_warn("couldn't follow m_doneq");
578 605 rv = DCMD_ERR;
579 606 goto exit;
580 607 }
581 608 if ((c.cmd_flags & CFLAG_FINISHED) == 0)
582 609 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
583 610 "should have CFLAG_FINISHED set\n", q);
584 611 if (c.cmd_flags & CFLAG_IN_TRANSPORT)
585 612 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
586 613 "should not have CFLAG_IN_TRANSPORT set\n", q);
587 614 if (c.cmd_flags & CFLAG_CMDARQ)
588 615 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
589 616 "should not have CFLAG_CMDARQ set\n", q);
590 617 if (c.cmd_flags & CFLAG_COMPLETED)
591 618 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
592 619 "should not have CFLAG_COMPLETED set\n", q);
593 620 }
594 621
|
↓ open down ↓ |
101 lines elided |
↑ open up ↑ |
595 622 exit:
596 623 mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
597 624 return (rv);
598 625 #endif
599 626 mdb_printf("\n");
600 627 mdb_printf("The slot information is not implemented yet\n");
601 628 return (0);
602 629 }
603 630
604 631 void
605 -display_deviceinfo(struct mptsas m)
632 +display_deviceinfo(struct mptsas *mp)
606 633 {
607 634 char device_path[PATH_MAX];
608 635
609 636 *device_path = 0;
610 - if (construct_path((uintptr_t)m.m_dip, device_path) != DCMD_OK) {
637 + if (construct_path((uintptr_t)mp->m_dip, device_path) != DCMD_OK) {
611 638 strcpy(device_path, "couldn't determine device path");
612 639 }
613 640
614 641 mdb_printf("\n");
615 642 mdb_printf("Path in device tree %s\n", device_path);
616 643 #if 0
617 644 mdb_printf("base_wwid phys "
618 645 "mptid prodid devid revid ssid\n");
619 646 mdb_printf("-----------------------------"
620 647 "----------------------------------\n");
621 648 mdb_printf("%"PRIx64" %2d %3d "
622 649 "0x%04x 0x%04x ", m.un.m_base_wwid, m.m_num_phys, m.m_mptid,
623 650 m.m_productid, m.m_devid);
624 651 switch (m.m_devid) {
625 652 case MPTSAS_909:
626 653 mdb_printf("(909) ");
627 654 break;
628 655 case MPTSAS_929:
629 656 mdb_printf("(929) ");
630 657 break;
631 658 case MPTSAS_919:
632 659 mdb_printf("(919) ");
633 660 break;
634 661 case MPTSAS_1030:
635 662 mdb_printf("(1030) ");
636 663 break;
637 664 case MPTSAS_1064:
638 665 mdb_printf("(1064) ");
639 666 break;
640 667 case MPTSAS_1068:
641 668 mdb_printf("(1068) ");
642 669 break;
643 670 case MPTSAS_1064E:
644 671 mdb_printf("(1064E) ");
645 672 break;
646 673 case MPTSAS_1068E:
647 674 mdb_printf("(1068E) ");
648 675 break;
649 676 default:
650 677 mdb_printf("(?????) ");
651 678 break;
652 679 }
653 680 mdb_printf("0x%02x 0x%04x\n", m.m_revid, m.m_ssid);
654 681 mdb_printf("%s\n", device_path);
655 682
656 683 for (i = 0; i < MAX_MPI2_PORTS; i++) {
657 684 if (i%4 == 0)
658 685 mdb_printf("\n");
659 686
660 687 mdb_printf("%d:", i);
661 688
662 689 switch (m.m_port_type[i]) {
663 690 case MPI2_PORTFACTS_PORTTYPE_INACTIVE:
664 691 mdb_printf("inactive ",
665 692 m.m_protocol_flags[i]);
666 693 break;
667 694 case MPI2_PORTFACTS_PORTTYPE_SCSI:
668 695 mdb_printf("SCSI (0x%1x) ",
669 696 m.m_protocol_flags[i]);
670 697 break;
671 698 case MPI2_PORTFACTS_PORTTYPE_FC:
672 699 mdb_printf("FC (0x%1x) ",
673 700 m.m_protocol_flags[i]);
674 701 break;
675 702 case MPI2_PORTFACTS_PORTTYPE_ISCSI:
676 703 mdb_printf("iSCSI (0x%1x) ",
677 704 m.m_protocol_flags[i]);
678 705 break;
679 706 case MPI2_PORTFACTS_PORTTYPE_SAS:
680 707 mdb_printf("SAS (0x%1x) ",
681 708 m.m_protocol_flags[i]);
682 709 break;
683 710 default:
684 711 mdb_printf("unknown ");
|
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
685 712 }
686 713 }
687 714 #endif
688 715 mdb_printf("\n");
689 716 }
690 717
691 718 static int
692 719 mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
693 720 {
694 721 struct mptsas m;
695 - struct mptsas_slots *s;
722 + struct mptsas_slots *s;
696 723
697 724 int nslots;
698 725 int slot_size = 0;
699 726 uint_t verbose = FALSE;
700 727 uint_t target_info = FALSE;
701 728 uint_t slot_info = FALSE;
702 729 uint_t device_info = FALSE;
703 730 uint_t port_info = FALSE;
704 731 int rv = DCMD_OK;
705 732 void *mptsas_state;
706 733
707 734 if (!(flags & DCMD_ADDRSPEC)) {
708 735 mptsas_state = NULL;
709 736 if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
710 737 mdb_warn("can't read mptsas_state");
711 738 return (DCMD_ERR);
712 739 }
713 740 if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc,
714 741 argv, (uintptr_t)mptsas_state) == -1) {
715 742 mdb_warn("mdb_pwalk_dcmd failed");
716 743 return (DCMD_ERR);
717 744 }
718 745 return (DCMD_OK);
719 746 }
720 747
721 748 if (mdb_getopts(argc, argv,
722 749 's', MDB_OPT_SETBITS, TRUE, &slot_info,
723 750 'd', MDB_OPT_SETBITS, TRUE, &device_info,
724 751 't', MDB_OPT_SETBITS, TRUE, &target_info,
725 752 'p', MDB_OPT_SETBITS, TRUE, &port_info,
726 753 'v', MDB_OPT_SETBITS, TRUE, &verbose,
727 754 NULL) != argc)
728 755 return (DCMD_USAGE);
729 756
730 757
731 758 if (mdb_vread(&m, sizeof (m), addr) == -1) {
732 759 mdb_warn("couldn't read mpt struct at 0x%p", addr);
733 760 return (DCMD_ERR);
734 761 }
735 762
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
736 763 s = mdb_alloc(sizeof (mptsas_slots_t), UM_SLEEP);
737 764
738 765 if (mdb_vread(s, sizeof (mptsas_slots_t),
739 766 (uintptr_t)m.m_active) == -1) {
740 767 mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
741 768 m.m_active);
742 769 mdb_free(s, sizeof (mptsas_slots_t));
743 770 return (DCMD_ERR);
744 771 }
745 772
746 - nslots = s->m_n_slots;
773 + nslots = s->m_n_normal;
747 774
748 775 mdb_free(s, sizeof (mptsas_slots_t));
749 776
750 777 slot_size = sizeof (mptsas_slots_t) +
751 778 (sizeof (mptsas_cmd_t *) * (nslots-1));
752 779
753 780 s = mdb_alloc(slot_size, UM_SLEEP);
754 781
755 782 if (mdb_vread(s, slot_size, (uintptr_t)m.m_active) == -1) {
756 783 mdb_warn("couldn't read large mptsas_slots_t at 0x%p",
757 784 m.m_active);
758 785 mdb_free(s, slot_size);
759 786 return (DCMD_ERR);
760 787 }
761 788
762 789 /* processing completed */
763 790
764 791 if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) ||
765 792 (flags & DCMD_LOOPFIRST) || slot_info || device_info ||
766 793 target_info) {
767 794 if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST))
768 795 mdb_printf("\n");
769 796 mdb_printf(" mptsas_t inst ncmds suspend power");
770 797 mdb_printf("\n");
771 798 mdb_printf("========================================="
772 799 "=======================================");
773 800 mdb_printf("\n");
774 801 }
775 802
776 803 mdb_printf("%16p %4d %5d ", addr, m.m_instance, m.m_ncmds);
777 804 mdb_printf("%7d", m.m_suspended);
778 805 switch (m.m_power_level) {
779 806 case PM_LEVEL_D0:
780 807 mdb_printf(" ON=D0 ");
781 808 break;
782 809 case PM_LEVEL_D1:
783 810 mdb_printf(" D1 ");
784 811 break;
785 812 case PM_LEVEL_D2:
786 813 mdb_printf(" D2 ");
787 814 break;
788 815 case PM_LEVEL_D3:
|
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
789 816 mdb_printf("OFF=D3 ");
790 817 break;
791 818 default:
792 819 mdb_printf("INVALD ");
793 820 }
794 821 mdb_printf("\n");
795 822
796 823 mdb_inc_indent(17);
797 824
798 825 if (target_info)
799 - display_targets(s);
826 + display_targets(&m);
800 827
801 828 if (port_info)
802 - display_ports(m);
829 + display_ports(&m);
803 830
804 831 if (device_info)
805 - display_deviceinfo(m);
832 + display_deviceinfo(&m);
806 833
807 834 if (slot_info)
808 835 display_slotinfo();
809 836
810 837 mdb_dec_indent(17);
811 838
812 839 mdb_free(s, slot_size);
813 840
814 841 return (rv);
815 842 }
816 -/*
817 - * Only -t is implemented now, will add more later when the driver is stable
818 - */
843 +
819 844 void
820 845 mptsas_help()
821 846 {
822 847 mdb_printf("Prints summary information about each mpt_sas instance, "
823 848 "including warning\nmessages when slot usage doesn't match "
824 849 "summary information.\n"
825 850 "Without the address of a \"struct mptsas\", prints every "
826 851 "instance.\n\n"
827 852 "Switches:\n"
828 853 " -t includes information about targets\n"
829 854 " -p includes information about port\n"
830 855 " -d includes information about the hardware\n");
831 856 }
832 857
833 858 static const mdb_dcmd_t dcmds[] = {
834 859 { "mptsas", "?[-tpd]", "print mpt_sas information", mptsas_dcmd,
835 860 mptsas_help}, { NULL }
836 861 };
837 862
838 863 static const mdb_modinfo_t modinfo = {
839 864 MDB_API_VERSION, dcmds, NULL
840 865 };
841 866
842 867 const mdb_modinfo_t *
843 868 _mdb_init(void)
844 869 {
845 870 return (&modinfo);
846 871 }
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX