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