19ef7884dSanovick /*
29ef7884dSanovick  * CDDL HEADER START
39ef7884dSanovick  *
49ef7884dSanovick  * The contents of this file are subject to the terms of the
59ef7884dSanovick  * Common Development and Distribution License (the "License").
69ef7884dSanovick  * You may not use this file except in compliance with the License.
79ef7884dSanovick  *
89ef7884dSanovick  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ef7884dSanovick  * or http://www.opensolaris.org/os/licensing.
109ef7884dSanovick  * See the License for the specific language governing permissions
119ef7884dSanovick  * and limitations under the License.
129ef7884dSanovick  *
139ef7884dSanovick  * When distributing Covered Code, include this CDDL HEADER in each
149ef7884dSanovick  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159ef7884dSanovick  * If applicable, add the following below this CDDL HEADER, with the
169ef7884dSanovick  * fields enclosed by brackets "[]" replaced with your own identifying
179ef7884dSanovick  * information: Portions Copyright [yyyy] [name of copyright owner]
189ef7884dSanovick  *
199ef7884dSanovick  * CDDL HEADER END
209ef7884dSanovick  */
219ef7884dSanovick 
229ef7884dSanovick /*
23*087113e1Smb  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
249ef7884dSanovick  * Use is subject to license terms.
259ef7884dSanovick  */
269ef7884dSanovick 
279ef7884dSanovick /*
289ef7884dSanovick  * Sun4v Platform specific functions.
299ef7884dSanovick  *
309ef7884dSanovick  * 	called when :
319ef7884dSanovick  *      machine_type ==  StPaul
329ef7884dSanovick  *
339ef7884dSanovick  */
349ef7884dSanovick 
359ef7884dSanovick #include <stdio.h>
369ef7884dSanovick #include <stdlib.h>
379ef7884dSanovick #include <unistd.h>
389ef7884dSanovick #include <kstat.h>
399ef7884dSanovick #include <fcntl.h>
409ef7884dSanovick #include <string.h>
419ef7884dSanovick #include <assert.h>
429ef7884dSanovick #include <libintl.h>
439ef7884dSanovick #include <note.h>
449ef7884dSanovick #include <sys/systeminfo.h>
459ef7884dSanovick #include <sys/openpromio.h>
469ef7884dSanovick #include <sys/sysmacros.h>
479ef7884dSanovick #include <picl.h>
489ef7884dSanovick #include "picldefs.h"
499ef7884dSanovick #include <pdevinfo.h>
509ef7884dSanovick #include <display.h>
519ef7884dSanovick #include <display_sun4v.h>
529ef7884dSanovick #include <libprtdiag.h>
539ef7884dSanovick #include "stpaul.h"
549ef7884dSanovick 
559ef7884dSanovick /* prototypes for local functions */
569ef7884dSanovick static void get_bus_type(char *path, struct io_card *card);
579ef7884dSanovick static void get_slot_number(char *path, struct io_card *card);
589ef7884dSanovick static int stpaul_get_network_instance(char *path);
595b20c9b9Sanovick static int stpaul_get_usb_instance(char *path);
605b20c9b9Sanovick static int stpaul_get_io_instance(char *path, char *type);
619ef7884dSanovick static int stpaul_get_first_compatible_value(picl_nodehdl_t nodeh,
629ef7884dSanovick     char **outbuf);
639ef7884dSanovick static int64_t stpaul_get_int_propval(picl_nodehdl_t modh, char *prop_name,
649ef7884dSanovick     int *ret);
659ef7884dSanovick 
669ef7884dSanovick /* ARGSUSED */
679ef7884dSanovick int
stpaul_pci_callback(picl_nodehdl_t pcih,void * args)689ef7884dSanovick stpaul_pci_callback(picl_nodehdl_t pcih, void *args)
699ef7884dSanovick {
709ef7884dSanovick 	int		err = PICL_SUCCESS;
719ef7884dSanovick 	picl_nodehdl_t	nodeh;
729ef7884dSanovick 	char		path[MAXSTRLEN];
739ef7884dSanovick 	char		parent_path[MAXSTRLEN];
749ef7884dSanovick 	char		piclclass[PICL_CLASSNAMELEN_MAX];
759ef7884dSanovick 	char		name[MAXSTRLEN];
769ef7884dSanovick 	char		model[MAXSTRLEN];
779ef7884dSanovick 	char		*compatible;
789ef7884dSanovick 	char		binding_name[MAXSTRLEN];
799ef7884dSanovick 	struct io_card	pci_card;
809ef7884dSanovick 	int32_t		instance;
815b20c9b9Sanovick 	char		pn_type;
829ef7884dSanovick 
839ef7884dSanovick 	err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, parent_path,
849ef7884dSanovick 	    sizeof (parent_path));
859ef7884dSanovick 	if (err != PICL_SUCCESS)
869ef7884dSanovick 		return (err);
879ef7884dSanovick 
889ef7884dSanovick 	/* Walk through the children */
899ef7884dSanovick 
909ef7884dSanovick 	err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
919ef7884dSanovick 	    sizeof (picl_nodehdl_t));
929ef7884dSanovick 
939ef7884dSanovick 	while (err == PICL_SUCCESS) {
949ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
959ef7884dSanovick 		    piclclass, sizeof (piclclass));
969ef7884dSanovick 		if (err !=  PICL_SUCCESS)
979ef7884dSanovick 			return (err);
989ef7884dSanovick 
995b20c9b9Sanovick 		if (strcmp(piclclass, PICL_CLASS_PCIEX) == 0) {
1009ef7884dSanovick 			err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
1019ef7884dSanovick 			    &nodeh, sizeof (picl_nodehdl_t));
1029ef7884dSanovick 			continue;
1039ef7884dSanovick 		}
1049ef7884dSanovick 
1059ef7884dSanovick 		if (strcmp(piclclass, PICL_CLASS_PCI) == 0) {
1069ef7884dSanovick 			err = picl_get_propval_by_name(nodeh, PICL_PROP_CHILD,
1079ef7884dSanovick 			    &nodeh, sizeof (picl_nodehdl_t));
1089ef7884dSanovick 			continue;
1099ef7884dSanovick 		}
1109ef7884dSanovick 
1119ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH,
1129ef7884dSanovick 		    path, sizeof (path));
1139ef7884dSanovick 		if (err != PICL_SUCCESS)
1149ef7884dSanovick 			return (err);
1159ef7884dSanovick 
1169ef7884dSanovick 		(void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes));
1179ef7884dSanovick 
1185b20c9b9Sanovick 		get_bus_type(path, &pci_card);
1199ef7884dSanovick 
1205b20c9b9Sanovick 		get_slot_number(path, &pci_card);
1219ef7884dSanovick 
1229ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, &name,
1239ef7884dSanovick 		    sizeof (name));
1249ef7884dSanovick 		if (err == PICL_PROPNOTFOUND)
1255b20c9b9Sanovick 			(void) strlcpy(name, "", sizeof (name));
1269ef7884dSanovick 		else if (err != PICL_SUCCESS)
1279ef7884dSanovick 			return (err);
1289ef7884dSanovick 
1299ef7884dSanovick 		/* Figure NAC name */
1309ef7884dSanovick 		if ((strcmp(name, NETWORK) == 0) &&
1319ef7884dSanovick 		    (strcmp(pci_card.slot_str, MOTHERBOARD) == 0)) {
1329ef7884dSanovick 			instance = stpaul_get_network_instance(path);
1335b20c9b9Sanovick 			(void) snprintf(pci_card.status,
1345b20c9b9Sanovick 			    sizeof (pci_card.status), "%s/%s%d",
1355b20c9b9Sanovick 			    MOTHERBOARD, "NET", instance);
1369ef7884dSanovick 
1375b20c9b9Sanovick 
1385b20c9b9Sanovick 		} else if ((strcmp(name, SCSI) == 0) &&
1395b20c9b9Sanovick 		    (strcmp(pci_card.slot_str, MOTHERBOARD) == 0)) {
1409ef7884dSanovick 			(void) snprintf(pci_card.status,
1415b20c9b9Sanovick 			    sizeof (pci_card.status), "%s/%s",
1425b20c9b9Sanovick 			    MOTHERBOARD, SPL_SCSI_TAG);
1435b20c9b9Sanovick 
1449ef7884dSanovick 		} else {
1459ef7884dSanovick 			if (pci_card.slot != -1) {
1469ef7884dSanovick 				(void) snprintf(pci_card.status,
1479ef7884dSanovick 				    sizeof (pci_card.status), "%s/%s%d",
1489ef7884dSanovick 				    MOTHERBOARD, pci_card.bus_type,
1499ef7884dSanovick 				    pci_card.slot);
1509ef7884dSanovick 			} else {
1519ef7884dSanovick 				(void) snprintf(pci_card.status,
1529ef7884dSanovick 				    sizeof (pci_card.status), "%s/%s",
1539ef7884dSanovick 				    MOTHERBOARD, pci_card.bus_type);
1549ef7884dSanovick 			}
1559ef7884dSanovick 		}
1569ef7884dSanovick 
1575b20c9b9Sanovick 		/* Special case for USB */
1585b20c9b9Sanovick 		if (strncmp(name, USB, strlen(USB)) == 0) {
1595b20c9b9Sanovick 			instance = stpaul_get_usb_instance(path);
1605b20c9b9Sanovick 			if (instance != -1)
1615b20c9b9Sanovick 				(void) snprintf(pci_card.status,
1625b20c9b9Sanovick 				    sizeof (pci_card.status), "%s/%s%d",
1635b20c9b9Sanovick 				    MOTHERBOARD, "USB", instance);
1645b20c9b9Sanovick 		}
1655b20c9b9Sanovick 
1665b20c9b9Sanovick 		/* PEM/NEM case is handled here */
1675b20c9b9Sanovick 		if ((instance = stpaul_get_io_instance(path, &pn_type)) != -1) {
1685b20c9b9Sanovick 			if (pn_type == SPL_PEM_TYPE)
1695b20c9b9Sanovick 				(void) snprintf(pci_card.status,
1705b20c9b9Sanovick 				    sizeof (pci_card.status), "%s/%s%d",
171870ec092Sanovick 				    MOTHERBOARD, "PCI-EM", instance);
1725b20c9b9Sanovick 			else if (pn_type == SPL_NEM_TYPE)
1735b20c9b9Sanovick 				(void) snprintf(pci_card.status,
1745b20c9b9Sanovick 				    sizeof (pci_card.status), "%s/%s%d",
1755b20c9b9Sanovick 				    MOTHERBOARD, "NEM", instance);
1765b20c9b9Sanovick 		}
1779ef7884dSanovick 		/*
1789ef7884dSanovick 		 * Get the name of this card. If binding_name is found,
1799ef7884dSanovick 		 * name will be <nodename>-<binding_name>
1809ef7884dSanovick 		 */
1819ef7884dSanovick 
1829ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
1839ef7884dSanovick 		    &binding_name, sizeof (binding_name));
1849ef7884dSanovick 		if (err == PICL_PROPNOTFOUND) {
1859ef7884dSanovick 			/*
1869ef7884dSanovick 			 * if compatible prop is found, name will be
1879ef7884dSanovick 			 * <nodename>-<compatible>
1889ef7884dSanovick 			 */
1899ef7884dSanovick 			err = stpaul_get_first_compatible_value(nodeh,
1909ef7884dSanovick 			    &compatible);
1919ef7884dSanovick 			if (err == PICL_SUCCESS) {
1929ef7884dSanovick 				(void) strlcat(name, "-", MAXSTRLEN);
1939ef7884dSanovick 				(void) strlcat(name, compatible, MAXSTRLEN);
1949ef7884dSanovick 				free(compatible);
1959ef7884dSanovick 			} else if (err != PICL_PROPNOTFOUND)
1969ef7884dSanovick 				return (err);
1979ef7884dSanovick 		} else if (err != PICL_SUCCESS)
1989ef7884dSanovick 			return (err);
1999ef7884dSanovick 		else if (strcmp(name, binding_name) != 0) {
2009ef7884dSanovick 			(void) strlcat(name, "-", MAXSTRLEN);
2019ef7884dSanovick 			(void) strlcat(name, binding_name, MAXSTRLEN);
2029ef7884dSanovick 		}
2039ef7884dSanovick 
2049ef7884dSanovick 		(void) strlcpy(pci_card.name, name, sizeof (pci_card.name));
2059ef7884dSanovick 
2069ef7884dSanovick 		/* Get the model of this card */
2079ef7884dSanovick 
2089ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL,
2099ef7884dSanovick 		    &model, sizeof (model));
2109ef7884dSanovick 		if (err == PICL_PROPNOTFOUND)
2115b20c9b9Sanovick 			(void) strlcpy(model, "", sizeof (model));
2129ef7884dSanovick 		else if (err != PICL_SUCCESS)
2139ef7884dSanovick 			return (err);
2149ef7884dSanovick 		(void) strlcpy(pci_card.model, model, sizeof (pci_card.model));
2159ef7884dSanovick 
2169ef7884dSanovick 		/* Print NAC name */
2179ef7884dSanovick 		log_printf("%-11s", pci_card.status);
2189ef7884dSanovick 		/* Print IO Type */
2199ef7884dSanovick 		log_printf("%6s", pci_card.bus_type);
2209ef7884dSanovick 		/* Print Slot # */
2219ef7884dSanovick 		log_printf("%5s", pci_card.slot_str);
2229ef7884dSanovick 		/* Print Parent Path */
2239ef7884dSanovick 		log_printf("%46.45s", pci_card.notes);
2249ef7884dSanovick 		/* Printf Card Name */
2259ef7884dSanovick 		if (strlen(pci_card.name) > 24)
2269ef7884dSanovick 			log_printf("%25.24s+", pci_card.name);
2279ef7884dSanovick 		else
2289ef7884dSanovick 			log_printf("%26s", pci_card.name);
2299ef7884dSanovick 		/* Print Card Model */
2309ef7884dSanovick 		if (strlen(pci_card.model) > 10)
2319ef7884dSanovick 			log_printf("%10.9s+", pci_card.model);
2329ef7884dSanovick 		else
2339ef7884dSanovick 			log_printf("%10s", pci_card.model);
2349ef7884dSanovick 		log_printf("\n");
2359ef7884dSanovick 
2369ef7884dSanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
2379ef7884dSanovick 		    sizeof (picl_nodehdl_t));
2389ef7884dSanovick 
2399ef7884dSanovick 	}
2409ef7884dSanovick 
2419ef7884dSanovick 	return (PICL_WALK_CONTINUE);
2429ef7884dSanovick }
2439ef7884dSanovick 
2449ef7884dSanovick /* ARGSUSED */
2459ef7884dSanovick int
stpaul_hw_rev_callback(picl_nodehdl_t pcih,void * args)2469ef7884dSanovick stpaul_hw_rev_callback(picl_nodehdl_t pcih, void *args)
2479ef7884dSanovick {
2489ef7884dSanovick 	int		err = PICL_SUCCESS;
2495b20c9b9Sanovick 	char		path[MAXSTRLEN];
2509ef7884dSanovick 	char		device_path[MAXSTRLEN];
2519ef7884dSanovick 	char		NAC[MAXSTRLEN];
2529ef7884dSanovick 	char		*compatible;
2539ef7884dSanovick 	int32_t		revision;
2549ef7884dSanovick 	int		device_found = 0;
2555b20c9b9Sanovick 	char		name[MAXSTRLEN];
2565b20c9b9Sanovick 	picl_nodehdl_t	nodeh;
2579ef7884dSanovick 
2589ef7884dSanovick 	err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, path,
2599ef7884dSanovick 	    sizeof (path));
2609ef7884dSanovick 	if (err != PICL_SUCCESS)
2619ef7884dSanovick 		return (err);
2629ef7884dSanovick 
2635b20c9b9Sanovick 	/* usb is special as a child of PCIE2PCI bridge */
2645b20c9b9Sanovick 	if (strcmp(path, SPL_PCIE2PCI) == 0) {
2655b20c9b9Sanovick 		err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
2665b20c9b9Sanovick 		    sizeof (picl_nodehdl_t));
2675b20c9b9Sanovick 		if (err != PICL_SUCCESS)
2685b20c9b9Sanovick 			return (err);
2695b20c9b9Sanovick 		err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, &name,
2705b20c9b9Sanovick 		    sizeof (name));
2715b20c9b9Sanovick 		if (err != PICL_SUCCESS)
2725b20c9b9Sanovick 			return (err);
2735b20c9b9Sanovick 		if (strcmp(name, USB) == 0) {
2745b20c9b9Sanovick 			err = stpaul_hw_rev_callback(nodeh, &nodeh);
2755b20c9b9Sanovick 			if (err != PICL_SUCCESS)
2765b20c9b9Sanovick 				return (err);
2775b20c9b9Sanovick 		}
2785b20c9b9Sanovick 	}
2795b20c9b9Sanovick 
2809ef7884dSanovick 	if ((strcmp(path, SPL_NETWORK_0_PATH) == 0) ||
2819ef7884dSanovick 	    (strcmp(path, SPL_NETWORK_1_PATH) == 0)) {
2829ef7884dSanovick 		device_found = 1;
2839ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s%d", MOTHERBOARD,
2849ef7884dSanovick 		    OPHIR, 0);
2859ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
2869ef7884dSanovick 		    &err);
2879ef7884dSanovick 	}
2889ef7884dSanovick 
2895b20c9b9Sanovick 	if ((strcmp(path, SPL_USB0_PATH) == 0) ||
2905b20c9b9Sanovick 	    (strcmp(path, SPL_USB1_PATH) == 0) ||
2915b20c9b9Sanovick 	    (strcmp(path, SPL_USB2_PATH) == 0)) {
2929ef7884dSanovick 		device_found = 1;
2939ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s%d", MOTHERBOARD,
2945b20c9b9Sanovick 		    USB_TAG, 0);
2959ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
2969ef7884dSanovick 		    &err);
2979ef7884dSanovick 	}
2989ef7884dSanovick 
2999ef7884dSanovick 	if ((strcmp(path, FIRE_PATH0) == 0) ||
3009ef7884dSanovick 	    (strcmp(path, FIRE_PATH1) == 0)) {
3019ef7884dSanovick 		device_found = 1;
3029ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
3039ef7884dSanovick 		    "IO-BRIDGE");
3049ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_VERSION_NUM,
3059ef7884dSanovick 		    &err);
3069ef7884dSanovick 	}
3079ef7884dSanovick 
3089ef7884dSanovick 	if (strcmp(path, SWITCH_A_PATH) == 0) {
3099ef7884dSanovick 		device_found = 1;
3109ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
3119ef7884dSanovick 		    SWITCH_A);
3129ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
3139ef7884dSanovick 		    &err);
3149ef7884dSanovick 	}
3159ef7884dSanovick 
3169ef7884dSanovick 	if (strcmp(path, SWITCH_B_PATH) == 0) {
3179ef7884dSanovick 		device_found = 1;
3189ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
3199ef7884dSanovick 		    SWITCH_B);
3209ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
3219ef7884dSanovick 		    &err);
3229ef7884dSanovick 	}
3239ef7884dSanovick 
3249ef7884dSanovick 	if (strcmp(path, SPL_LSI_PATH) == 0) {
3259ef7884dSanovick 		device_found = 1;
3269ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
3279ef7884dSanovick 		    SPL_SAS_HBA);
3289ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
3299ef7884dSanovick 		    &err);
3309ef7884dSanovick 	}
3319ef7884dSanovick 
3329ef7884dSanovick 	if (strcmp(path, SPL_PCIE2PCI) == 0) {
3339ef7884dSanovick 		device_found = 1;
3349ef7884dSanovick 		(void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
3359ef7884dSanovick 		    PCI_BRIDGE);
3369ef7884dSanovick 		revision = stpaul_get_int_propval(pcih, OBP_PROP_REVISION_ID,
3379ef7884dSanovick 		    &err);
3389ef7884dSanovick 	}
3399ef7884dSanovick 
3409ef7884dSanovick 	if (device_found == 1) {
3419ef7884dSanovick 
3425b20c9b9Sanovick 		(void) strlcpy(device_path, path, sizeof (device_path));
3439ef7884dSanovick 		err = stpaul_get_first_compatible_value(pcih, &compatible);
3449ef7884dSanovick 
3459ef7884dSanovick 		/* Print NAC name */
3469ef7884dSanovick 		log_printf("%-20s", NAC);
3479ef7884dSanovick 		/* Print Device Path */
3489ef7884dSanovick 		if (strlen(device_path) > 38)
3499ef7884dSanovick 			log_printf("%38.37s+", device_path);
3509ef7884dSanovick 		else
3519ef7884dSanovick 			log_printf("%39s", device_path);
3529ef7884dSanovick 		/* Print Compatible # */
353*087113e1Smb 		if (err == PICL_SUCCESS) {
354*087113e1Smb 			log_printf("%31s", compatible);
355*087113e1Smb 			free(compatible);
356*087113e1Smb 		} else
357*087113e1Smb 			log_printf("%31s", " ");
3589ef7884dSanovick 		/* Print Revision */
3599ef7884dSanovick 		log_printf("%6d", revision);
3609ef7884dSanovick 		log_printf("\n");
3619ef7884dSanovick 	}
3629ef7884dSanovick 
3639ef7884dSanovick 	return (PICL_WALK_CONTINUE);
3649ef7884dSanovick }
3659ef7884dSanovick 
3669ef7884dSanovick static void
get_bus_type(char * path,struct io_card * card)3679ef7884dSanovick get_bus_type(char *path, struct io_card *card)
3689ef7884dSanovick {
3695b20c9b9Sanovick 	if (strncmp(path, SPL_PCIE_PEM0, strlen(SPL_PCIE_PEM0)) == 0) {
3705b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3715b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_PEM1, strlen(SPL_PCIE_PEM1)) == 0) {
3725b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3735b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM0, strlen(SPL_PCIE_NEM0)) == 0) {
3745b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3755b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM1, strlen(SPL_PCIE_NEM1)) == 0) {
3765b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3779ef7884dSanovick 	} else if (strncmp(path, SWITCH_A_PATH, strlen(SWITCH_A_PATH)) == 0) {
3785b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3799ef7884dSanovick 	} else if (strncmp(path, SWITCH_B_PATH, strlen(SWITCH_B_PATH)) == 0) {
3805b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "PCIE", sizeof (card->bus_type));
3819ef7884dSanovick 	} else {
3825b20c9b9Sanovick 		(void) strlcpy(card->bus_type, "NONE", sizeof (card->bus_type));
3839ef7884dSanovick 	}
3849ef7884dSanovick }
3859ef7884dSanovick 
3869ef7884dSanovick static void
get_slot_number(char * path,struct io_card * card)3879ef7884dSanovick get_slot_number(char *path, struct io_card *card)
3889ef7884dSanovick {
3895b20c9b9Sanovick 	if (strncmp(path, SPL_PCIE_PEM0, strlen(SPL_PCIE_PEM0)) == 0) {
3905b20c9b9Sanovick 		(void) strlcpy(card->slot_str, "0", sizeof (card->slot_str));
3919ef7884dSanovick 		card->slot = 0;
3925b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM0, strlen(SPL_PCIE_NEM0)) == 0) {
3935b20c9b9Sanovick 		(void) strlcpy(card->slot_str, "0", sizeof (card->slot_str));
3945b20c9b9Sanovick 		card->slot = 0;
3955b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_PEM1, strlen(SPL_PCIE_PEM1)) == 0) {
3965b20c9b9Sanovick 		(void) strlcpy(card->slot_str, "1", sizeof (card->slot_str));
3975b20c9b9Sanovick 		card->slot = 1;
3985b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM1, strlen(SPL_PCIE_NEM1)) == 0) {
3995b20c9b9Sanovick 		(void) strlcpy(card->slot_str, "1", sizeof (card->slot_str));
4009ef7884dSanovick 		card->slot = 1;
4019ef7884dSanovick 	} else {
4025b20c9b9Sanovick 		(void) strlcpy(card->slot_str, MOTHERBOARD,
4035b20c9b9Sanovick 		    sizeof (card->slot_str));
4049ef7884dSanovick 		card->slot = -1;
4059ef7884dSanovick 	}
4069ef7884dSanovick }
4079ef7884dSanovick 
4089ef7884dSanovick static int
stpaul_get_network_instance(char * path)4099ef7884dSanovick stpaul_get_network_instance(char *path)
4109ef7884dSanovick {
4119ef7884dSanovick 	if (strncmp(path, SPL_NETWORK_1_PATH,
412*087113e1Smb 	    strlen(SPL_NETWORK_1_PATH)) == 0)
4139ef7884dSanovick 		return (1);
4149ef7884dSanovick 	else if (strncmp(path, SPL_NETWORK_0_PATH,
415*087113e1Smb 	    strlen(SPL_NETWORK_0_PATH)) == 0)
4169ef7884dSanovick 		return (0);
4179ef7884dSanovick 	else
4189ef7884dSanovick 		return (-1);
4199ef7884dSanovick }
4209ef7884dSanovick 
4215b20c9b9Sanovick static int
stpaul_get_usb_instance(char * path)4225b20c9b9Sanovick stpaul_get_usb_instance(char *path)
4235b20c9b9Sanovick {
4245b20c9b9Sanovick 	if (strncmp(path, SPL_USB2_PATH, strlen(SPL_USB2_PATH)) == 0)
4255b20c9b9Sanovick 		return (2);
4265b20c9b9Sanovick 	else if (strncmp(path, SPL_USB1_PATH, strlen(SPL_USB1_PATH)) == 0)
4275b20c9b9Sanovick 		return (1);
4285b20c9b9Sanovick 	else if (strncmp(path, SPL_USB0_PATH, strlen(path)) == 0)
4295b20c9b9Sanovick 		return (0);
4305b20c9b9Sanovick 	else
4315b20c9b9Sanovick 		return (-1);
4325b20c9b9Sanovick }
4335b20c9b9Sanovick 
4345b20c9b9Sanovick static int
stpaul_get_io_instance(char * path,char * type)4355b20c9b9Sanovick stpaul_get_io_instance(char *path, char *type)
4365b20c9b9Sanovick {
4375b20c9b9Sanovick 	if (strncmp(path, SPL_PCIE_PEM1, strlen(SPL_PCIE_PEM1)) == 0) {
4385b20c9b9Sanovick 		*type = SPL_PEM_TYPE;
4395b20c9b9Sanovick 		return (1);
4405b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_PEM0, strlen(SPL_PCIE_PEM0)) == 0) {
4415b20c9b9Sanovick 		*type = SPL_PEM_TYPE;
4425b20c9b9Sanovick 		return (0);
4435b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM1, strlen(SPL_PCIE_NEM1)) == 0) {
4445b20c9b9Sanovick 		*type = SPL_NEM_TYPE;
4455b20c9b9Sanovick 		return (1);
4465b20c9b9Sanovick 	} else if (strncmp(path, SPL_PCIE_NEM0, strlen(SPL_PCIE_NEM0)) == 0) {
4475b20c9b9Sanovick 		*type = SPL_NEM_TYPE;
4485b20c9b9Sanovick 		return (0);
4495b20c9b9Sanovick 	} else
4505b20c9b9Sanovick 		return (-1);
4515b20c9b9Sanovick }
4529ef7884dSanovick /*
4539ef7884dSanovick  * return the first compatible value
4549ef7884dSanovick  */
4559ef7884dSanovick static int
stpaul_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)4569ef7884dSanovick stpaul_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
4579ef7884dSanovick {
4589ef7884dSanovick 	int		err;
4599ef7884dSanovick 	picl_prophdl_t	proph;
4609ef7884dSanovick 	picl_propinfo_t	pinfo;
4619ef7884dSanovick 	picl_prophdl_t	tblh;
4629ef7884dSanovick 	picl_prophdl_t	rowproph;
4639ef7884dSanovick 	char		*pval;
4649ef7884dSanovick 
4659ef7884dSanovick 	err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
4669ef7884dSanovick 	    &pinfo, &proph);
4679ef7884dSanovick 	if (err != PICL_SUCCESS)
468*087113e1Smb 		return (err);
4699ef7884dSanovick 
4709ef7884dSanovick 	if (pinfo.type == PICL_PTYPE_CHARSTRING) {
4719ef7884dSanovick 		pval = malloc(pinfo.size);
4729ef7884dSanovick 		if (pval == NULL)
4739ef7884dSanovick 			return (PICL_FAILURE);
4749ef7884dSanovick 		err = picl_get_propval(proph, pval, pinfo.size);
4759ef7884dSanovick 		if (err != PICL_SUCCESS) {
4769ef7884dSanovick 			free(pval);
4779ef7884dSanovick 			return (err);
4789ef7884dSanovick 		}
4799ef7884dSanovick 		*outbuf = pval;
4809ef7884dSanovick 		return (PICL_SUCCESS);
4819ef7884dSanovick 	}
4829ef7884dSanovick 
4839ef7884dSanovick 	if (pinfo.type != PICL_PTYPE_TABLE)
4849ef7884dSanovick 		return (PICL_FAILURE);
4859ef7884dSanovick 
4869ef7884dSanovick 	/* get first string from table */
4879ef7884dSanovick 	err = picl_get_propval(proph, &tblh, pinfo.size);
4889ef7884dSanovick 	if (err != PICL_SUCCESS)
4899ef7884dSanovick 		return (err);
4909ef7884dSanovick 
4919ef7884dSanovick 	err = picl_get_next_by_row(tblh, &rowproph);
4929ef7884dSanovick 	if (err != PICL_SUCCESS)
4939ef7884dSanovick 		return (err);
4949ef7884dSanovick 
4959ef7884dSanovick 	err = picl_get_propinfo(rowproph, &pinfo);
4969ef7884dSanovick 	if (err != PICL_SUCCESS)
497*087113e1Smb 		return (err);
4989ef7884dSanovick 
4999ef7884dSanovick 	pval = malloc(pinfo.size);
5009ef7884dSanovick 	if (pval == NULL)
5019ef7884dSanovick 		return (PICL_FAILURE);
5029ef7884dSanovick 
5039ef7884dSanovick 	err = picl_get_propval(rowproph, pval, pinfo.size);
5049ef7884dSanovick 	if (err != PICL_SUCCESS) {
5059ef7884dSanovick 		free(pval);
5069ef7884dSanovick 		return (err);
5079ef7884dSanovick 	}
5089ef7884dSanovick 
5099ef7884dSanovick 	*outbuf = pval;
5109ef7884dSanovick 	return (PICL_SUCCESS);
5119ef7884dSanovick }
5129ef7884dSanovick 
5139ef7884dSanovick static int64_t
stpaul_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)5149ef7884dSanovick stpaul_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
5159ef7884dSanovick {
5169ef7884dSanovick 	int		err;
5179ef7884dSanovick 	picl_prophdl_t	proph;
5189ef7884dSanovick 	picl_propinfo_t	pinfo;
5199ef7884dSanovick 	int8_t		int8v;
5209ef7884dSanovick 	int16_t		int16v;
5219ef7884dSanovick 	int32_t		int32v;
5229ef7884dSanovick 	int64_t		int64v;
5239ef7884dSanovick 
5249ef7884dSanovick 	err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
5259ef7884dSanovick 	if (err != PICL_SUCCESS) {
5269ef7884dSanovick 		*ret = err;
5279ef7884dSanovick 		return (0);
5289ef7884dSanovick 	}
5299ef7884dSanovick 
5309ef7884dSanovick 	/*
5319ef7884dSanovick 	 * If it is not an int, uint or byte array prop, return failure
5329ef7884dSanovick 	 */
5339ef7884dSanovick 	if ((pinfo.type != PICL_PTYPE_INT) &&
534*087113e1Smb 	    (pinfo.type != PICL_PTYPE_UNSIGNED_INT) &&
535*087113e1Smb 	    (pinfo.type != PICL_PTYPE_BYTEARRAY)) {
5369ef7884dSanovick 		*ret = PICL_FAILURE;
5379ef7884dSanovick 		return (0);
5389ef7884dSanovick 	}
5399ef7884dSanovick 
5409ef7884dSanovick 	switch (pinfo.size) {
5419ef7884dSanovick 	case sizeof (int8_t):
5429ef7884dSanovick 		err = picl_get_propval(proph, &int8v, sizeof (int8v));
5439ef7884dSanovick 		*ret = err;
5449ef7884dSanovick 		return (int8v);
5459ef7884dSanovick 	case sizeof (int16_t):
5469ef7884dSanovick 		err = picl_get_propval(proph, &int16v, sizeof (int16v));
5479ef7884dSanovick 		*ret = err;
5489ef7884dSanovick 		return (int16v);
5499ef7884dSanovick 	case sizeof (int32_t):
5509ef7884dSanovick 		err = picl_get_propval(proph, &int32v, sizeof (int32v));
5519ef7884dSanovick 		*ret = err;
5529ef7884dSanovick 		return (int32v);
5539ef7884dSanovick 	case sizeof (int64_t):
5549ef7884dSanovick 		err = picl_get_propval(proph, &int64v, sizeof (int64v));
5559ef7884dSanovick 		*ret = err;
5569ef7884dSanovick 		return (int64v);
5579ef7884dSanovick 	default:	/* not supported size */
5589ef7884dSanovick 		*ret = PICL_FAILURE;
5599ef7884dSanovick 		return (0);
5609ef7884dSanovick 	}
5619ef7884dSanovick }
562