1 /*
2 * Copyright (c) 2004-2008 Voltaire Inc. All rights reserved.
3 * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35 #if HAVE_CONFIG_H
36 # include <config.h>
37 #endif /* HAVE_CONFIG_H */
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <inttypes.h>
44 #include <netinet/in.h>
45
46 #include <mad.h>
47 #include <infiniband/common.h>
48
49 void
mad_dump_int(char * buf,int bufsz,void * val,int valsz)50 mad_dump_int(char *buf, int bufsz, void *val, int valsz)
51 {
52 switch (valsz) {
53 case 1:
54 snprintf(buf, bufsz, "%d", *(uint8_t *)val);
55 break;
56 case 2:
57 snprintf(buf, bufsz, "%d", *(uint16_t *)val);
58 break;
59 case 3:
60 case 4:
61 snprintf(buf, bufsz, "%d", *(uint32_t *)val);
62 break;
63 case 5:
64 case 6:
65 case 7:
66 case 8:
67 snprintf(buf, bufsz, "%" PRIu64, *(uint64_t *)val);
68 break;
69 default:
70 IBWARN("bad int sz %d", valsz);
71 buf[0] = 0;
72 }
73 }
74
75 void
mad_dump_uint(char * buf,int bufsz,void * val,int valsz)76 mad_dump_uint(char *buf, int bufsz, void *val, int valsz)
77 {
78 switch (valsz) {
79 case 1:
80 snprintf(buf, bufsz, "%u", *(uint8_t *)val);
81 break;
82 case 2:
83 snprintf(buf, bufsz, "%u", *(uint16_t *)val);
84 break;
85 case 3:
86 case 4:
87 snprintf(buf, bufsz, "%u", *(uint32_t *)val);
88 break;
89 case 5:
90 case 6:
91 case 7:
92 case 8:
93 snprintf(buf, bufsz, "%" PRIu64, *(uint64_t *)val);
94 break;
95 default:
96 IBWARN("bad int sz %u", valsz);
97 buf[0] = 0;
98 }
99 }
100
101 void
mad_dump_hex(char * buf,int bufsz,void * val,int valsz)102 mad_dump_hex(char *buf, int bufsz, void *val, int valsz)
103 {
104 switch (valsz) {
105 case 1:
106 snprintf(buf, bufsz, "0x%02x", *(uint8_t *)val);
107 break;
108 case 2:
109 snprintf(buf, bufsz, "0x%04x", *(uint16_t *)val);
110 break;
111 case 3:
112 snprintf(buf, bufsz, "0x%06x", *(uint32_t *)val & 0xffffff);
113 break;
114 case 4:
115 snprintf(buf, bufsz, "0x%08x", *(uint32_t *)val);
116 break;
117 case 5:
118 snprintf(buf, bufsz, "0x%010" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffllu);
119 break;
120 case 6:
121 snprintf(buf, bufsz, "0x%012" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffffllu);
122 break;
123 case 7:
124 snprintf(buf, bufsz, "0x%014" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffffffllu);
125 break;
126 case 8:
127 snprintf(buf, bufsz, "0x%016" PRIx64, *(uint64_t *)val);
128 break;
129 default:
130 IBWARN("bad int sz %d", valsz);
131 buf[0] = 0;
132 }
133 }
134
135 void
mad_dump_rhex(char * buf,int bufsz,void * val,int valsz)136 mad_dump_rhex(char *buf, int bufsz, void *val, int valsz)
137 {
138 switch (valsz) {
139 case 1:
140 snprintf(buf, bufsz, "%02x", *(uint8_t *)val);
141 break;
142 case 2:
143 snprintf(buf, bufsz, "%04x", *(uint16_t *)val);
144 break;
145 case 3:
146 snprintf(buf, bufsz, "%06x", *(uint32_t *)val & 0xffffff);
147 break;
148 case 4:
149 snprintf(buf, bufsz, "%08x", *(uint32_t *)val);
150 break;
151 case 5:
152 snprintf(buf, bufsz, "%010" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffllu);
153 break;
154 case 6:
155 snprintf(buf, bufsz, "%012" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffffllu);
156 break;
157 case 7:
158 snprintf(buf, bufsz, "%014" PRIx64, *(uint64_t *)val & (uint64_t) 0xffffffffffffffllu);
159 break;
160 case 8:
161 snprintf(buf, bufsz, "%016" PRIx64, *(uint64_t *)val);
162 break;
163 default:
164 IBWARN("bad int sz %d", valsz);
165 buf[0] = 0;
166 }
167 }
168
169 void
mad_dump_linkwidth(char * buf,int bufsz,void * val,int valsz)170 mad_dump_linkwidth(char *buf, int bufsz, void *val, int valsz)
171 {
172 int width = *(int *)val;
173
174 switch (width) {
175 case 1:
176 snprintf(buf, bufsz, "1X");
177 break;
178 case 2:
179 snprintf(buf, bufsz, "4X");
180 break;
181 case 4:
182 snprintf(buf, bufsz, "8X");
183 break;
184 case 8:
185 snprintf(buf, bufsz, "12X");
186 break;
187 default:
188 IBWARN("bad width %d", width);
189 buf[0] = 0;
190 }
191 }
192
193 static void
dump_linkwidth(char * buf,int bufsz,int width)194 dump_linkwidth(char *buf, int bufsz, int width)
195 {
196 int n = 0;
197
198 if (width & 0x1)
199 n += snprintf(buf + n, bufsz - n, "1X or ");
200 if (n < bufsz && (width & 0x2))
201 n += snprintf(buf + n, bufsz - n, "4X or ");
202 if (n < bufsz && (width & 0x4))
203 n += snprintf(buf + n, bufsz - n, "8X or ");
204 if (n < bufsz && (width & 0x8))
205 n += snprintf(buf + n, bufsz - n, "12X or ");
206
207 if (n >= bufsz)
208 return;
209 else if (width == 0 || (width >> 4))
210 snprintf(buf + n, bufsz - n, "undefined (%d)", width);
211 else if (bufsz > 3)
212 buf[n-4] = '\0';
213 }
214
215 void
mad_dump_linkwidthsup(char * buf,int bufsz,void * val,int valsz)216 mad_dump_linkwidthsup(char *buf, int bufsz, void *val, int valsz)
217 {
218 int width = *(int *)val;
219
220 dump_linkwidth(buf, bufsz, width);
221
222 switch(width) {
223 case 1:
224 case 3:
225 case 7:
226 case 11:
227 case 15:
228 break;
229
230 default:
231 if (!(width >> 4))
232 snprintf(buf + strlen(buf), bufsz - strlen(buf),
233 " (IBA extension)");
234 break;
235 }
236 }
237
238 void
mad_dump_linkwidthen(char * buf,int bufsz,void * val,int valsz)239 mad_dump_linkwidthen(char *buf, int bufsz, void *val, int valsz)
240 {
241 int width = *(int *)val;
242
243 dump_linkwidth(buf, bufsz, width);
244 }
245
246 void
mad_dump_linkspeed(char * buf,int bufsz,void * val,int valsz)247 mad_dump_linkspeed(char *buf, int bufsz, void *val, int valsz)
248 {
249 int speed = *(int *)val;
250
251 switch (speed) {
252 case 1:
253 snprintf(buf, bufsz, "2.5 Gbps");
254 break;
255 case 2:
256 snprintf(buf, bufsz, "5.0 Gbps");
257 break;
258 case 4:
259 snprintf(buf, bufsz, "10.0 Gbps");
260 break;
261 default:
262 snprintf(buf, bufsz, "undefined (%d)", speed);
263 break;
264 }
265 }
266
267 static void
dump_linkspeed(char * buf,int bufsz,int speed)268 dump_linkspeed(char *buf, int bufsz, int speed)
269 {
270 int n = 0;
271
272 if (speed & 0x1)
273 n += snprintf(buf + n, bufsz - n, "2.5 Gbps or ");
274 if (n < bufsz && (speed & 0x2))
275 n += snprintf(buf + n, bufsz - n, "5.0 Gbps or ");
276 if (n < bufsz && (speed & 0x4))
277 n += snprintf(buf + n, bufsz - n, "10.0 Gbps or ");
278
279 if (n >= bufsz)
280 return;
281 else if (speed == 0 || (speed >> 3)) {
282 n += snprintf(buf + n, bufsz - n, "undefined (%d)", speed);
283 if (n >= bufsz)
284 return;
285 } else if (bufsz > 3) {
286 buf[n-4] = '\0';
287 n -= 4;
288 }
289
290 switch (speed) {
291 case 1:
292 case 3:
293 case 5:
294 case 7:
295 break;
296 default:
297 if (!(speed >> 3))
298 snprintf(buf + n, bufsz - n, " (IBA extension)");
299 break;
300 }
301 }
302
303 void
mad_dump_linkspeedsup(char * buf,int bufsz,void * val,int valsz)304 mad_dump_linkspeedsup(char *buf, int bufsz, void *val, int valsz)
305 {
306 int speed = *(int *)val;
307
308 dump_linkspeed(buf, bufsz, speed);
309 }
310
311 void
mad_dump_linkspeeden(char * buf,int bufsz,void * val,int valsz)312 mad_dump_linkspeeden(char *buf, int bufsz, void *val, int valsz)
313 {
314 int speed = *(int *)val;
315
316 dump_linkspeed(buf, bufsz, speed);
317 }
318
319 void
mad_dump_portstate(char * buf,int bufsz,void * val,int valsz)320 mad_dump_portstate(char *buf, int bufsz, void *val, int valsz)
321 {
322 int state = *(int *)val;
323
324 switch (state) {
325 case 0:
326 snprintf(buf, bufsz, "NoChange");
327 break;
328 case 1:
329 snprintf(buf, bufsz, "Down");
330 break;
331 case 2:
332 snprintf(buf, bufsz, "Initialize");
333 break;
334 case 3:
335 snprintf(buf, bufsz, "Armed");
336 break;
337 case 4:
338 snprintf(buf, bufsz, "Active");
339 break;
340 default:
341 snprintf(buf, bufsz, "?(%d)", state);
342 }
343 }
344
345 void
mad_dump_linkdowndefstate(char * buf,int bufsz,void * val,int valsz)346 mad_dump_linkdowndefstate(char *buf, int bufsz, void *val, int valsz)
347 {
348 int state = *(int *)val;
349
350 switch(state) {
351 case 0:
352 snprintf(buf, bufsz, "NoChange");
353 break;
354 case 1:
355 snprintf(buf, bufsz, "Sleep");
356 break;
357 case 2:
358 snprintf(buf, bufsz, "Polling");
359 break;
360 default:
361 snprintf(buf, bufsz, "?(%d)", state);
362 break;
363 }
364 }
365
366 void
mad_dump_physportstate(char * buf,int bufsz,void * val,int valsz)367 mad_dump_physportstate(char *buf, int bufsz, void *val, int valsz)
368 {
369 int state = *(int *)val;
370
371 switch (state) {
372 case 0:
373 snprintf(buf, bufsz, "NoChange");
374 break;
375 case 1:
376 snprintf(buf, bufsz, "Sleep");
377 break;
378 case 2:
379 snprintf(buf, bufsz, "Polling");
380 break;
381 case 3:
382 snprintf(buf, bufsz, "Disabled");
383 break;
384 case 4:
385 snprintf(buf, bufsz, "PortConfigurationTraining");
386 break;
387 case 5:
388 snprintf(buf, bufsz, "LinkUp");
389 break;
390 case 6:
391 snprintf(buf, bufsz, "LinkErrorRecovery");
392 break;
393 case 7:
394 snprintf(buf, bufsz, "PhyTest");
395 break;
396 default:
397 snprintf(buf, bufsz, "?(%d)", state);
398 }
399 }
400
401 void
mad_dump_mtu(char * buf,int bufsz,void * val,int valsz)402 mad_dump_mtu(char *buf, int bufsz, void *val, int valsz)
403 {
404 int mtu = *(int *)val;
405
406 switch (mtu) {
407 case 1:
408 snprintf(buf, bufsz, "256");
409 break;
410 case 2:
411 snprintf(buf, bufsz, "512");
412 break;
413 case 3:
414 snprintf(buf, bufsz, "1024");
415 break;
416 case 4:
417 snprintf(buf, bufsz, "2048");
418 break;
419 case 5:
420 snprintf(buf, bufsz, "4096");
421 break;
422 default:
423 snprintf(buf, bufsz, "?(%d)", mtu);
424 buf[0] = 0;
425 }
426 }
427
428 void
mad_dump_vlcap(char * buf,int bufsz,void * val,int valsz)429 mad_dump_vlcap(char *buf, int bufsz, void *val, int valsz)
430 {
431 int vlcap = *(int *)val;
432
433 switch (vlcap) {
434 case 1:
435 snprintf(buf, bufsz, "VL0");
436 break;
437 case 2:
438 snprintf(buf, bufsz, "VL0-1");
439 break;
440 case 3:
441 snprintf(buf, bufsz, "VL0-3");
442 break;
443 case 4:
444 snprintf(buf, bufsz, "VL0-7");
445 break;
446 case 5:
447 snprintf(buf, bufsz, "VL0-14");
448 break;
449 default:
450 snprintf(buf, bufsz, "?(%d)", vlcap);
451 }
452 }
453
454 void
mad_dump_opervls(char * buf,int bufsz,void * val,int valsz)455 mad_dump_opervls(char *buf, int bufsz, void *val, int valsz)
456 {
457 int opervls = *(int *)val;
458
459 switch (opervls) {
460 case 0:
461 snprintf(buf, bufsz, "No change");
462 break;
463 case 1:
464 snprintf(buf, bufsz, "VL0");
465 break;
466 case 2:
467 snprintf(buf, bufsz, "VL0-1");
468 break;
469 case 3:
470 snprintf(buf, bufsz, "VL0-3");
471 break;
472 case 4:
473 snprintf(buf, bufsz, "VL0-7");
474 break;
475 case 5:
476 snprintf(buf, bufsz, "VL0-14");
477 break;
478 default:
479 snprintf(buf, bufsz, "?(%d)", opervls);
480 }
481 }
482
483 void
mad_dump_portcapmask(char * buf,int bufsz,void * val,int valsz)484 mad_dump_portcapmask(char *buf, int bufsz, void *val, int valsz)
485 {
486 unsigned mask = *(unsigned *)val;
487 char *s = buf;
488
489 s += sprintf(s, "0x%x\n", mask);
490 if (mask & (1 << 1))
491 s += sprintf(s, "\t\t\t\tIsSM\n");
492 if (mask & (1 << 2))
493 s += sprintf(s, "\t\t\t\tIsNoticeSupported\n");
494 if (mask & (1 << 3))
495 s += sprintf(s, "\t\t\t\tIsTrapSupported\n");
496 if (mask & (1 << 5))
497 s += sprintf(s, "\t\t\t\tIsAutomaticMigrationSupported\n");
498 if (mask & (1 << 6))
499 s += sprintf(s, "\t\t\t\tIsSLMappingSupported\n");
500 if (mask & (1 << 7))
501 s += sprintf(s, "\t\t\t\tIsMKeyNVRAM\n");
502 if (mask & (1 << 8))
503 s += sprintf(s, "\t\t\t\tIsPKeyNVRAM\n");
504 if (mask & (1 << 9))
505 s += sprintf(s, "\t\t\t\tIsLedInfoSupported\n");
506 if (mask & (1 << 10))
507 s += sprintf(s, "\t\t\t\tIsSMdisabled\n");
508 if (mask & (1 << 11))
509 s += sprintf(s, "\t\t\t\tIsSystemImageGUIDsupported\n");
510 if (mask & (1 << 12))
511 s += sprintf(s, "\t\t\t\tIsPkeySwitchExternalPortTrapSupported\n");
512 if (mask & (1 << 16))
513 s += sprintf(s, "\t\t\t\tIsCommunicatonManagementSupported\n");
514 if (mask & (1 << 17))
515 s += sprintf(s, "\t\t\t\tIsSNMPTunnelingSupported\n");
516 if (mask & (1 << 18))
517 s += sprintf(s, "\t\t\t\tIsReinitSupported\n");
518 if (mask & (1 << 19))
519 s += sprintf(s, "\t\t\t\tIsDeviceManagementSupported\n");
520 if (mask & (1 << 20))
521 s += sprintf(s, "\t\t\t\tIsVendorClassSupported\n");
522 if (mask & (1 << 21))
523 s += sprintf(s, "\t\t\t\tIsDRNoticeSupported\n");
524 if (mask & (1 << 22))
525 s += sprintf(s, "\t\t\t\tIsCapabilityMaskNoticeSupported\n");
526 if (mask & (1 << 23))
527 s += sprintf(s, "\t\t\t\tIsBootManagementSupported\n");
528 if (mask & (1 << 24))
529 s += sprintf(s, "\t\t\t\tIsLinkRoundTripLatencySupported\n");
530 if (mask & (1 << 25))
531 s += sprintf(s, "\t\t\t\tIsClientRegistrationSupported\n");
532 if (mask & (1 << 26))
533 s += sprintf(s, "\t\t\t\tIsOtherLocalChangesNoticeSupported\n");
534 if (mask & (1 << 27))
535 s += sprintf(s, "\t\t\t\tIsLinkSpeedWidthPairsTableSupported\n");
536
537 if (s != buf)
538 *(--s) = 0;
539 }
540
541 void
mad_dump_bitfield(char * buf,int bufsz,void * val,int valsz)542 mad_dump_bitfield(char *buf, int bufsz, void *val, int valsz)
543 {
544 snprintf(buf, bufsz, "0x%x", *(uint32_t *)val);
545 }
546
547 void
mad_dump_array(char * buf,int bufsz,void * val,int valsz)548 mad_dump_array(char *buf, int bufsz, void *val, int valsz)
549 {
550 uint8_t *p = val, *e;
551 char *s = buf;
552
553 if (bufsz < valsz*2)
554 valsz = bufsz/2;
555
556 for (p = val, e = p + valsz; p < e; p++, s += 2)
557 sprintf(s, "%02x", *p);
558 }
559
560 void
mad_dump_string(char * buf,int bufsz,void * val,int valsz)561 mad_dump_string(char *buf, int bufsz, void *val, int valsz)
562 {
563 if (bufsz < valsz)
564 valsz = bufsz;
565
566 snprintf(buf, valsz, "'%s'", (char *)val);
567 }
568
569 void
mad_dump_node_type(char * buf,int bufsz,void * val,int valsz)570 mad_dump_node_type(char *buf, int bufsz, void *val, int valsz)
571 {
572 int nodetype = *(int*)val;
573
574 switch (nodetype) {
575 case 1:
576 snprintf(buf, bufsz, "Channel Adapter");
577 break;
578 case 2:
579 snprintf(buf, bufsz, "Switch");
580 break;
581 case 3:
582 snprintf(buf, bufsz, "Router");
583 break;
584 default:
585 snprintf(buf, bufsz, "?(%d)?", nodetype);
586 break;
587 }
588 }
589
590 #define IB_MAX_NUM_VLS 16
591 #define IB_MAX_NUM_VLS_TO_U8 ((IB_MAX_NUM_VLS)/2)
592
593 typedef struct _ib_slvl_table {
594 uint8_t vl_by_sl_num[IB_MAX_NUM_VLS_TO_U8];
595 } ib_slvl_table_t;
596
597 static inline void
ib_slvl_get_i(ib_slvl_table_t * tbl,int i,uint8_t * vl)598 ib_slvl_get_i(ib_slvl_table_t *tbl, int i, uint8_t *vl)
599 {
600 *vl = (tbl->vl_by_sl_num[i >> 1] >> ((!(i&1)) << 2)) & 0xf;
601 }
602
603 #define IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK 32
604
605 typedef struct _ib_vl_arb_table {
606 struct {
607 uint8_t res_vl;
608 uint8_t weight;
609 } vl_entry[IB_NUM_VL_ARB_ELEMENTS_IN_BLOCK];
610 } __attribute__((packed)) ib_vl_arb_table_t;
611
612 static inline void
ib_vl_arb_get_vl(uint8_t res_vl,uint8_t * const vl)613 ib_vl_arb_get_vl(uint8_t res_vl, uint8_t *const vl )
614 {
615 *vl = res_vl & 0x0F;
616 }
617
618 void
mad_dump_sltovl(char * buf,int bufsz,void * val,int valsz)619 mad_dump_sltovl(char *buf, int bufsz, void *val, int valsz)
620 {
621 ib_slvl_table_t* p_slvl_tbl = val;
622 uint8_t vl;
623 int i, n = 0;
624 n = snprintf(buf, bufsz, "|");
625 for (i = 0; i < 16; i++) {
626 ib_slvl_get_i(p_slvl_tbl, i, &vl);
627 n += snprintf(buf + n, bufsz - n, "%2u|", vl);
628 if (n >= bufsz)
629 break;
630 }
631 snprintf(buf + n, bufsz - n, "\n");
632 }
633
634 void
mad_dump_vlarbitration(char * buf,int bufsz,void * val,int num)635 mad_dump_vlarbitration(char *buf, int bufsz, void *val, int num)
636 {
637 ib_vl_arb_table_t* p_vla_tbl = val;
638 unsigned i, n;
639 uint8_t vl;
640
641 num /= sizeof(p_vla_tbl->vl_entry[0]);
642
643 n = snprintf(buf, bufsz, "\nVL : |");
644 if (n >= bufsz)
645 return;
646 for (i = 0; i < num; i++) {
647 ib_vl_arb_get_vl(p_vla_tbl->vl_entry[i].res_vl, &vl);
648 n += snprintf(buf + n, bufsz - n, "0x%-2X|", vl);
649 if (n >= bufsz)
650 return;
651 }
652
653 n += snprintf(buf + n, bufsz - n, "\nWEIGHT: |");
654 if (n >= bufsz)
655 return;
656 for (i = 0; i < num; i++) {
657 n += snprintf(buf + n, bufsz - n, "0x%-2X|",
658 p_vla_tbl->vl_entry[i].weight);
659 if (n >= bufsz)
660 return;
661 }
662
663 snprintf(buf + n, bufsz - n, "\n");
664 }
665
666 static int
_dump_fields(char * buf,int bufsz,void * data,int start,int end)667 _dump_fields(char *buf, int bufsz, void *data, int start, int end)
668 {
669 char val[64];
670 char *s = buf;
671 int n, field;
672
673 for (field = start; field < end && bufsz > 0; field++) {
674 mad_decode_field(data, field, val);
675 if (!mad_dump_field(field, s, bufsz, val))
676 return -1;
677 n = strlen(s);
678 s += n;
679 *s++ = '\n';
680 *s = 0;
681 n++;
682 bufsz -= n;
683 }
684
685 return s - buf;
686 }
687
688 void
mad_dump_nodedesc(char * buf,int bufsz,void * val,int valsz)689 mad_dump_nodedesc(char *buf, int bufsz, void *val, int valsz)
690 {
691 strncpy(buf, val, bufsz);
692
693 if (valsz < bufsz)
694 buf[valsz] = 0;
695 }
696
697 void
mad_dump_nodeinfo(char * buf,int bufsz,void * val,int valsz)698 mad_dump_nodeinfo(char *buf, int bufsz, void *val, int valsz)
699 {
700 _dump_fields(buf, bufsz, val, IB_NODE_FIRST_F, IB_NODE_LAST_F);
701 }
702
703 void
mad_dump_portinfo(char * buf,int bufsz,void * val,int valsz)704 mad_dump_portinfo(char *buf, int bufsz, void *val, int valsz)
705 {
706 _dump_fields(buf, bufsz, val, IB_PORT_FIRST_F, IB_PORT_LAST_F);
707 }
708
709 void
mad_dump_portstates(char * buf,int bufsz,void * val,int valsz)710 mad_dump_portstates(char *buf, int bufsz, void *val, int valsz)
711 {
712 _dump_fields(buf, bufsz, val, IB_PORT_STATE_F, IB_PORT_LINK_DOWN_DEF_F);
713 }
714
715 void
mad_dump_switchinfo(char * buf,int bufsz,void * val,int valsz)716 mad_dump_switchinfo(char *buf, int bufsz, void *val, int valsz)
717 {
718 _dump_fields(buf, bufsz, val, IB_SW_FIRST_F, IB_SW_LAST_F);
719 }
720
721 void
mad_dump_perfcounters(char * buf,int bufsz,void * val,int valsz)722 mad_dump_perfcounters(char *buf, int bufsz, void *val, int valsz)
723 {
724 _dump_fields(buf, bufsz, val, IB_PC_FIRST_F, IB_PC_LAST_F);
725 }
726
727 void
mad_dump_perfcounters_ext(char * buf,int bufsz,void * val,int valsz)728 mad_dump_perfcounters_ext(char *buf, int bufsz, void *val, int valsz)
729 {
730 _dump_fields(buf, bufsz, val, IB_PC_EXT_FIRST_F, IB_PC_EXT_LAST_F);
731 }
732
733 /************************/
734
735 char *
_mad_dump_val(ib_field_t * f,char * buf,int bufsz,void * val)736 _mad_dump_val(ib_field_t *f, char *buf, int bufsz, void *val)
737 {
738 f->def_dump_fn(buf, bufsz, val, ALIGN(f->bitlen, 8) / 8);
739 buf[bufsz - 1] = 0;
740
741 return buf;
742 }
743
744 char *
_mad_dump_field(ib_field_t * f,char * name,char * buf,int bufsz,void * val)745 _mad_dump_field(ib_field_t *f, char *name, char *buf, int bufsz, void *val)
746 {
747 char dots[128];
748 int l, n;
749
750 if (bufsz <= 32)
751 return 0; /* buf too small */
752
753 if (!name)
754 name = f->name;
755
756 l = strlen(name);
757 if (l < 32) {
758 memset(dots, '.', 32 - l);
759 dots[32 - l] = 0;
760 }
761
762 n = snprintf(buf, bufsz, "%s:%s", name, dots);
763 _mad_dump_val(f, buf + n, bufsz - n, val);
764 buf[bufsz - 1] = 0;
765
766 return buf;
767 }
768
769 int
_mad_dump(ib_mad_dump_fn * fn,char * name,void * val,int valsz)770 _mad_dump(ib_mad_dump_fn *fn, char *name, void *val, int valsz)
771 {
772 ib_field_t f = { .def_dump_fn = fn, .bitlen = valsz * 8};
773 char buf[512];
774
775 return printf("%s\n", _mad_dump_field(&f, name, buf, sizeof buf, val));
776 }
777
778 int
_mad_print_field(ib_field_t * f,char * name,void * val,int valsz)779 _mad_print_field(ib_field_t *f, char *name, void *val, int valsz)
780 {
781 return _mad_dump(f->def_dump_fn, name ? name : f->name, val, valsz ? valsz : ALIGN(f->bitlen, 8) / 8);
782 }
783