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