]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/libibmad/src/dump.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / management / libibmad / src / dump.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
613 ib_vl_arb_get_vl(uint8_t res_vl, uint8_t *const vl )
614 {
615         *vl = res_vl & 0x0F;
616 }
617
618 void
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
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
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
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
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
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
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
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
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
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 *
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 *
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
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
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 }