Print this page
NEX-17006 backport mpt_sas tri-mode parts support change
9044 Need support for mpt_sas tri-mode parts
9045 Clean up mpt_sas compiler warnings
9046 mptsas_handle_topo_change can return without its locks held
9047 workaround SAS3408 firmware issue
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Albert Lee <trisk@forkgnu.org>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Approved by: Richard Lowe <richlowe@richlowe.net>
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>
backout 4500 mptsas_hash_traverse() is unsafe, leads to missing devices
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
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
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 26 /*
27 - * Copyright 2014 Joyent, Inc. All rights reserved.
27 + * Copyright (c) 2017 Joyent, Inc.
28 28 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
29 29 */
30 30
31 31 #include <limits.h>
32 32 #include <sys/mdb_modapi.h>
33 33 #include <sys/sysinfo.h>
34 34 #include <sys/sunmdi.h>
35 35 #include <sys/list.h>
36 36 #include <sys/scsi/scsi.h>
37 37
38 38 #pragma pack(1)
39 39 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
40 40 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
41 41 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
42 42 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
43 43 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
44 44 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
45 45 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
46 46 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
47 47 #pragma pack()
48 48
49 49 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
50 50 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
51 51
52 52 struct {
53 53 int value;
54 54 char *text;
55 55 } devinfo_array[] = {
56 56 { MPI2_SAS_DEVICE_INFO_SEP, "SEP" },
57 57 { MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE, "ATAPI device" },
58 58 { MPI2_SAS_DEVICE_INFO_LSI_DEVICE, "LSI device" },
59 59 { MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH, "direct attach" },
60 60 { MPI2_SAS_DEVICE_INFO_SSP_TARGET, "SSP tgt" },
61 61 { MPI2_SAS_DEVICE_INFO_STP_TARGET, "STP tgt" },
62 62 { MPI2_SAS_DEVICE_INFO_SMP_TARGET, "SMP tgt" },
63 63 { MPI2_SAS_DEVICE_INFO_SATA_DEVICE, "SATA dev" },
64 64 { MPI2_SAS_DEVICE_INFO_SSP_INITIATOR, "SSP init" },
65 65 { MPI2_SAS_DEVICE_INFO_STP_INITIATOR, "STP init" },
66 66 { MPI2_SAS_DEVICE_INFO_SMP_INITIATOR, "SMP init" },
67 67 { MPI2_SAS_DEVICE_INFO_SATA_HOST, "SATA host" }
68 68 };
69 69
70 70 int
71 71 construct_path(uintptr_t addr, char *result)
72 72 {
73 73 struct dev_info d;
74 74 char devi_node[PATH_MAX];
75 75 char devi_addr[PATH_MAX];
76 76
77 77 if (mdb_vread(&d, sizeof (d), addr) == -1) {
78 78 mdb_warn("couldn't read dev_info");
79 79 return (DCMD_ERR);
80 80 }
81 81
82 82 if (d.devi_parent) {
83 83 construct_path((uintptr_t)d.devi_parent, result);
84 84 mdb_readstr(devi_node, sizeof (devi_node),
85 85 (uintptr_t)d.devi_node_name);
86 86 mdb_readstr(devi_addr, sizeof (devi_addr),
87 87 (uintptr_t)d.devi_addr);
88 88 mdb_snprintf(result+strlen(result),
89 89 PATH_MAX-strlen(result),
90 90 "/%s%s%s", devi_node, (*devi_addr ? "@" : ""),
91 91 devi_addr);
92 92 }
93 93 return (DCMD_OK);
94 94 }
95 95
96 96 /* ARGSUSED */
97 97 int
98 98 mdi_info_cb(uintptr_t addr, const void *data, void *cbdata)
99 99 {
100 100 struct mdi_pathinfo pi;
101 101 struct mdi_client c;
102 102 char dev_path[PATH_MAX];
103 103 char string[PATH_MAX];
104 104 int mdi_target = 0, mdi_lun = 0;
105 105 int target = *(int *)cbdata;
106 106
107 107 if (mdb_vread(&pi, sizeof (pi), addr) == -1) {
108 108 mdb_warn("couldn't read mdi_pathinfo");
109 109 return (DCMD_ERR);
110 110 }
111 111 mdb_readstr(string, sizeof (string), (uintptr_t)pi.pi_addr);
112 112 mdi_target = (int)mdb_strtoull(string);
113 113 mdi_lun = (int)mdb_strtoull(strchr(string, ',') + 1);
114 114 if (target != mdi_target)
115 115 return (0);
116 116
117 117 if (mdb_vread(&c, sizeof (c), (uintptr_t)pi.pi_client) == -1) {
118 118 mdb_warn("couldn't read mdi_client");
119 119 return (-1);
120 120 }
121 121
122 122 *dev_path = NULL;
123 123 if (construct_path((uintptr_t)c.ct_dip, dev_path) != DCMD_OK)
124 124 strcpy(dev_path, "unknown");
125 125
126 126 mdb_printf("LUN %d: %s\n", mdi_lun, dev_path);
127 127 mdb_printf(" dip: %p %s path", c.ct_dip,
128 128 (pi.pi_preferred ? "preferred" : ""));
129 129 switch (pi.pi_state & MDI_PATHINFO_STATE_MASK) {
130 130 case MDI_PATHINFO_STATE_INIT:
131 131 mdb_printf(" initializing");
132 132 break;
133 133 case MDI_PATHINFO_STATE_ONLINE:
134 134 mdb_printf(" online");
135 135 break;
136 136 case MDI_PATHINFO_STATE_STANDBY:
137 137 mdb_printf(" standby");
138 138 break;
139 139 case MDI_PATHINFO_STATE_FAULT:
140 140 mdb_printf(" fault");
141 141 break;
142 142 case MDI_PATHINFO_STATE_OFFLINE:
143 143 mdb_printf(" offline");
144 144 break;
145 145 default:
146 146 mdb_printf(" invalid state");
147 147 break;
148 148 }
149 149 mdb_printf("\n");
150 150 return (0);
151 151 }
152 152
153 153 void
154 154 mdi_info(struct mptsas *mp, int target)
155 155 {
156 156 struct dev_info d;
157 157 struct mdi_phci p;
158 158
159 159 if (mdb_vread(&d, sizeof (d), (uintptr_t)mp->m_dip) == -1) {
160 160 mdb_warn("couldn't read m_dip");
161 161 return;
162 162 }
163 163
164 164 if (MDI_PHCI(&d)) {
165 165 if (mdb_vread(&p, sizeof (p), (uintptr_t)d.devi_mdi_xhci)
166 166 == -1) {
167 167 mdb_warn("couldn't read m_dip.devi_mdi_xhci");
168 168 return;
169 169 }
170 170 if (p.ph_path_head)
171 171 mdb_pwalk("mdipi_phci_list", (mdb_walk_cb_t)mdi_info_cb,
172 172 &target, (uintptr_t)p.ph_path_head);
173 173 return;
174 174 }
175 175 }
176 176
177 177 void
178 178 print_cdb(mptsas_cmd_t *m)
179 179 {
180 180 struct scsi_pkt pkt;
181 181 uchar_t cdb[512]; /* an arbitrarily large number */
182 182 int j;
183 183
184 184 if (mdb_vread(&pkt, sizeof (pkt), (uintptr_t)m->cmd_pkt) == -1) {
185 185 mdb_warn("couldn't read cmd_pkt");
186 186 return;
187 187 }
188 188
189 189 /*
190 190 * We use cmd_cdblen here because 5.10 doesn't
191 191 * have the cdb length in the pkt
192 192 */
193 193 if (mdb_vread(&cdb, m->cmd_cdblen, (uintptr_t)pkt.pkt_cdbp) == -1) {
194 194 mdb_warn("couldn't read pkt_cdbp");
195 195 return;
196 196 }
197 197
198 198 mdb_printf("%3d,%-3d [ ",
199 199 pkt.pkt_address.a_target, pkt.pkt_address.a_lun);
200 200
201 201 for (j = 0; j < m->cmd_cdblen; j++)
202 202 mdb_printf("%02x ", cdb[j]);
203 203
204 204 mdb_printf("]\n");
205 205 }
206 206
207 207
208 208 void
209 209 display_ports(struct mptsas *mp)
210 210 {
211 211 int i;
212 212 mdb_printf("\n");
213 213 mdb_printf("phy number and port mapping table\n");
214 214 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
215 215 if (mp->m_phy_info[i].attached_devhdl) {
216 216 mdb_printf("phy %x --> port %x, phymask %x,"
217 217 "attached_devhdl %x\n", i, mp->m_phy_info[i].port_num,
218 218 mp->m_phy_info[i].phy_mask,
219 219 mp->m_phy_info[i].attached_devhdl);
220 220 }
221 221 }
222 222 mdb_printf("\n");
223 223 }
224 224
225 225 static uintptr_t
226 226 klist_head(list_t *lp, uintptr_t klp)
227 227 {
228 228 if ((uintptr_t)lp->list_head.list_next ==
229 229 klp + offsetof(struct list, list_head))
230 230 return (NULL);
231 231
232 232 return ((uintptr_t)(((char *)lp->list_head.list_next) -
233 233 lp->list_offset));
234 234 }
235 235
236 236 static uintptr_t
237 237 klist_next(list_t *lp, uintptr_t klp, void *op)
238 238 {
239 239 /* LINTED E_BAD_PTR_CAST_ALIG */
240 240 struct list_node *np = (struct list_node *)(((char *)op) +
241 241 lp->list_offset);
242 242
243 243 if ((uintptr_t)np->list_next == klp + offsetof(struct list, list_head))
244 244 return (NULL);
245 245
246 246 return (((uintptr_t)(np->list_next)) - lp->list_offset);
247 247 }
248 248
249 249 static void *
250 250 krefhash_first(uintptr_t khp, uintptr_t *addr)
251 251 {
252 252 refhash_t mh;
253 253 uintptr_t klp;
254 254 uintptr_t kop;
255 255 void *rp;
256 256
257 257 mdb_vread(&mh, sizeof (mh), khp);
258 258 klp = klist_head(&mh.rh_objs, khp + offsetof(refhash_t, rh_objs));
259 259 if (klp == 0)
260 260 return (NULL);
261 261
262 262 kop = klp - mh.rh_link_off;
263 263 if (addr)
264 264 *addr = kop;
265 265 rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
266 266 mdb_vread(rp, mh.rh_obj_size, kop);
267 267
268 268 return (rp);
269 269 }
270 270
271 271 static void *
272 272 krefhash_next(uintptr_t khp, void *op, uintptr_t *addr)
273 273 {
274 274 refhash_t mh;
275 275 void *prev = op;
276 276 refhash_link_t *lp;
277 277 uintptr_t klp;
278 278 uintptr_t kop;
279 279 refhash_link_t ml;
280 280 void *rp;
281 281
282 282 mdb_vread(&mh, sizeof (mh), khp);
283 283 /* LINTED E_BAD_PTR_CAST_ALIG */
284 284 lp = (refhash_link_t *)(((char *)(op)) + mh.rh_link_off);
285 285 ml = *lp;
286 286 while ((klp = klist_next(&mh.rh_objs,
287 287 khp + offsetof(refhash_t, rh_objs), &ml)) != NULL) {
288 288 mdb_vread(&ml, sizeof (ml), klp);
289 289 if (!(ml.rhl_flags & RHL_F_DEAD))
290 290 break;
291 291 }
292 292
293 293 if (klp == 0) {
294 294 mdb_free(prev, mh.rh_obj_size);
295 295 return (NULL);
296 296 }
297 297
298 298 kop = klp - mh.rh_link_off;
299 299 if (addr)
300 300 *addr = kop;
301 301 rp = mdb_alloc(mh.rh_obj_size, UM_SLEEP);
302 302 mdb_vread(rp, mh.rh_obj_size, kop);
303 303
304 304 mdb_free(prev, mh.rh_obj_size);
305 305 return (rp);
306 306 }
307 307
308 308 void
309 309 display_targets(struct mptsas *mp, uint_t verbose)
310 310 {
311 311 mptsas_target_t *ptgt;
312 312 mptsas_smp_t *psmp;
313 313 int loop, comma;
314 314 uintptr_t p_addr;
315 315
316 316 mdb_printf("\n");
317 317 mdb_printf(" mptsas_target_t slot devhdl wwn ncmds throttle "
318 318 "dr_flag dups\n");
319 319 mdb_printf("---------------------------------------"
320 320 "-------------------------------\n");
321 321 for (ptgt = krefhash_first((uintptr_t)mp->m_targets, &p_addr);
322 322 ptgt != NULL;
323 323 ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt, &p_addr)) {
324 324 if (ptgt->m_addr.mta_wwn ||
325 325 ptgt->m_deviceinfo) {
326 326 mdb_printf("%16p ", p_addr);
327 327 mdb_printf("%4d ", ptgt->m_slot_num);
328 328 mdb_printf("%4d ", ptgt->m_devhdl);
329 329 if (ptgt->m_addr.mta_wwn)
330 330 mdb_printf("%"PRIx64" ",
331 331 ptgt->m_addr.mta_wwn);
332 332 mdb_printf("%3d", ptgt->m_t_ncmds);
333 333 switch (ptgt->m_t_throttle) {
334 334 case QFULL_THROTTLE:
335 335 mdb_printf(" QFULL ");
336 336 break;
337 337 case DRAIN_THROTTLE:
338 338 mdb_printf(" DRAIN ");
339 339 break;
340 340 case HOLD_THROTTLE:
341 341 mdb_printf(" HOLD ");
342 342 break;
343 343 case MAX_THROTTLE:
344 344 mdb_printf(" MAX ");
345 345 break;
346 346 default:
347 347 mdb_printf("%8d ",
348 348 ptgt->m_t_throttle);
349 349 }
350 350 switch (ptgt->m_dr_flag) {
351 351 case MPTSAS_DR_INACTIVE:
352 352 mdb_printf(" INACTIVE ");
353 353 break;
354 354 case MPTSAS_DR_INTRANSITION:
355 355 mdb_printf("TRANSITION ");
356 356 break;
357 357 default:
358 358 mdb_printf(" UNKNOWN ");
359 359 break;
360 360 }
361 361 mdb_printf("%d\n",
362 362 ptgt->m_dups);
363 363
364 364 if (verbose) {
365 365 mdb_inc_indent(5);
366 366 if ((ptgt->m_deviceinfo &
367 367 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
368 368 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
369 369 mdb_printf("Fanout expander: ");
370 370 if ((ptgt->m_deviceinfo &
371 371 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
372 372 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
373 373 mdb_printf("Edge expander: ");
374 374 if ((ptgt->m_deviceinfo &
375 375 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
376 376 MPI2_SAS_DEVICE_INFO_END_DEVICE)
377 377 mdb_printf("End device: ");
378 378 if ((ptgt->m_deviceinfo &
379 379 MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
380 380 MPI2_SAS_DEVICE_INFO_NO_DEVICE)
381 381 mdb_printf("No device ");
382 382
383 383 for (loop = 0, comma = 0;
384 384 loop < (sizeof (devinfo_array) /
385 385 sizeof (devinfo_array[0])); loop++) {
386 386 if (ptgt->m_deviceinfo &
387 387 devinfo_array[loop].value) {
388 388 mdb_printf("%s%s",
389 389 (comma ? ", " : ""),
390 390 devinfo_array[loop].text);
391 391 comma++;
392 392 }
393 393 }
394 394 mdb_printf("\n");
395 395 mdi_info(mp, ptgt->m_slot_num);
396 396 mdb_dec_indent(5);
397 397 }
398 398 }
399 399 }
400 400
401 401 mdb_printf("\n");
402 402 mdb_printf(" mptsas_smp_t devhdl wwn phymask\n");
403 403 mdb_printf("---------------------------------------"
404 404 "------------------\n");
405 405 for (psmp = (mptsas_smp_t *)krefhash_first(
406 406 (uintptr_t)mp->m_smp_targets, &p_addr);
407 407 psmp != NULL;
408 408 psmp = krefhash_next((uintptr_t)mp->m_smp_targets, psmp,
409 409 &p_addr)) {
410 410 mdb_printf("%16p ", p_addr);
411 411 mdb_printf("%4d %"PRIx64" %04x\n",
412 412 psmp->m_devhdl, psmp->m_addr.mta_wwn,
413 413 psmp->m_addr.mta_phymask);
414 414
415 415 if (!verbose)
416 416 continue;
417 417
418 418 mdb_inc_indent(5);
419 419 if ((psmp->m_deviceinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE)
420 420 == MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER)
421 421 mdb_printf("Fanout expander: ");
422 422 if ((psmp->m_deviceinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE)
423 423 == MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER)
424 424 mdb_printf("Edge expander: ");
425 425 if ((psmp->m_deviceinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE)
426 426 == MPI2_SAS_DEVICE_INFO_END_DEVICE)
427 427 mdb_printf("End device: ");
428 428 if ((psmp->m_deviceinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE)
429 429 == MPI2_SAS_DEVICE_INFO_NO_DEVICE)
430 430 mdb_printf("No device ");
431 431
432 432 for (loop = 0, comma = 0;
433 433 loop < (sizeof (devinfo_array)
434 434 / sizeof (devinfo_array[0]));
435 435 loop++) {
436 436 if (psmp->m_deviceinfo &
437 437 devinfo_array[loop].value) {
438 438 mdb_printf("%s%s",
439 439 (comma ? ", " : ""),
440 440 devinfo_array[loop].text);
441 441 comma++;
442 442 }
443 443 }
444 444 mdb_printf("\n");
445 445 mdb_dec_indent(5);
446 446 }
447 447 }
448 448
449 449 int
450 450 display_slotinfo(struct mptsas *mp, struct mptsas_slots *s)
451 451 {
452 452 int i, nslots;
453 453 struct mptsas_cmd c, *q, *slots;
454 454 mptsas_target_t *ptgt;
455 455 int header_output = 0;
456 456 int rv = DCMD_OK;
457 457 int slots_in_use = 0;
458 458 int tcmds = 0;
459 459 int mismatch = 0;
460 460 int wq, dq;
461 461 int ncmds = 0;
462 462 ulong_t saved_indent;
463 463 uintptr_t panicstr;
464 464 int state;
465 465
466 466 if ((state = mdb_get_state()) == MDB_STATE_RUNNING) {
467 467 mdb_warn("mptsas: slot info can only be displayed on a system "
468 468 "dump or under kmdb\n");
469 469 return (DCMD_ERR);
470 470 }
471 471
472 472 if (mdb_readvar(&panicstr, "panicstr") == -1) {
473 473 mdb_warn("can't read variable 'panicstr'");
474 474 return (DCMD_ERR);
475 475 }
476 476
477 477 if (state != MDB_STATE_STOPPED && panicstr == NULL) {
478 478 mdb_warn("mptsas: slot info not available for live dump\n");
479 479 return (DCMD_ERR);
480 480 }
481 481
482 482 nslots = s->m_n_normal;
483 483 slots = mdb_alloc(sizeof (mptsas_cmd_t) * nslots, UM_SLEEP);
484 484
485 485 for (i = 0; i < nslots; i++)
486 486 if (s->m_slot[i]) {
487 487 slots_in_use++;
488 488 if (mdb_vread(&slots[i], sizeof (mptsas_cmd_t),
489 489 (uintptr_t)s->m_slot[i]) == -1) {
490 490 mdb_warn("couldn't read slot");
491 491 s->m_slot[i] = NULL;
492 492 }
493 493 if ((slots[i].cmd_flags & CFLAG_CMDIOC) == 0)
494 494 tcmds++;
495 495 if (i != slots[i].cmd_slot)
496 496 mismatch++;
497 497 }
498 498
499 499 for (q = mp->m_waitq, wq = 0; q; q = c.cmd_linkp, wq++)
500 500 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
501 501 mdb_warn("couldn't follow m_waitq");
502 502 rv = DCMD_ERR;
503 503 goto exit;
504 504 }
505 505
506 506 for (q = mp->m_doneq, dq = 0; q; q = c.cmd_linkp, dq++)
507 507 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
508 508 mdb_warn("couldn't follow m_doneq");
509 509 rv = DCMD_ERR;
510 510 goto exit;
511 511 }
512 512
513 513 for (ptgt = krefhash_first((uintptr_t)mp->m_targets, NULL);
514 514 ptgt != NULL;
515 515 ptgt = krefhash_next((uintptr_t)mp->m_targets, ptgt, NULL)) {
516 516 if (ptgt->m_addr.mta_wwn ||
517 517 ptgt->m_deviceinfo) {
518 518 ncmds += ptgt->m_t_ncmds;
519 519 }
520 520 }
521 521
522 522 mdb_printf("\n");
523 523 mdb_printf(" mpt. slot mptsas_slots slot");
524 524 mdb_printf("\n");
525 525 mdb_printf("m_ncmds total"
526 526 " targ throttle m_t_ncmds targ_tot wq dq");
527 527 mdb_printf("\n");
528 528 mdb_printf("----------------------------------------------------");
529 529 mdb_printf("\n");
530 530
531 531 mdb_printf("%7d ", mp->m_ncmds);
532 532 mdb_printf("%s", (mp->m_ncmds == slots_in_use ? " " : "!="));
533 533 mdb_printf("%3d total %3d ", slots_in_use, ncmds);
534 534 mdb_printf("%s", (tcmds == ncmds ? " " : " !="));
535 535 mdb_printf("%3d %2d %2d\n", tcmds, wq, dq);
536 536
537 537 saved_indent = mdb_dec_indent(0);
538 538 mdb_dec_indent(saved_indent);
539 539
540 540 for (i = 0; i < s->m_n_normal; i++)
541 541 if (s->m_slot[i]) {
542 542 if (!header_output) {
543 543 mdb_printf("\n");
544 544 mdb_printf("mptsas_cmd slot cmd_slot "
545 545 "cmd_flags cmd_pkt_flags scsi_pkt "
546 546 " targ,lun [ pkt_cdbp ...\n");
547 547 mdb_printf("-------------------------------"
548 548 "--------------------------------------"
549 549 "--------------------------------------"
550 550 "------\n");
551 551 header_output = 1;
552 552 }
553 553 mdb_printf("%16p %4d %s %4d %8x %8x %16p ",
554 554 s->m_slot[i], i,
555 555 (i == slots[i].cmd_slot?" ":"BAD"),
556 556 slots[i].cmd_slot,
557 557 slots[i].cmd_flags,
558 558 slots[i].cmd_pkt_flags,
559 559 slots[i].cmd_pkt);
560 560 (void) print_cdb(&slots[i]);
561 561 }
562 562
563 563 /* print the wait queue */
564 564
565 565 for (q = mp->m_waitq; q; q = c.cmd_linkp) {
566 566 if (q == mp->m_waitq)
567 567 mdb_printf("\n");
568 568 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
569 569 == -1) {
570 570 mdb_warn("couldn't follow m_waitq");
571 571 rv = DCMD_ERR;
572 572 goto exit;
573 573 }
574 574 mdb_printf("%16p wait n/a %4d %8x %8x %16p ",
575 575 q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
576 576 c.cmd_pkt);
577 577 print_cdb(&c);
578 578 }
579 579
580 580 /* print the done queue */
581 581
582 582 for (q = mp->m_doneq; q; q = c.cmd_linkp) {
583 583 if (q == mp->m_doneq)
584 584 mdb_printf("\n");
585 585 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q)
586 586 == -1) {
587 587 mdb_warn("couldn't follow m_doneq");
588 588 rv = DCMD_ERR;
589 589 goto exit;
590 590 }
591 591 mdb_printf("%16p done n/a %4d %8x %8x %16p ",
592 592 q, c.cmd_slot, c.cmd_flags, c.cmd_pkt_flags,
593 593 c.cmd_pkt);
594 594 print_cdb(&c);
595 595 }
596 596
597 597 mdb_inc_indent(saved_indent);
598 598
599 599 if (mp->m_ncmds != slots_in_use)
600 600 mdb_printf("WARNING: mpt.m_ncmds does not match the number of "
601 601 "slots in use\n");
602 602
603 603 if (tcmds != ncmds)
604 604 mdb_printf("WARNING: the total of m_target[].m_t_ncmds does "
605 605 "not match the slots in use\n");
606 606
607 607 if (mismatch)
608 608 mdb_printf("WARNING: corruption in slot table, "
609 609 "m_slot[].cmd_slot incorrect\n");
610 610
611 611 /* now check for corruptions */
612 612
613 613 for (q = mp->m_waitq; q; q = c.cmd_linkp) {
614 614 for (i = 0; i < nslots; i++)
615 615 if (s->m_slot[i] == q)
616 616 mdb_printf("WARNING: m_waitq entry"
617 617 "(mptsas_cmd_t) %p is in m_slot[%i]\n",
618 618 q, i);
619 619
620 620 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
621 621 mdb_warn("couldn't follow m_waitq");
622 622 rv = DCMD_ERR;
623 623 goto exit;
624 624 }
625 625 }
626 626
627 627 for (q = mp->m_doneq; q; q = c.cmd_linkp) {
628 628 for (i = 0; i < nslots; i++)
629 629 if (s->m_slot[i] == q)
630 630 mdb_printf("WARNING: m_doneq entry "
631 631 "(mptsas_cmd_t) %p is in m_slot[%i]\n", q, i);
632 632
633 633 if (mdb_vread(&c, sizeof (mptsas_cmd_t), (uintptr_t)q) == -1) {
634 634 mdb_warn("couldn't follow m_doneq");
635 635 rv = DCMD_ERR;
636 636 goto exit;
637 637 }
638 638 if ((c.cmd_flags & CFLAG_FINISHED) == 0)
639 639 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
640 640 "should have CFLAG_FINISHED set\n", q);
641 641 if (c.cmd_flags & CFLAG_IN_TRANSPORT)
642 642 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
643 643 "should not have CFLAG_IN_TRANSPORT set\n", q);
644 644 if (c.cmd_flags & CFLAG_CMDARQ)
645 645 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
646 646 "should not have CFLAG_CMDARQ set\n", q);
647 647 if (c.cmd_flags & CFLAG_COMPLETED)
648 648 mdb_printf("WARNING: m_doneq entry (mptsas_cmd_t) %p "
649 649 "should not have CFLAG_COMPLETED set\n", q);
650 650 }
651 651
652 652 exit:
653 653 mdb_free(slots, sizeof (mptsas_cmd_t) * nslots);
654 654 return (rv);
655 655 }
656 656
657 657 void
658 658 display_deviceinfo(struct mptsas *mp)
659 659 {
660 660 char device_path[PATH_MAX];
661 661
662 662 *device_path = 0;
663 663 if (construct_path((uintptr_t)mp->m_dip, device_path) != DCMD_OK) {
664 664 strcpy(device_path, "couldn't determine device path");
665 665 }
666 666
667 667 mdb_printf("\n");
668 668 mdb_printf("base_wwid phys "
669 669 " prodid devid revid ssid\n");
670 670 mdb_printf("-----------------------------"
671 671 "----------------------------------\n");
672 672 mdb_printf("%"PRIx64" %2d "
673 673 "0x%04x 0x%04x ", mp->un.m_base_wwid, mp->m_num_phys,
674 674 mp->m_productid, mp->m_devid);
675 675 switch (mp->m_devid) {
676 676 case MPI2_MFGPAGE_DEVID_SAS2004:
677 677 mdb_printf("(SAS2004) ");
678 678 break;
679 679 case MPI2_MFGPAGE_DEVID_SAS2008:
680 680 mdb_printf("(SAS2008) ");
681 681 break;
682 682 case MPI2_MFGPAGE_DEVID_SAS2108_1:
683 683 case MPI2_MFGPAGE_DEVID_SAS2108_2:
684 684 case MPI2_MFGPAGE_DEVID_SAS2108_3:
685 685 mdb_printf("(SAS2108) ");
686 686 break;
687 687 case MPI2_MFGPAGE_DEVID_SAS2116_1:
688 688 case MPI2_MFGPAGE_DEVID_SAS2116_2:
689 689 mdb_printf("(SAS2116) ");
690 690 break;
691 691 case MPI2_MFGPAGE_DEVID_SSS6200:
692 692 mdb_printf("(SSS6200) ");
693 693 break;
694 694 case MPI2_MFGPAGE_DEVID_SAS2208_1:
695 695 case MPI2_MFGPAGE_DEVID_SAS2208_2:
696 696 case MPI2_MFGPAGE_DEVID_SAS2208_3:
697 697 case MPI2_MFGPAGE_DEVID_SAS2208_4:
698 698 case MPI2_MFGPAGE_DEVID_SAS2208_5:
699 699 case MPI2_MFGPAGE_DEVID_SAS2208_6:
700 700 mdb_printf("(SAS2208) ");
701 701 break;
702 702 case MPI2_MFGPAGE_DEVID_SAS2308_1:
703 703 case MPI2_MFGPAGE_DEVID_SAS2308_2:
704 704 case MPI2_MFGPAGE_DEVID_SAS2308_3:
705 705 mdb_printf("(SAS2308) ");
706 706 break;
707 707 case MPI25_MFGPAGE_DEVID_SAS3004:
708 708 mdb_printf("(SAS3004) ");
|
↓ open down ↓ |
671 lines elided |
↑ open up ↑ |
709 709 break;
710 710 case MPI25_MFGPAGE_DEVID_SAS3008:
711 711 mdb_printf("(SAS3008) ");
712 712 break;
713 713 case MPI25_MFGPAGE_DEVID_SAS3108_1:
714 714 case MPI25_MFGPAGE_DEVID_SAS3108_2:
715 715 case MPI25_MFGPAGE_DEVID_SAS3108_5:
716 716 case MPI25_MFGPAGE_DEVID_SAS3108_6:
717 717 mdb_printf("(SAS3108) ");
718 718 break;
719 + case MPI26_MFGPAGE_DEVID_SAS3216:
720 + case MPI26_MFGPAGE_DEVID_SAS3316_1:
721 + case MPI26_MFGPAGE_DEVID_SAS3316_2:
722 + case MPI26_MFGPAGE_DEVID_SAS3316_3:
723 + case MPI26_MFGPAGE_DEVID_SAS3316_4:
724 + mdb_printf("(SAS3216) ");
725 + break;
726 + case MPI26_MFGPAGE_DEVID_SAS3224:
727 + case MPI26_MFGPAGE_DEVID_SAS3324_1:
728 + case MPI26_MFGPAGE_DEVID_SAS3324_2:
729 + case MPI26_MFGPAGE_DEVID_SAS3324_3:
730 + case MPI26_MFGPAGE_DEVID_SAS3324_4:
731 + mdb_printf("(SAS3224) ");
732 + break;
733 + case MPI26_MFGPAGE_DEVID_SAS3408:
734 + mdb_printf("(SAS3408) ");
735 + break;
736 + case MPI26_MFGPAGE_DEVID_SAS3416:
737 + mdb_printf("(SAS3416) ");
738 + break;
739 + case MPI26_MFGPAGE_DEVID_SAS3508:
740 + case MPI26_MFGPAGE_DEVID_SAS3508_1:
741 + mdb_printf("(SAS3508) ");
742 + break;
743 + case MPI26_MFGPAGE_DEVID_SAS3516:
744 + case MPI26_MFGPAGE_DEVID_SAS3516_1:
745 + mdb_printf("(SAS3516) ");
746 + break;
747 + case MPI26_MFGPAGE_DEVID_SAS3616:
748 + mdb_printf("(SAS3616) ");
749 + break;
750 + case MPI26_MFGPAGE_DEVID_SAS3708:
751 + mdb_printf("(SAS3708) ");
752 + break;
753 + case MPI26_MFGPAGE_DEVID_SAS3716:
754 + mdb_printf("(SAS3716) ");
755 + break;
756 + case MPI26_MFGPAGE_DEVID_SAS4008:
757 + mdb_printf("(SAS4008) ");
758 + break;
719 759 default:
720 760 mdb_printf("(SAS????) ");
721 761 break;
722 762 }
723 763 mdb_printf("0x%02x 0x%04x\n", mp->m_revid, mp->m_ssid);
724 764 mdb_printf("%s\n", device_path);
725 765
726 766 }
727 767
728 768 void
729 769 dump_debug_log(void)
730 770 {
731 771 uint32_t idx;
732 772 size_t linecnt, linelen;
733 773 char *logbuf;
734 774 int i;
735 775
736 776 if (mdb_readsym(&idx, sizeof (uint32_t), "mptsas_dbglog_idx") == -1) {
737 777 mdb_warn("No debug log buffer present");
738 778 return;
739 779 }
740 780 if (mdb_readsym(&linecnt, sizeof (size_t), "mptsas_dbglog_linecnt")
741 781 == -1) {
742 782 mdb_warn("No debug linecnt present");
743 783 return;
744 784 }
745 785 if (mdb_readsym(&linelen, sizeof (size_t), "mptsas_dbglog_linelen")
746 786 == -1) {
747 787 mdb_warn("No debug linelen present");
748 788 return;
749 789 }
750 790 logbuf = mdb_alloc(linelen * linecnt, UM_SLEEP);
751 791
752 792 if (mdb_readsym(logbuf, linelen * linecnt, "mptsas_dbglog_bufs")
753 793 == -1) {
754 794 mdb_warn("No debug log buffer present");
755 795 return;
756 796 }
757 797 mdb_printf("\n");
758 798 idx &= linecnt - 1;
759 799 for (i = 0; i < linecnt; i++) {
760 800 mdb_printf("%s\n", &logbuf[idx * linelen]);
761 801 idx++;
762 802 idx &= linecnt - 1;
763 803 }
764 804 mdb_free(logbuf, linelen * linecnt);
765 805 }
766 806
767 807 static int
768 808 mptsas_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
769 809 {
770 810 struct mptsas m;
771 811 struct mptsas_slots *s;
772 812
773 813 int nslots;
774 814 int slot_size = 0;
775 815 uint_t verbose = FALSE;
776 816 uint_t target_info = FALSE;
777 817 uint_t slot_info = FALSE;
778 818 uint_t device_info = FALSE;
779 819 uint_t port_info = FALSE;
780 820 uint_t debug_log = FALSE;
781 821 int rv = DCMD_OK;
782 822
783 823 if (!(flags & DCMD_ADDRSPEC)) {
784 824 void *mptsas_state = NULL;
785 825
786 826 if (mdb_readvar(&mptsas_state, "mptsas_state") == -1) {
787 827 mdb_warn("can't read mptsas_state");
788 828 return (DCMD_ERR);
789 829 }
790 830 if (mdb_pwalk_dcmd("genunix`softstate", "mpt_sas`mptsas", argc,
791 831 argv, (uintptr_t)mptsas_state) == -1) {
792 832 mdb_warn("mdb_pwalk_dcmd failed");
793 833 return (DCMD_ERR);
794 834 }
795 835 return (DCMD_OK);
796 836 }
797 837
798 838 if (mdb_getopts(argc, argv,
799 839 's', MDB_OPT_SETBITS, TRUE, &slot_info,
800 840 'd', MDB_OPT_SETBITS, TRUE, &device_info,
801 841 't', MDB_OPT_SETBITS, TRUE, &target_info,
802 842 'p', MDB_OPT_SETBITS, TRUE, &port_info,
803 843 'v', MDB_OPT_SETBITS, TRUE, &verbose,
804 844 'D', MDB_OPT_SETBITS, TRUE, &debug_log,
805 845 NULL) != argc)
806 846 return (DCMD_USAGE);
807 847
808 848
809 849 if (mdb_vread(&m, sizeof (m), addr) == -1) {
810 850 mdb_warn("couldn't read mpt struct at 0x%p", addr);
811 851 return (DCMD_ERR);
812 852 }
813 853
814 854 s = mdb_alloc(sizeof (mptsas_slots_t), UM_SLEEP);
815 855
816 856 if (mdb_vread(s, sizeof (mptsas_slots_t),
817 857 (uintptr_t)m.m_active) == -1) {
818 858 mdb_warn("couldn't read small mptsas_slots_t at 0x%p",
819 859 m.m_active);
820 860 mdb_free(s, sizeof (mptsas_slots_t));
821 861 return (DCMD_ERR);
822 862 }
823 863
824 864 nslots = s->m_n_normal;
825 865
826 866 mdb_free(s, sizeof (mptsas_slots_t));
827 867
828 868 slot_size = sizeof (mptsas_slots_t) +
829 869 (sizeof (mptsas_cmd_t *) * (nslots-1));
830 870
831 871 s = mdb_alloc(slot_size, UM_SLEEP);
832 872
833 873 if (mdb_vread(s, slot_size, (uintptr_t)m.m_active) == -1) {
834 874 mdb_warn("couldn't read large mptsas_slots_t at 0x%p",
835 875 m.m_active);
836 876 mdb_free(s, slot_size);
837 877 return (DCMD_ERR);
838 878 }
839 879
840 880 /* processing completed */
841 881
842 882 if (((flags & DCMD_ADDRSPEC) && !(flags & DCMD_LOOP)) ||
843 883 (flags & DCMD_LOOPFIRST) || slot_info || device_info ||
844 884 target_info) {
845 885 if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST))
846 886 mdb_printf("\n");
847 887 mdb_printf(" mptsas_t inst ncmds suspend power");
848 888 mdb_printf("\n");
849 889 mdb_printf("========================================="
850 890 "=======================================");
851 891 mdb_printf("\n");
852 892 }
853 893
854 894 mdb_printf("%16p %4d %5d ", addr, m.m_instance, m.m_ncmds);
855 895 mdb_printf("%7d", m.m_suspended);
856 896 switch (m.m_power_level) {
857 897 case PM_LEVEL_D0:
858 898 mdb_printf(" ON=D0 ");
859 899 break;
860 900 case PM_LEVEL_D1:
861 901 mdb_printf(" D1 ");
862 902 break;
863 903 case PM_LEVEL_D2:
864 904 mdb_printf(" D2 ");
865 905 break;
866 906 case PM_LEVEL_D3:
867 907 mdb_printf("OFF=D3 ");
868 908 break;
869 909 default:
870 910 mdb_printf("INVALD ");
871 911 }
872 912 mdb_printf("\n");
873 913
874 914 mdb_inc_indent(17);
875 915
876 916 if (target_info)
877 917 display_targets(&m, verbose);
878 918
879 919 if (port_info)
880 920 display_ports(&m);
881 921
882 922 if (device_info)
883 923 display_deviceinfo(&m);
884 924
885 925 if (slot_info)
886 926 display_slotinfo(&m, s);
887 927
888 928 if (debug_log)
889 929 dump_debug_log();
890 930
891 931 mdb_dec_indent(17);
892 932
893 933 mdb_free(s, slot_size);
894 934
895 935 return (rv);
896 936 }
897 937
898 938 void
899 939 mptsas_help()
900 940 {
901 941 mdb_printf("Prints summary information about each mpt_sas instance, "
902 942 "including warning\nmessages when slot usage doesn't match "
903 943 "summary information.\n"
904 944 "Without the address of a \"struct mptsas\", prints every "
905 945 "instance.\n\n"
906 946 "Switches:\n"
907 947 " -t[v] includes information about targets, v = be more verbose\n"
908 948 " -p includes information about port\n"
909 949 " -s includes information about mpt slots\n"
910 950 " -d includes information about the hardware\n"
911 951 " -D print the mptsas specific debug log\n");
912 952 }
913 953
914 954 static const mdb_dcmd_t dcmds[] = {
915 955 { "mptsas", "?[-tpsdD]", "print mpt_sas information", mptsas_dcmd,
916 956 mptsas_help}, { NULL }
917 957 };
918 958
919 959 static const mdb_modinfo_t modinfo = {
920 960 MDB_API_VERSION, dcmds, NULL
921 961 };
922 962
923 963 const mdb_modinfo_t *
924 964 _mdb_init(void)
925 965 {
926 966 return (&modinfo);
927 967 }
|
↓ open down ↓ |
199 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX