1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Sun4v Platform specific functions.
28 *
29 * called when :
30 * machine_type == ontario
31 *
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <kstat.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <assert.h>
41 #include <libintl.h>
42 #include <note.h>
43 #include <sys/systeminfo.h>
44 #include <sys/openpromio.h>
45 #include <sys/sysmacros.h>
46 #include <picl.h>
47 #include "picldefs.h"
48 #include <pdevinfo.h>
49 #include <display.h>
50 #include <display_sun4v.h>
51 #include <libprtdiag.h>
52 #include "ontario.h"
53 #include "erie.h"
54 #include "pelton.h"
55 #include "stpaul.h"
56 #include "huron.h"
57
58 #if !defined(TEXT_DOMAIN)
59 #define TEXT_DOMAIN "SYS_TEST"
60 #endif
61
62 /*
63 * these functions will overlay the symbol table of libprtdiag
64 * at runtime
65 */
66 void sun4v_display_pci(picl_nodehdl_t plafh);
67 void sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh);
68
69
70 /* local functions */
71 static void sun4v_display_hw_revisions(Prom_node *root, picl_nodehdl_t plafh);
72 static int ontario_pci_callback(picl_nodehdl_t pcih, void *args);
73 static int ontario_get_first_compatible_value(picl_nodehdl_t nodeh,
74 char **outbuf);
75 static int64_t ontario_get_int_propval(picl_nodehdl_t modh, char *prop_name,
76 int *ret);
77
78 static void
get_bus_type(char * path,struct io_card * card)79 get_bus_type(char *path, struct io_card *card)
80 {
81 if (strncmp(path, PCIX_SLOT0, PCIX_COMP_NUM) == 0) {
82 (void) strcpy(card->bus_type, "PCIX");
83 } else {
84 (void) strcpy(card->bus_type, "PCIE");
85 }
86 }
87
88 static void
get_slot_number(picl_nodehdl_t nodeh,char * path,struct io_card * card)89 get_slot_number(picl_nodehdl_t nodeh, char *path, struct io_card *card)
90 {
91 if (strncmp(path, PCIE_SLOT0, PCIE_COMP_NUM) == 0) {
92 (void) strcpy(card->slot_str, "0");
93 card->slot = 0;
94 } else if (strncmp(path, PCIE_SLOT1, PCIE_COMP_NUM) == 0) {
95 (void) strcpy(card->slot_str, "1");
96 card->slot = 1;
97 } else if (strncmp(path, PCIE_SLOT2, PCIE_COMP_NUM) == 0) {
98 (void) strcpy(card->slot_str, "2");
99 card->slot = 2;
100 } else if ((strncmp(path, PCIX_SLOT1, strlen(PCIX_SLOT1)) == 0) ||
101 (strncmp(path, PCIX_SLOT0, strlen(PCIX_SLOT0)) == 0)) {
102 char ua[MAXSTRLEN];
103 int err;
104
105 (void) strcpy(card->slot_str, "PCIX");
106 card->slot = -1;
107
108 /*
109 * PCIX_SLOT0 and PCIX_SLOT1 are actually the same path so
110 * use the unit address to distinguish the slot number.
111 */
112 err = picl_get_propval_by_name(nodeh, PICL_PROP_UNIT_ADDRESS,
113 ua, sizeof (ua));
114 if (err == PICL_SUCCESS) {
115 if (ua[0] == '2') {
116 card->slot = 0;
117 (void) strcpy(card->slot_str, "0");
118 } else if (ua[0] == '1') {
119 card->slot = 1;
120 (void) strcpy(card->slot_str, "1");
121 }
122 }
123 } else {
124 (void) strcpy(card->slot_str, IOBOARD);
125 card->slot = -1;
126 }
127 }
128
129 static int
ontario_get_network_instance(char * path)130 ontario_get_network_instance(char *path)
131 {
132 if (strncmp(path, NETWORK_1_PATH, strlen(NETWORK_1_PATH)) == 0) {
133 return (1);
134 } else if (strncmp(path, NETWORK_3_PATH, strlen(NETWORK_3_PATH)) == 0) {
135 return (3);
136 } else if (strncmp(path, NETWORK_0_PATH, strlen(NETWORK_0_PATH)) == 0) {
137 return (0);
138 } else if (strncmp(path, NETWORK_2_PATH, strlen(NETWORK_2_PATH)) == 0) {
139 return (2);
140 } else {
141 return (-1);
142 }
143 }
144 /*
145 * add all io devices under pci in io list
146 */
147 /* ARGSUSED */
148 static int
ontario_pci_callback(picl_nodehdl_t pcih,void * args)149 ontario_pci_callback(picl_nodehdl_t pcih, void *args)
150 {
151 int err = PICL_SUCCESS;
152 picl_nodehdl_t nodeh;
153 char path[MAXSTRLEN];
154 char parent_path[MAXSTRLEN];
155 char piclclass[PICL_CLASSNAMELEN_MAX];
156 char name[MAXSTRLEN];
157 char model[MAXSTRLEN];
158 char *compatible;
159 char binding_name[MAXSTRLEN];
160 struct io_card pci_card;
161 int32_t instance;
162
163 err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, parent_path,
164 sizeof (parent_path));
165 if (err != PICL_SUCCESS) {
166 return (err);
167 }
168
169 /* Walk through the children */
170
171 err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
172 sizeof (picl_nodehdl_t));
173
174 while (err == PICL_SUCCESS) {
175 err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
176 piclclass, sizeof (piclclass));
177 if (err != PICL_SUCCESS)
178 return (err);
179
180 /*
181 * Skip PCI and PCIEX devices because they will be processed
182 * later in the picl tree walk.
183 */
184 if ((strcmp(piclclass, "pci") == 0) ||
185 (strcmp(piclclass, "pciex") == 0)) {
186 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
187 &nodeh, sizeof (picl_nodehdl_t));
188 continue;
189 }
190
191 err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH,
192 path, sizeof (path));
193 if (err != PICL_SUCCESS) {
194 return (err);
195 }
196
197 (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes));
198
199 get_bus_type(parent_path, &pci_card);
200
201 get_slot_number(nodeh, parent_path, &pci_card);
202
203 err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, &name,
204 sizeof (name));
205 if (err == PICL_PROPNOTFOUND)
206 (void) strcpy(name, "");
207 else if (err != PICL_SUCCESS)
208 return (err);
209
210 /* Figure NAC name */
211 if ((strcmp(name, NETWORK) == 0) &&
212 (strcmp(pci_card.slot_str, IOBOARD) == 0)) {
213 instance = ontario_get_network_instance(path);
214
215 (void) snprintf(pci_card.status,
216 sizeof (pci_card.status), "%s/%s%d", IOBOARD,
217 "NET", instance);
218 } else {
219 if (pci_card.slot != -1) {
220 (void) snprintf(pci_card.status,
221 sizeof (pci_card.status), "%s/%s%d",
222 IOBOARD, pci_card.bus_type, pci_card.slot);
223 } else {
224 (void) snprintf(pci_card.status,
225 sizeof (pci_card.status), "%s/%s", IOBOARD,
226 pci_card.bus_type);
227 }
228 }
229
230 /*
231 * Get the name of this card. If binding_name is found,
232 * name will be <nodename>-<binding_name>
233 */
234
235 err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
236 &binding_name, sizeof (binding_name));
237 if (err == PICL_PROPNOTFOUND) {
238 /*
239 * if compatible prop is found, name will be
240 * <nodename>-<compatible>
241 */
242 err = ontario_get_first_compatible_value(nodeh,
243 &compatible);
244 if (err == PICL_SUCCESS) {
245 (void) strlcat(name, "-", MAXSTRLEN);
246 (void) strlcat(name, compatible, MAXSTRLEN);
247 free(compatible);
248 } else if (err != PICL_PROPNOTFOUND) {
249 return (err);
250 }
251 } else if (err != PICL_SUCCESS) {
252 return (err);
253 } else if (strcmp(name, binding_name) != 0) {
254 (void) strlcat(name, "-", MAXSTRLEN);
255 (void) strlcat(name, binding_name, MAXSTRLEN);
256 }
257
258 (void) strlcpy(pci_card.name, name, sizeof (pci_card.name));
259
260 /* Get the model of this card */
261
262 err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL,
263 &model, sizeof (model));
264 if (err == PICL_PROPNOTFOUND)
265 (void) strcpy(model, "");
266 else if (err != PICL_SUCCESS)
267 return (err);
268 (void) strlcpy(pci_card.model, model, sizeof (pci_card.model));
269
270 /* Print NAC name */
271 log_printf("%-11s", pci_card.status);
272 /* Print IO Type */
273 log_printf("%6s", pci_card.bus_type);
274 /* Print Slot # */
275 log_printf("%5s", pci_card.slot_str);
276 /* Print Parent Path */
277 log_printf("%46.45s", pci_card.notes);
278 /* Printf Card Name */
279 if (strlen(pci_card.name) > 25)
280 log_printf("%25.24s+", pci_card.name);
281 else
282 log_printf("%26s", pci_card.name);
283 /* Print Card Model */
284 if (strlen(pci_card.model) > 10)
285 log_printf("%10.9s+", pci_card.model);
286 else
287 log_printf("%11s", pci_card.model);
288 log_printf("\n");
289
290 err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
291 sizeof (picl_nodehdl_t));
292
293 }
294
295 return (PICL_WALK_CONTINUE);
296 }
297 /*
298 * display_pci
299 * Display all the PCI IO cards on this board.
300 */
301 void
sun4v_display_pci(picl_nodehdl_t plafh)302 sun4v_display_pci(picl_nodehdl_t plafh)
303 {
304 char platbuf[MAXSTRLEN];
305 char *fmt = "%-11s %-5s %-4s %-45s %-25s %-10s";
306 static int banner = FALSE; /* Have we printed the column headings? */
307
308 if (banner == FALSE) {
309 log_printf("\n", 0);
310 log_printf("=========================", 0);
311 log_printf(dgettext(TEXT_DOMAIN, " IO Configuration "), 0);
312 log_printf("=========================", 0);
313 log_printf("\n", 0);
314 log_printf("\n", 0);
315 log_printf(fmt, "", "IO", "", "", "", "", 0);
316 log_printf("\n", 0);
317 log_printf(fmt, "Location", "Type", "Slot", "Path",
318 "Name", "Model", 0);
319 log_printf("\n");
320 log_printf(fmt, "-----------", "-----", "----",
321 "---------------------------------------------",
322 "-------------------------", "----------", 0);
323 log_printf("\n");
324 banner = TRUE;
325 }
326
327 /* Get platform name, if that fails, use ontario name by default */
328 if (sysinfo(SI_PLATFORM, platbuf, sizeof (platbuf)) == -1) {
329 (void) strcpy(platbuf, ONTARIO_PLATFORM);
330 }
331
332 /*
333 * Call functions based on appropriate platform
334 */
335 if ((strncmp(platbuf, ONTARIO_PLATFORM,
336 strlen(ONTARIO_PLATFORM)) == 0) ||
337 (strncmp(platbuf, ONTARIO_PLATFORM2,
338 strlen(ONTARIO_PLATFORM2)) == 0)) {
339 (void) picl_walk_tree_by_class(plafh, "pciex",
340 "pciex", ontario_pci_callback);
341 (void) picl_walk_tree_by_class(plafh, "pci",
342 "pci", ontario_pci_callback);
343 } else if ((strncmp(platbuf, PELTON_PLATFORM,
344 strlen(PELTON_PLATFORM))) == 0) {
345 (void) picl_walk_tree_by_class(plafh, "pciex",
346 "pciex", pelton_pci_callback);
347 (void) picl_walk_tree_by_class(plafh, "pci",
348 "pci", pelton_pci_callback);
349 } else if ((strncmp(platbuf, STPAUL_PLATFORM,
350 strlen(STPAUL_PLATFORM))) == 0) {
351 (void) picl_walk_tree_by_class(plafh, "pciex",
352 "pciex", stpaul_pci_callback);
353 } else if ((strncmp(platbuf, HURON_1U_PLATFORM,
354 strlen(HURON_1U_PLATFORM)) == 0) || (strncmp(platbuf,
355 HURON_2U_PLATFORM, strlen(HURON_2U_PLATFORM)) == 0)) {
356 (void) picl_walk_tree_by_class(plafh, "sun4v",
357 "niu", huron_pci_callback);
358 (void) picl_walk_tree_by_class(plafh, "pciex",
359 "pciex", huron_pci_callback);
360 } else {
361 (void) picl_walk_tree_by_class(plafh, "pciex", "pciex",
362 erie_pci_callback);
363 (void) picl_walk_tree_by_class(plafh, "pci", "pci",
364 erie_pci_callback);
365 }
366 }
367
368 /*
369 * ----------------------------------------------------------------------------
370 */
371
372 /* ARGSUSED */
373 void
sun4v_display_diaginfo(int flag,Prom_node * root,picl_nodehdl_t plafh)374 sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh)
375 {
376 /* NOTE(ARGUNUSED(kstats)) */
377 /*
378 * Now display the last powerfail time and the fatal hardware
379 * reset information. We do this under a couple of conditions.
380 * First if the user asks for it. The second is if the user
381 * told us to do logging, and we found a system failure.
382 */
383 if (flag) {
384 /*
385 * display time of latest powerfail. Not all systems
386 * have this capability. For those that do not, this
387 * is just a no-op.
388 */
389 disp_powerfail(root);
390
391 /* platform_disp_prom_version(tree); */
392 sun4v_display_hw_revisions(root, plafh);
393 }
394 }
395
396 /*
397 * local functions
398 */
399 /*
400 * add all io devices under pci in io list
401 */
402 /* ARGSUSED */
403 static int
ontario_hw_rev_callback(picl_nodehdl_t pcih,void * args)404 ontario_hw_rev_callback(picl_nodehdl_t pcih, void *args)
405 {
406 int err = PICL_SUCCESS;
407 char path[MAXSTRLEN] = "";
408 char device_path[MAXSTRLEN];
409 char NAC[MAXSTRLEN];
410 char *compatible;
411 int32_t revision;
412 int device_found;
413
414 device_found = 0;
415
416 err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, path,
417 sizeof (path));
418 if (err != PICL_SUCCESS) {
419 return (err);
420 }
421
422 if ((strcmp(path, NETWORK_0_PATH) == 0) ||
423 (strcmp(path, NETWORK_1_PATH) == 0)) {
424 device_found = 1;
425 (void) snprintf(NAC, sizeof (NAC), "%s/%s%d", IOBOARD, OPHIR,
426 0);
427 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
428 &err);
429 }
430
431 if ((strcmp(path, NETWORK_2_PATH) == 0) ||
432 (strcmp(path, NETWORK_3_PATH) == 0)) {
433 device_found = 1;
434 (void) snprintf(NAC, sizeof (NAC), "%s/%s%d", IOBOARD, OPHIR,
435 1);
436 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
437 &err);
438 }
439
440 if ((strcmp(path, FIRE_PATH0) == 0) ||
441 (strcmp(path, FIRE_PATH1) == 0)) {
442 device_found = 1;
443 (void) snprintf(NAC, sizeof (NAC), "%s/%s", IOBOARD,
444 "IO-BRIDGE");
445 revision = ontario_get_int_propval(pcih, OBP_PROP_VERSION_NUM,
446 &err);
447 }
448
449 if ((strcmp(path, PCIX_SLOT0) == 0) ||
450 (strcmp(path, PCIX_SLOT1) == 0)) {
451 device_found = 1;
452 (void) snprintf(NAC, sizeof (NAC), "%s/%s", IOBOARD,
453 PCI_BRIDGE);
454 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
455 &err);
456 }
457
458 if (strcmp(path, SWITCH_A_PATH) == 0) {
459 device_found = 1;
460 (void) snprintf(NAC, sizeof (NAC), "%s/%s", IOBOARD, SWITCH_A);
461 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
462 &err);
463 }
464
465 if (strcmp(path, SWITCH_B_PATH) == 0) {
466 device_found = 1;
467 (void) snprintf(NAC, sizeof (NAC), "%s/%s", IOBOARD, SWITCH_B);
468 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
469 &err);
470 }
471
472 if (strcmp(path, ONT_LSI_PATH) == 0) {
473 device_found = 1;
474 (void) snprintf(NAC, sizeof (NAC), "%s/%s", IOBOARD,
475 SAS_SATA_HBA);
476 revision = ontario_get_int_propval(pcih, OBP_PROP_REVISION_ID,
477 &err);
478 }
479 if (device_found == 1) {
480 (void) strcpy(device_path, path);
481 err = ontario_get_first_compatible_value(pcih, &compatible);
482
483 /* Print NAC name */
484 log_printf("%-20s", NAC);
485 /* Print Device Path */
486 if (strlen(device_path) > 38)
487 log_printf("%38.37s+", device_path);
488 else
489 log_printf("%39s", device_path);
490 /* Print Compatible # */
491 if (err == PICL_SUCCESS) {
492 log_printf("%31s", compatible);
493 free(compatible);
494 } else
495 log_printf("%31s", " ");
496 /* Print Revision */
497 log_printf("%6d", revision);
498 log_printf("\n");
499 }
500
501 return (PICL_WALK_CONTINUE);
502 }
503
504 /*ARGSUSED*/
505 static void
sun4v_display_hw_revisions(Prom_node * root,picl_nodehdl_t plafh)506 sun4v_display_hw_revisions(Prom_node *root, picl_nodehdl_t plafh)
507 {
508 Prom_node *pnode;
509 char *value;
510 char platbuf[MAXSTRLEN];
511 char *fmt = "%-20s %-45s %-30s %-9s";
512
513 log_printf(dgettext(TEXT_DOMAIN, "\n"
514 "========================= HW Revisions "
515 "=======================================\n\n"));
516
517 log_printf(dgettext(TEXT_DOMAIN,
518 "System PROM revisions:\n"
519 "----------------------\n"));
520
521 pnode = dev_find_node(root, "openprom");
522 if (pnode != NULL) {
523 value = (char *)get_prop_val(find_prop(pnode, "version"));
524 log_printf(value);
525 }
526
527 log_printf(dgettext(TEXT_DOMAIN, "\n\n"
528 "IO ASIC revisions:\n"
529 "------------------\n"));
530 log_printf(fmt, "Location", "Path", "Device", "Revision\n", 0);
531 log_printf(fmt, "--------------------",
532 "---------------------------------------------",
533 "------------------------------",
534 "---------\n", 0);
535
536 /* Get platform name, if that fails, use ontario name by default */
537 if (sysinfo(SI_PLATFORM, platbuf, sizeof (platbuf)) == -1) {
538 (void) strcpy(platbuf, ONTARIO_PLATFORM);
539 }
540
541 /*
542 * Walk tree based on platform
543 */
544 if ((strncmp(platbuf, ONTARIO_PLATFORM,
545 strlen(ONTARIO_PLATFORM))) == 0) {
546 (void) picl_walk_tree_by_class(plafh, "pciex",
547 "pciex", ontario_hw_rev_callback);
548 (void) picl_walk_tree_by_class(plafh, "pci",
549 "pci", ontario_hw_rev_callback);
550 (void) picl_walk_tree_by_class(plafh, "network",
551 "network", ontario_hw_rev_callback);
552 (void) picl_walk_tree_by_class(plafh, "scsi-2", "scsi-2",
553 ontario_hw_rev_callback);
554 } else if ((strncmp(platbuf, PELTON_PLATFORM,
555 strlen(PELTON_PLATFORM))) == 0) {
556 (void) picl_walk_tree_by_class(plafh, "pciex",
557 "pciex", pelton_hw_rev_callback);
558 (void) picl_walk_tree_by_class(plafh, "pci",
559 "pci", pelton_hw_rev_callback);
560 (void) picl_walk_tree_by_class(plafh, "network",
561 "network", pelton_hw_rev_callback);
562 (void) picl_walk_tree_by_class(plafh, "scsi-2", "scsi-2",
563 pelton_hw_rev_callback);
564 } else if ((strncmp(platbuf, STPAUL_PLATFORM,
565 strlen(STPAUL_PLATFORM))) == 0) {
566 (void) picl_walk_tree_by_class(plafh, "pciex",
567 "pciex", stpaul_hw_rev_callback);
568 (void) picl_walk_tree_by_class(plafh, "pci",
569 "pci", stpaul_hw_rev_callback);
570 (void) picl_walk_tree_by_class(plafh, "network",
571 "network", stpaul_hw_rev_callback);
572 (void) picl_walk_tree_by_class(plafh, "scsi-2", "scsi-2",
573 stpaul_hw_rev_callback);
574 } else if ((strncmp(platbuf, HURON_1U_PLATFORM,
575 strlen(HURON_1U_PLATFORM)) == 0) || (strncmp(platbuf,
576 HURON_2U_PLATFORM, strlen(HURON_2U_PLATFORM)) == 0)) {
577 (void) picl_walk_tree_by_class(plafh, "pciex",
578 "pciex", huron_hw_rev_callback);
579 (void) picl_walk_tree_by_class(plafh, "sun4v",
580 "niu", huron_hw_rev_callback);
581 (void) picl_walk_tree_by_class(plafh, "network",
582 "network", huron_hw_rev_callback);
583 (void) picl_walk_tree_by_class(plafh, "scsi-2", "scsi-2",
584 huron_hw_rev_callback);
585 } else {
586 (void) picl_walk_tree_by_class(plafh, "pciex", "pciex",
587 erie_hw_rev_callback);
588 (void) picl_walk_tree_by_class(plafh, "pci", "pci",
589 erie_hw_rev_callback);
590 (void) picl_walk_tree_by_class(plafh, "network", "network",
591 erie_hw_rev_callback);
592 (void) picl_walk_tree_by_class(plafh, "scsi-2", "scsi-2",
593 erie_hw_rev_callback);
594 }
595 }
596
597 /*
598 * return the first compatible value
599 */
600 static int
ontario_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)601 ontario_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
602 {
603 int err;
604 picl_prophdl_t proph;
605 picl_propinfo_t pinfo;
606 picl_prophdl_t tblh;
607 picl_prophdl_t rowproph;
608 char *pval;
609
610 err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
611 &pinfo, &proph);
612 if (err != PICL_SUCCESS)
613 return (err);
614
615 if (pinfo.type == PICL_PTYPE_CHARSTRING) {
616 pval = malloc(pinfo.size);
617 if (pval == NULL)
618 return (PICL_FAILURE);
619 err = picl_get_propval(proph, pval, pinfo.size);
620 if (err != PICL_SUCCESS) {
621 free(pval);
622 return (err);
623 }
624 *outbuf = pval;
625 return (PICL_SUCCESS);
626 }
627
628 if (pinfo.type != PICL_PTYPE_TABLE)
629 return (PICL_FAILURE);
630
631 /* get first string from table */
632 err = picl_get_propval(proph, &tblh, pinfo.size);
633 if (err != PICL_SUCCESS)
634 return (err);
635
636 err = picl_get_next_by_row(tblh, &rowproph);
637 if (err != PICL_SUCCESS)
638 return (err);
639
640 err = picl_get_propinfo(rowproph, &pinfo);
641 if (err != PICL_SUCCESS)
642 return (err);
643
644 pval = malloc(pinfo.size);
645 if (pval == NULL)
646 return (PICL_FAILURE);
647
648 err = picl_get_propval(rowproph, pval, pinfo.size);
649 if (err != PICL_SUCCESS) {
650 free(pval);
651 return (err);
652 }
653
654 *outbuf = pval;
655 return (PICL_SUCCESS);
656 }
657
658 static int64_t
ontario_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)659 ontario_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
660 {
661 int err;
662 picl_prophdl_t proph;
663 picl_propinfo_t pinfo;
664 int8_t int8v;
665 int16_t int16v;
666 int32_t int32v;
667 int64_t int64v;
668
669 err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
670 if (err != PICL_SUCCESS) {
671 *ret = err;
672 return (0);
673 }
674
675 /*
676 * If it is not an int, uint or byte array prop, return failure
677 */
678 if ((pinfo.type != PICL_PTYPE_INT) &&
679 (pinfo.type != PICL_PTYPE_UNSIGNED_INT) &&
680 (pinfo.type != PICL_PTYPE_BYTEARRAY)) {
681 *ret = PICL_FAILURE;
682 return (0);
683 }
684
685 switch (pinfo.size) {
686 case sizeof (int8_t):
687 err = picl_get_propval(proph, &int8v, sizeof (int8v));
688 *ret = err;
689 return (int8v);
690 case sizeof (int16_t):
691 err = picl_get_propval(proph, &int16v, sizeof (int16v));
692 *ret = err;
693 return (int16v);
694 case sizeof (int32_t):
695 err = picl_get_propval(proph, &int32v, sizeof (int32v));
696 *ret = err;
697 return (int32v);
698 case sizeof (int64_t):
699 err = picl_get_propval(proph, &int64v, sizeof (int64v));
700 *ret = err;
701 return (int64v);
702 default: /* not supported size */
703 *ret = PICL_FAILURE;
704 return (0);
705 }
706 }
707