13db86aabSstevel /*
23db86aabSstevel  * CDDL HEADER START
33db86aabSstevel  *
43db86aabSstevel  * The contents of this file are subject to the terms of the
53db86aabSstevel  * Common Development and Distribution License, Version 1.0 only
63db86aabSstevel  * (the "License").  You may not use this file except in compliance
73db86aabSstevel  * with the License.
83db86aabSstevel  *
93db86aabSstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
103db86aabSstevel  * or http://www.opensolaris.org/os/licensing.
113db86aabSstevel  * See the License for the specific language governing permissions
123db86aabSstevel  * and limitations under the License.
133db86aabSstevel  *
143db86aabSstevel  * When distributing Covered Code, include this CDDL HEADER in each
153db86aabSstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
163db86aabSstevel  * If applicable, add the following below this CDDL HEADER, with the
173db86aabSstevel  * fields enclosed by brackets "[]" replaced with your own identifying
183db86aabSstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
193db86aabSstevel  *
203db86aabSstevel  * CDDL HEADER END
213db86aabSstevel  */
223db86aabSstevel /*
233db86aabSstevel  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
243db86aabSstevel  * Use is subject to license terms.
253db86aabSstevel  */
263db86aabSstevel 
273db86aabSstevel #include <stddef.h>
283db86aabSstevel #include <locale.h>
293db86aabSstevel #include <ctype.h>
303db86aabSstevel #include <stdio.h>
313db86aabSstevel #include <stdlib.h>
323db86aabSstevel #include <string.h>
333db86aabSstevel #include <fcntl.h>
343db86aabSstevel #include <unistd.h>
353db86aabSstevel #include <errno.h>
363db86aabSstevel #include <locale.h>
373db86aabSstevel #include <langinfo.h>
383db86aabSstevel #include <time.h>
393db86aabSstevel #include <stdarg.h>
403db86aabSstevel #include <sys/types.h>
413db86aabSstevel #include <sys/ioctl.h>
423db86aabSstevel #include <sys/dditypes.h>
433db86aabSstevel #include <sys/modctl.h>
443db86aabSstevel #include <sys/obpdefs.h>
453db86aabSstevel #include <sys/fhc.h>
463db86aabSstevel #include <sys/sysctrl.h>
473db86aabSstevel #include <sys/openpromio.h>
483db86aabSstevel #ifdef	SIM
493db86aabSstevel #include <sys/stat.h>
503db86aabSstevel #endif
513db86aabSstevel #define	CFGA_PLUGIN_LIB
523db86aabSstevel #include <config_admin.h>
533db86aabSstevel 
543db86aabSstevel #ifdef	DEBUG
553db86aabSstevel #define	DBG	printf
563db86aabSstevel #define	DBG1	printf
573db86aabSstevel #define	DBG3	printf
583db86aabSstevel #define	DBG4	printf
593db86aabSstevel #else
603db86aabSstevel #define	DBG(a, b)
613db86aabSstevel #define	DBG1(a)
623db86aabSstevel #define	DBG3(a, b, c)
633db86aabSstevel #define	DBG4(a, b, c, d)
643db86aabSstevel #endif
653db86aabSstevel 
663db86aabSstevel #define	BD_CPU			1
673db86aabSstevel #define	BD_MEM			2
683db86aabSstevel #define	BD_IO_2SBUS		3
693db86aabSstevel #define	BD_IO_SBUS_FFB		4
703db86aabSstevel #define	BD_IO_PCI		5
713db86aabSstevel #define	BD_DISK			6
723db86aabSstevel #define	BD_IO_2SBUS_SOCPLUS	7
733db86aabSstevel #define	BD_IO_SBUS_FFB_SOCPLUS	8
743db86aabSstevel #define	BD_UNKNOWN		9
753db86aabSstevel #define	CMD_GETSTAT		10
763db86aabSstevel #define	CMD_LIST		11
773db86aabSstevel #define	CMD_CONNECT		12
783db86aabSstevel #define	CMD_DISCONNECT		13
793db86aabSstevel #define	CMD_CONFIGURE		14
803db86aabSstevel #define	CMD_UNCONFIGURE		15
813db86aabSstevel #define	CMD_QUIESCE		16
823db86aabSstevel #define	CMD_INSERT		17
833db86aabSstevel #define	CMD_REMOVE		18
843db86aabSstevel #define	CMD_SET_COND		19
853db86aabSstevel #define	OPT_ENABLE		20
863db86aabSstevel #define	OPT_DISABLE		21
873db86aabSstevel #define	ERR_PROM_OPEN		22
883db86aabSstevel #define	ERR_PROM_GETPROP	23
893db86aabSstevel #define	ERR_PROM_SETPROP	24
903db86aabSstevel #define	ERR_TRANS		25
913db86aabSstevel #define	ERR_CMD_INVAL		26
923db86aabSstevel #define	ERR_OPT_INVAL		27
933db86aabSstevel #define	ERR_AP_INVAL		28
943db86aabSstevel #define	ERR_DISABLED		29
953db86aabSstevel #define	DIAG_FORCE		30
963db86aabSstevel #define	DIAG_TRANS_OK		31
973db86aabSstevel #define	DIAG_FAILED		32
983db86aabSstevel #define	DIAG_WAS_ENABLED	33
993db86aabSstevel #define	DIAG_WAS_DISABLED	34
1003db86aabSstevel #define	DIAG_WILL_ENABLE	35
1013db86aabSstevel #define	DIAG_WILL_DISABLE	36
1023db86aabSstevel #define	HELP_HEADER		37
1033db86aabSstevel #define	HELP_QUIESCE		38
1043db86aabSstevel #define	HELP_INSERT		39
1053db86aabSstevel #define	HELP_REMOVE		40
1063db86aabSstevel #define	HELP_SET_COND		41
1073db86aabSstevel #define	HELP_ENABLE		42
1083db86aabSstevel #define	HELP_DISABLE		43
1093db86aabSstevel #define	HELP_UNKNOWN		44
1103db86aabSstevel #define	ASK_CONNECT		45
1113db86aabSstevel #define	STR_BD			46
1123db86aabSstevel #define	STR_COL			47
1133db86aabSstevel #define	COND_UNKNOWN		48
1143db86aabSstevel #define	COND_OK			49
1153db86aabSstevel #define	COND_FAILING		50
1163db86aabSstevel #define	COND_FAILED		51
1173db86aabSstevel #define	COND_UNUSABLE		52
1183db86aabSstevel #define	SYSC_COOLING		53
1193db86aabSstevel #define	SYSC_POWER		54
1203db86aabSstevel #define	SYSC_PRECHARGE		55
1213db86aabSstevel #define	SYSC_INTRANS		56
1223db86aabSstevel #define	SYSC_UTHREAD		57
1233db86aabSstevel #define	SYSC_KTHREAD		58
1243db86aabSstevel #define	SYSC_DEV_ATTACH		59
1253db86aabSstevel #define	SYSC_DEV_DETACH		60
1263db86aabSstevel #define	SYSC_NDI_ATTACH		61
1273db86aabSstevel #define	SYSC_NDI_DETACH		62
1283db86aabSstevel #define	SYSC_CORE_RESOURCE	63
1293db86aabSstevel #define	SYSC_OSTATE		64
1303db86aabSstevel #define	SYSC_RSTATE		65
1313db86aabSstevel #define	SYSC_COND		66
1323db86aabSstevel #define	SYSC_PROM		67
1333db86aabSstevel #define	SYSC_NOMEM		68
1343db86aabSstevel #define	SYSC_HOTPLUG		69
1353db86aabSstevel #define	SYSC_HW_COMPAT		70
1363db86aabSstevel #define	SYSC_NON_DR_PROM	71
1373db86aabSstevel #define	SYSC_SUSPEND		72
1383db86aabSstevel #define	SYSC_RESUME		73
1393db86aabSstevel #define	SYSC_UNKNOWN		74
1403db86aabSstevel #define	SYSC_DEVSTR		75
1413db86aabSstevel 
1423db86aabSstevel /*
1433db86aabSstevel  * The string table contains all the strings used by the platform
1443db86aabSstevel  * library.  The comment next to each string specifies whether the
1453db86aabSstevel  * string should be internationalized (y) or not (n).
1463db86aabSstevel  * Note that there are calls to dgettext() with strings other than
1473db86aabSstevel  * the ones below, they are marked by the li18 symbol.
1483db86aabSstevel  */
1493db86aabSstevel static char *
1503db86aabSstevel cfga_strs[] = {
1513db86aabSstevel 	/*   */ NULL,
1523db86aabSstevel 	/* n */ "cpu/mem   ",
1533db86aabSstevel 	/* n */ "mem       ",
1543db86aabSstevel 	/* n */ "dual-sbus ",
1553db86aabSstevel 	/* n */ "sbus-upa  ",
1563db86aabSstevel 	/* n */ "dual-pci  ",
1573db86aabSstevel 	/* n */ "disk      ",
1583db86aabSstevel 	/* n */ "soc+sbus  ",
1593db86aabSstevel 	/* n */ "soc+upa   ",
1603db86aabSstevel 	/* n */ "unknown   ",
1613db86aabSstevel 	/* n */ "get-status",
1623db86aabSstevel 	/* n */ "list",
1633db86aabSstevel 	/* n */ "connect",
1643db86aabSstevel 	/* n */ "disconnect",
1653db86aabSstevel 	/* n */ "configure",
1663db86aabSstevel 	/* n */ "unconfigure",
1673db86aabSstevel 	/* n */ "quiesce-test",
1683db86aabSstevel 	/* n */ "insert-test",
1693db86aabSstevel 	/* n */ "remove-test",
1703db86aabSstevel 	/* n */ "set-condition-test",
1713db86aabSstevel 	/* n */ "enable-at-boot",
1723db86aabSstevel 	/* n */ "disable-at-boot",
1733db86aabSstevel 	/* n */ "prom open",
1743db86aabSstevel 	/* n */ "prom getprop",
1753db86aabSstevel 	/* n */ "prom setprop",
1763db86aabSstevel 	/* y */ "invalid transition",
1773db86aabSstevel 	/* y */ "invalid command: ",
1783db86aabSstevel 	/* y */ "invalid option: ",
1793db86aabSstevel 	/* y */ "invalid attachment point: ",
1803db86aabSstevel 	/* y */ "board is disabled: must override with ",
1813db86aabSstevel 	/* n */ "[-f][-o enable-at-boot]",
1823db86aabSstevel 	/* y */ "transition succeeded but ",
1833db86aabSstevel 	/* y */ " failed: ",
1843db86aabSstevel 	/* y */ "was already enabled at boot time",
1853db86aabSstevel 	/* y */ "was already disabled at boot time",
1863db86aabSstevel 	/* y */ "will be enabled at boot time",
1873db86aabSstevel 	/* y */ "will be disabled at boot time",
1883db86aabSstevel 	/* y */ "\nSysctrl specific commands/options:",
1893db86aabSstevel 	/* n */ "\t-x quiesce-test ap_id [ap_id...]",
1903db86aabSstevel 	/* n */ "\t-x insert-test  ap_id [ap_id...]",
1913db86aabSstevel 	/* n */ "\t-x remove-test  ap_id [ap_id...]",
1923db86aabSstevel 	/* n */ "\t-x set-condition-test=<condition>",
1933db86aabSstevel 	/* n */ "\t-o enable-at-boot",
1943db86aabSstevel 	/* n */ "\t-o disable-at-boot",
1953db86aabSstevel 	/* y */ "\tunknown command or option: ",
1963db86aabSstevel 	/* y */
1973db86aabSstevel 	"system will be temporarily suspended to connect a board: proceed",
1983db86aabSstevel 	/* y */ "board ",
1993db86aabSstevel 	/* y */ ": ",
2003db86aabSstevel 	/* n */ "unknown",
2013db86aabSstevel 	/* n */ "ok",
2023db86aabSstevel 	/* n */ "failing",
2033db86aabSstevel 	/* n */ "failed",
2043db86aabSstevel 	/* n */ "unusable",
2053db86aabSstevel 	/* y */ "not enough cooling for a new board",
2063db86aabSstevel 	/* y */ "not enough power for a new board",
2073db86aabSstevel 	/* y */ "not enough precharge power for a new board",
2083db86aabSstevel 	/* y */ "configuration operation already in progress on this board",
2093db86aabSstevel 	/* y */ "could not suspend user process: ",
2103db86aabSstevel 	/* y */ "could not suspend system processes",
2113db86aabSstevel 	/* y */ "device did not attach",
2123db86aabSstevel 	/* y */ "device did not detach",
2133db86aabSstevel 	/* y */ "nexus error during attach",
2143db86aabSstevel 	/* y */ "nexus error during detach",
2153db86aabSstevel 	/* y */ "attempt to remove core system resource",
2163db86aabSstevel 	/* y */ "invalid occupant state",
2173db86aabSstevel 	/* y */ "invalid receptacle state",
2183db86aabSstevel 	/* y */ "insufficient condition",
2193db86aabSstevel 	/* y */ "firmware operation error",
2203db86aabSstevel 	/* y */ "not enough memory",
2213db86aabSstevel 	/* y */ "hotplug feature unavailable on this machine",
2223db86aabSstevel 	/* y */ "board does not support dynamic reconfiguration",
2233db86aabSstevel 	/* y */ "firmware does not support dynamic reconfiguration",
2243db86aabSstevel 	/* y */ "system suspend error",
2253db86aabSstevel 	/* y */ "system resume error",
2263db86aabSstevel 	/* y */ "unknown system error",
2273db86aabSstevel 	/*   */ NULL
2283db86aabSstevel };
2293db86aabSstevel 
2303db86aabSstevel #define	cfga_str(i)		cfga_strs[(i)]
2313db86aabSstevel 
2323db86aabSstevel #define	cfga_eid(a, b)		(((a) << 8) + (b))
2333db86aabSstevel 
2343db86aabSstevel /*
2353db86aabSstevel  *
2363db86aabSstevel  *	Translation table for mapping from an <errno,sysc_err>
2373db86aabSstevel  *	pair to an error string.
2383db86aabSstevel  *
2393db86aabSstevel  *
2403db86aabSstevel  *	SYSC_COOLING,		EAGAIN,  SYSC_ERR_COOLING
2413db86aabSstevel  *	SYSC_POWER,		EAGAIN,  SYSC_ERR_POWER
2423db86aabSstevel  *	SYSC_PRECHARGE,		EAGAIN,  SYSC_ERR_PRECHARGE
2433db86aabSstevel  *	SYSC_INTRANS,		EBUSY,   SYSC_ERR_INTRANS
2443db86aabSstevel  *	SYSC_KTHREAD,		EBUSY,   SYSC_ERR_KTHREAD
2453db86aabSstevel  *	SYSC_DEV_ATTACH,	EBUSY,   SYSC_ERR_NDI_ATTACH
2463db86aabSstevel  *	SYSC_DEV_DETACH,	EBUSY,   SYSC_ERR_NDI_DETACH
2473db86aabSstevel  *	SYSC_NDI_ATTACH,	EFAULT,  SYSC_ERR_NDI_ATTACH
2483db86aabSstevel  *	SYSC_NDI_DETACH,	EFAULT,  SYSC_ERR_NDI_DETACH
2493db86aabSstevel  *	SYSC_CORE_RESOURCE,	EINVAL,  SYSC_ERR_CORE_RESOURCE
2503db86aabSstevel  *	SYSC_OSTATE,		EINVAL,  SYSC_ERR_OSTATE
2513db86aabSstevel  *	SYSC_RSTATE,		EINVAL,  SYSC_ERR_RSTATE
2523db86aabSstevel  *	SYSC_COND,		EINVAL,  SYSC_ERR_COND
2533db86aabSstevel  *	SYSC_PROM,		EIO,     SYSC_ERR_PROM
2543db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_DR_INIT
2553db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_NDI_ATTACH
2563db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_NDI_DETACH
2573db86aabSstevel  *	SYSC_HOTPLUG,		ENOTSUP, SYSC_ERR_HOTPLUG
2583db86aabSstevel  *	SYSC_HW_COMPAT,		ENOTSUP, SYSC_ERR_HW_COMPAT
2593db86aabSstevel  *	SYSC_NON_DR_PROM,	ENOTSUP, SYSC_ERR_NON_DR_PROM
2603db86aabSstevel  *	SYSC_SUSPEND,		ENXIO,   SYSC_ERR_SUSPEND
2613db86aabSstevel  *	SYSC_RESUME,		ENXIO,   SYSC_ERR_RESUME
2623db86aabSstevel  *	SYSC_UTHREAD,		ESRCH,   SYSC_ERR_UTHREAD
2633db86aabSstevel  */
2643db86aabSstevel static int
cfga_sid(int err,int scerr)2653db86aabSstevel cfga_sid(int err, int scerr)
2663db86aabSstevel {
2673db86aabSstevel 	if (scerr == SYSC_ERR_DEFAULT)
2683db86aabSstevel 		return (SYSC_UNKNOWN);
2693db86aabSstevel 
2703db86aabSstevel 	switch (cfga_eid(err, scerr)) {
2713db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_COOLING):
2723db86aabSstevel 		return (SYSC_COOLING);
2733db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_POWER):
2743db86aabSstevel 		return (SYSC_POWER);
2753db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_PRECHARGE):
2763db86aabSstevel 		return (SYSC_PRECHARGE);
2773db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_INTRANS):
2783db86aabSstevel 		return (SYSC_INTRANS);
2793db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_KTHREAD):
2803db86aabSstevel 		return (SYSC_KTHREAD);
2813db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_NDI_ATTACH):
2823db86aabSstevel 		return (SYSC_DEV_ATTACH);
2833db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_NDI_DETACH):
2843db86aabSstevel 		return (SYSC_DEV_DETACH);
2853db86aabSstevel 	case cfga_eid(EFAULT, SYSC_ERR_NDI_ATTACH):
2863db86aabSstevel 		return (SYSC_NDI_ATTACH);
2873db86aabSstevel 	case cfga_eid(EFAULT, SYSC_ERR_NDI_DETACH):
2883db86aabSstevel 		return (SYSC_NDI_DETACH);
2893db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_CORE_RESOURCE):
2903db86aabSstevel 		return (SYSC_CORE_RESOURCE);
2913db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_OSTATE):
2923db86aabSstevel 		return (SYSC_OSTATE);
2933db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_RSTATE):
2943db86aabSstevel 		return (SYSC_RSTATE);
2953db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_COND):
2963db86aabSstevel 		return (SYSC_COND);
2973db86aabSstevel 	case cfga_eid(EIO, SYSC_ERR_PROM):
2983db86aabSstevel 		return (SYSC_PROM);
2993db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_DR_INIT):
3003db86aabSstevel 		return (SYSC_NOMEM);
3013db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_NDI_ATTACH):
3023db86aabSstevel 		return (SYSC_NOMEM);
3033db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_NDI_DETACH):
3043db86aabSstevel 		return (SYSC_NOMEM);
3053db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_HOTPLUG):
3063db86aabSstevel 		return (SYSC_HOTPLUG);
3073db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_HW_COMPAT):
3083db86aabSstevel 		return (SYSC_HW_COMPAT);
3093db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_NON_DR_PROM):
3103db86aabSstevel 		return (SYSC_NON_DR_PROM);
3113db86aabSstevel 	case cfga_eid(ENXIO, SYSC_ERR_SUSPEND):
3123db86aabSstevel 		return (SYSC_SUSPEND);
3133db86aabSstevel 	case cfga_eid(ENXIO, SYSC_ERR_RESUME):
3143db86aabSstevel 		return (SYSC_RESUME);
3153db86aabSstevel 	case cfga_eid(ESRCH, SYSC_ERR_UTHREAD):
3163db86aabSstevel 		return (SYSC_UTHREAD);
3173db86aabSstevel 	default:
3183db86aabSstevel 		break;
3193db86aabSstevel 	}
3203db86aabSstevel 
3213db86aabSstevel 	return (SYSC_UNKNOWN);
3223db86aabSstevel }
3233db86aabSstevel 
3243db86aabSstevel static void
sysc_cmd_init(sysc_cfga_cmd_t * sc,char * outputstr,int force)3253db86aabSstevel sysc_cmd_init(sysc_cfga_cmd_t *sc, char *outputstr, int force)
3263db86aabSstevel {
3273db86aabSstevel 	sc->force = force;
3283db86aabSstevel 	sc->outputstr = outputstr;
3293db86aabSstevel 	sc->errtype = SYSC_ERR_DEFAULT;
3303db86aabSstevel 
3313db86aabSstevel 	(void) memset((void *)outputstr, 0, sizeof (outputstr));
3323db86aabSstevel 
3333db86aabSstevel 	cfga_str(SYSC_DEVSTR) = outputstr;
3343db86aabSstevel }
3353db86aabSstevel 
3363db86aabSstevel /*
3373db86aabSstevel  * cfga_err() accepts a variable number of message IDs and constructs
3383db86aabSstevel  * a corresponding error string which is returned via the errstring argument.
3393db86aabSstevel  * cfga_err() calls dgettext() to internationalize proper messages.
3403db86aabSstevel  */
3413db86aabSstevel static void
cfga_err(sysc_cfga_cmd_t * sc,char ** errstring,...)3423db86aabSstevel cfga_err(sysc_cfga_cmd_t *sc, char **errstring, ...)
3433db86aabSstevel {
3443db86aabSstevel 	int a;
3453db86aabSstevel 	int i;
3463db86aabSstevel 	int n;
3473db86aabSstevel 	int len;
3483db86aabSstevel 	int flen;
3493db86aabSstevel 	char *p;
3503db86aabSstevel 	char *q;
3513db86aabSstevel 	char *s[32];
3523db86aabSstevel 	char *failed;
3533db86aabSstevel 	va_list ap;
3543db86aabSstevel 	char syserr_num[20];
3553db86aabSstevel 
3563db86aabSstevel 	/*
3573db86aabSstevel 	 * If errstring is null it means user in not interested in getting
3583db86aabSstevel 	 * error status. So we don't do all the work
3593db86aabSstevel 	 */
3603db86aabSstevel 	if (errstring == NULL) {
3613db86aabSstevel 		return;
3623db86aabSstevel 	}
3633db86aabSstevel 	va_start(ap, errstring);
3643db86aabSstevel 
3653db86aabSstevel 	failed = dgettext(TEXT_DOMAIN, cfga_str(DIAG_FAILED));
3663db86aabSstevel 	flen = strlen(failed);
3673db86aabSstevel 
3683db86aabSstevel 	for (n = len = 0; (a = va_arg(ap, int)) != 0; n++) {
3693db86aabSstevel 
3703db86aabSstevel 		switch (a) {
3713db86aabSstevel 		case ERR_PROM_OPEN:
3723db86aabSstevel 		case ERR_PROM_GETPROP:
3733db86aabSstevel 		case ERR_PROM_SETPROP:
3743db86aabSstevel 		case CMD_GETSTAT:
3753db86aabSstevel 		case CMD_LIST:
3763db86aabSstevel 		case CMD_CONNECT:
3773db86aabSstevel 		case CMD_DISCONNECT:
3783db86aabSstevel 		case CMD_CONFIGURE:
3793db86aabSstevel 		case CMD_UNCONFIGURE:
3803db86aabSstevel 		case CMD_QUIESCE:
3813db86aabSstevel 		case CMD_INSERT:
3823db86aabSstevel 		case CMD_REMOVE:
3833db86aabSstevel 		case CMD_SET_COND:
3843db86aabSstevel 			p =  cfga_str(a);
3853db86aabSstevel 			len += (strlen(p) + flen);
3863db86aabSstevel 			s[n] = p;
3873db86aabSstevel 			s[++n] = failed;
3883db86aabSstevel 
3893db86aabSstevel 			DBG("<%s>", p);
3903db86aabSstevel 			DBG("<%s>", failed);
3913db86aabSstevel 			break;
3923db86aabSstevel 
3933db86aabSstevel 		case OPT_ENABLE:
3943db86aabSstevel 		case OPT_DISABLE:
3953db86aabSstevel 			p = dgettext(TEXT_DOMAIN, cfga_str(DIAG_TRANS_OK));
3963db86aabSstevel 			q = cfga_str(a);
3973db86aabSstevel 			len += (strlen(p) + strlen(q) + flen);
3983db86aabSstevel 			s[n] = p;
3993db86aabSstevel 			s[++n] = q;
4003db86aabSstevel 			s[++n] = failed;
4013db86aabSstevel 
4023db86aabSstevel 			DBG("<%s>", p);
4033db86aabSstevel 			DBG("<%s>", q);
4043db86aabSstevel 			DBG("<%s>", failed);
4053db86aabSstevel 			break;
4063db86aabSstevel 
4073db86aabSstevel 		case ERR_CMD_INVAL:
4083db86aabSstevel 		case ERR_AP_INVAL:
4093db86aabSstevel 		case ERR_OPT_INVAL:
4103db86aabSstevel 			p =  dgettext(TEXT_DOMAIN, cfga_str(a));
4113db86aabSstevel 			q = va_arg(ap, char *);
4123db86aabSstevel 			len += (strlen(p) + strlen(q));
4133db86aabSstevel 			s[n] = p;
4143db86aabSstevel 			s[++n] = q;
4153db86aabSstevel 
4163db86aabSstevel 			DBG("<%s>", p);
4173db86aabSstevel 			DBG("<%s>", q);
4183db86aabSstevel 			break;
4193db86aabSstevel 
4203db86aabSstevel 		case ERR_TRANS:
4213db86aabSstevel 		case ERR_DISABLED:
4223db86aabSstevel 			p =  dgettext(TEXT_DOMAIN, cfga_str(a));
4233db86aabSstevel 			len += strlen(p);
4243db86aabSstevel 			s[n] = p;
4253db86aabSstevel 
4263db86aabSstevel 			DBG("<%s>", p);
4273db86aabSstevel 			break;
4283db86aabSstevel 
4293db86aabSstevel 		case DIAG_FORCE:
4303db86aabSstevel 		default:
4313db86aabSstevel 			p =  cfga_str(a);
4323db86aabSstevel 			len += strlen(p);
4333db86aabSstevel 			s[n] = p;
4343db86aabSstevel 
4353db86aabSstevel 			DBG("<%s>", p);
4363db86aabSstevel 			break;
4373db86aabSstevel 		}
4383db86aabSstevel 	}
4393db86aabSstevel 
4403db86aabSstevel 	DBG1("\n");
4413db86aabSstevel 	va_end(ap);
4423db86aabSstevel 
4433db86aabSstevel 	if (errno) {
4443db86aabSstevel 		if (sc)
4453db86aabSstevel 			i = cfga_sid(errno, (int)sc->errtype);
4463db86aabSstevel 		else
4473db86aabSstevel 			i = SYSC_UNKNOWN;
4483db86aabSstevel 
4493db86aabSstevel 		DBG4("cfga_sid(%d,%d)=%d\n", errno, sc->errtype, i);
4503db86aabSstevel 
4513db86aabSstevel 		if (i == SYSC_UNKNOWN) {
4523db86aabSstevel 			p = strerror(errno);
4533db86aabSstevel 			if (p == NULL) {
4543db86aabSstevel 				(void) sprintf(syserr_num, "errno=%d", errno);
4553db86aabSstevel 				p = syserr_num;
4563db86aabSstevel 			}
4573db86aabSstevel 		} else
4583db86aabSstevel 			p = dgettext(TEXT_DOMAIN, cfga_str(i));
4593db86aabSstevel 
4603db86aabSstevel 		len += strlen(p);
4613db86aabSstevel 		s[n++] = p;
4623db86aabSstevel 		p = cfga_str(SYSC_DEVSTR);
4633db86aabSstevel 		if (p && p[0]) {
4643db86aabSstevel 			q = cfga_str(STR_COL);
4653db86aabSstevel 
4663db86aabSstevel 			len += strlen(q);
4673db86aabSstevel 			s[n++] = q;
4683db86aabSstevel 			len += strlen(p);
4693db86aabSstevel 			s[n++] = p;
4703db86aabSstevel 		}
4713db86aabSstevel 	}
4723db86aabSstevel 
4733db86aabSstevel 	if ((p = (char *)calloc(len, 1)) == NULL)
4743db86aabSstevel 		return;
4753db86aabSstevel 
4763db86aabSstevel 	for (i = 0; i < n; i++)
4773db86aabSstevel 		(void) strcat(p, s[i]);
4783db86aabSstevel 
4793db86aabSstevel 	*errstring = p;
4803db86aabSstevel #ifdef	SIM_MSG
4813db86aabSstevel 	printf("%s\n", *errstring);
4823db86aabSstevel #endif
4833db86aabSstevel }
4843db86aabSstevel 
4853db86aabSstevel /*
4863db86aabSstevel  * This routine accepts a variable number of message IDs and constructs
4873db86aabSstevel  * a corresponding error string which is printed via the message print routine
4883db86aabSstevel  * argument.  The HELP_UNKNOWN message ID has an argument string (the unknown
4893db86aabSstevel  * help topic) that follows.
4903db86aabSstevel  */
4913db86aabSstevel static void
cfga_msg(struct cfga_msg * msgp,...)4923db86aabSstevel cfga_msg(struct cfga_msg *msgp, ...)
4933db86aabSstevel {
4943db86aabSstevel 	int a;
4953db86aabSstevel 	int i;
4963db86aabSstevel 	int n;
4973db86aabSstevel 	int len;
4983db86aabSstevel 	char *p;
4993db86aabSstevel 	char *s[32];
5003db86aabSstevel 	va_list ap;
5013db86aabSstevel 
5023db86aabSstevel 	va_start(ap, msgp);
5033db86aabSstevel 
5043db86aabSstevel 	for (n = len = 0; (a = va_arg(ap, int)) != 0; n++) {
5053db86aabSstevel 		DBG("<%d>", a);
5063db86aabSstevel 		p =  dgettext(TEXT_DOMAIN, cfga_str(a));
5073db86aabSstevel 		len += strlen(p);
5083db86aabSstevel 		s[n] = p;
5093db86aabSstevel 		if (a == HELP_UNKNOWN) {
5103db86aabSstevel 			p = va_arg(ap, char *);
5113db86aabSstevel 			len += strlen(p);
5123db86aabSstevel 			s[++n] = p;
5133db86aabSstevel 		}
5143db86aabSstevel 	}
5153db86aabSstevel 
5163db86aabSstevel 	va_end(ap);
5173db86aabSstevel 
5183db86aabSstevel 	if ((p = (char *)calloc(len + 1, 1)) == NULL)
5193db86aabSstevel 		return;
5203db86aabSstevel 
5213db86aabSstevel 	for (i = 0; i < n; i++)
5223db86aabSstevel 		(void) strcat(p, s[i]);
5233db86aabSstevel 	(void) strcat(p, "\n");
5243db86aabSstevel 
5253db86aabSstevel #ifdef	SIM_MSG
5263db86aabSstevel 	printf("%s", p);
5273db86aabSstevel #else
5283db86aabSstevel 	(*msgp->message_routine)(msgp->appdata_ptr, p);
5293db86aabSstevel #endif
5303db86aabSstevel 	free(p);
5313db86aabSstevel }
5323db86aabSstevel 
5333db86aabSstevel static sysc_cfga_stat_t *
sysc_stat(const char * ap_id,int * fdp)5343db86aabSstevel sysc_stat(const char *ap_id, int *fdp)
5353db86aabSstevel {
5363db86aabSstevel 	int fd;
5373db86aabSstevel 	static sysc_cfga_stat_t sc_list[MAX_BOARDS];
5383db86aabSstevel 
5393db86aabSstevel 
5403db86aabSstevel 	if ((fd = open(ap_id, O_RDWR, 0)) == -1)
5413db86aabSstevel 		return (NULL);
5423db86aabSstevel 	else if (ioctl(fd, SYSC_CFGA_CMD_GETSTATUS, sc_list) == -1) {
5433db86aabSstevel 		(void) close(fd);
5443db86aabSstevel 		return (NULL);
5453db86aabSstevel 	} else if (fdp)
5463db86aabSstevel 		*fdp = fd;
5473db86aabSstevel 	else
5483db86aabSstevel 		(void) close(fd);
5493db86aabSstevel 
5503db86aabSstevel 	return (sc_list);
5513db86aabSstevel }
5523db86aabSstevel 
5533db86aabSstevel /*
5543db86aabSstevel  * This code implementes the simulation of the ioctls that transition state.
5553db86aabSstevel  * The GETSTAT ioctl is not simulated.  In this way a snapshot of the system
5563db86aabSstevel  * state is read and manipulated by the simulation routines.  It is basically
5573db86aabSstevel  * a useful debugging tool.
5583db86aabSstevel  */
5593db86aabSstevel #ifdef	SIM
5603db86aabSstevel static int sim_idx;
5613db86aabSstevel static int sim_fd = -1;
5623db86aabSstevel static int sim_size = MAX_BOARDS * sizeof (sysc_cfga_stat_t);
5633db86aabSstevel static sysc_cfga_stat_t sim_sc_list[MAX_BOARDS];
5643db86aabSstevel 
5653db86aabSstevel static sysc_cfga_stat_t *
sim_sysc_stat(const char * ap_id,int * fdp)5663db86aabSstevel sim_sysc_stat(const char *ap_id, int *fdp)
5673db86aabSstevel {
5683db86aabSstevel 	int fd;
5693db86aabSstevel 	struct stat buf;
5703db86aabSstevel 
5713db86aabSstevel 	if (sim_fd != -1)
5723db86aabSstevel 		return (sim_sc_list);
5733db86aabSstevel 
5743db86aabSstevel 	if ((sim_fd = open("/tmp/cfga_simdata", O_RDWR|O_CREAT)) == -1) {
5753db86aabSstevel 		perror("sim_open");
5763db86aabSstevel 		exit(1);
5773db86aabSstevel 	} else if (fstat(sim_fd, &buf) == -1) {
5783db86aabSstevel 		perror("sim_stat");
5793db86aabSstevel 		exit(1);
5803db86aabSstevel 	}
5813db86aabSstevel 
5823db86aabSstevel 	if (buf.st_size) {
5833db86aabSstevel 		if (buf.st_size != sim_size) {
5843db86aabSstevel 			perror("sim_size");
5853db86aabSstevel 			exit(1);
5863db86aabSstevel 		} else if (read(sim_fd, sim_sc_list, sim_size) == -1) {
5873db86aabSstevel 			perror("sim_read");
5883db86aabSstevel 			exit(1);
5893db86aabSstevel 		}
5903db86aabSstevel 	} else if ((fd = open(ap_id, O_RDWR, 0)) == -1)
5913db86aabSstevel 		return (NULL);
5923db86aabSstevel 	else if (ioctl(fd, SYSC_CFGA_CMD_GETSTATUS, sim_sc_list) == -1) {
5933db86aabSstevel 		(void) close(fd);
5943db86aabSstevel 		return (NULL);
5953db86aabSstevel 	} else if (fdp)
5963db86aabSstevel 		*fdp = fd;
5973db86aabSstevel 
5983db86aabSstevel 	return (sim_sc_list);
5993db86aabSstevel }
6003db86aabSstevel 
6013db86aabSstevel static int
sim_open(char * a,int b,int c)6023db86aabSstevel sim_open(char *a, int b, int c)
6033db86aabSstevel {
6043db86aabSstevel 	printf("sim_open(%s)\n", a);
6053db86aabSstevel 
6063db86aabSstevel 	if (strcmp(a, "/dev/openprom") == 0)
6073db86aabSstevel 		return (open(a, b, c));
6083db86aabSstevel 	return (0);
6093db86aabSstevel }
6103db86aabSstevel 
6113db86aabSstevel static int
sim_close(int a)612*13c31a0eSToomas Soome sim_close(int a)
613*13c31a0eSToomas Soome {
614*13c31a0eSToomas Soome 	return (0);
615*13c31a0eSToomas Soome }
6163db86aabSstevel 
6173db86aabSstevel static int
sim_ioctl(int fd,int cmd,void * a)6183db86aabSstevel sim_ioctl(int fd, int cmd, void *a)
6193db86aabSstevel {
6203db86aabSstevel 	printf("sim_ioctl(%d)\n", sim_idx);
6213db86aabSstevel 
6223db86aabSstevel 	switch (cmd) {
6233db86aabSstevel 	case SYSC_CFGA_CMD_CONNECT:
6243db86aabSstevel 		sim_sc_list[sim_idx].rstate = SYSC_CFGA_RSTATE_CONNECTED;
6253db86aabSstevel 		break;
6263db86aabSstevel 	case SYSC_CFGA_CMD_CONFIGURE:
6273db86aabSstevel 		sim_sc_list[sim_idx].ostate = SYSC_CFGA_OSTATE_CONFIGURED;
6283db86aabSstevel 		break;
6293db86aabSstevel 	case SYSC_CFGA_CMD_UNCONFIGURE:
6303db86aabSstevel 		sim_sc_list[sim_idx].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
6313db86aabSstevel 		break;
6323db86aabSstevel 	case SYSC_CFGA_CMD_DISCONNECT:
6333db86aabSstevel 		sim_sc_list[sim_idx].rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
6343db86aabSstevel 		break;
6353db86aabSstevel 	case SYSC_CFGA_CMD_QUIESCE_TEST:
6363db86aabSstevel 	case SYSC_CFGA_CMD_TEST:
6373db86aabSstevel 		return (0);
6383db86aabSstevel 	case OPROMGETOPT:
6393db86aabSstevel 		return (ioctl(fd, OPROMGETOPT, a));
6403db86aabSstevel 	case OPROMSETOPT:
6413db86aabSstevel 		return (ioctl(fd, OPROMSETOPT, a));
6423db86aabSstevel 	}
6433db86aabSstevel 
6443db86aabSstevel 	if (lseek(sim_fd, SEEK_SET, 0) == -1) {
6453db86aabSstevel 		perror("sim_seek");
6463db86aabSstevel 		exit(1);
6473db86aabSstevel 	}
6483db86aabSstevel 	if (write(sim_fd, sim_sc_list, sim_size) == -1) {
6493db86aabSstevel 		perror("sim_write");
6503db86aabSstevel 		exit(1);
6513db86aabSstevel 	}
6523db86aabSstevel 
6533db86aabSstevel 	return (0);
6543db86aabSstevel }
6553db86aabSstevel 
6563db86aabSstevel #define	open(a, b, c)	sim_open((char *)(a), (int)(b), (int)(c))
6573db86aabSstevel #define	close(a)	sim_close(a)
6583db86aabSstevel #define	ioctl(a, b, c)	sim_ioctl((int)(a), (int)(b), (void *)(c))
6593db86aabSstevel #define	sysc_stat(a, b)	sim_sysc_stat(a, b)
6603db86aabSstevel #endif	/* SIM */
6613db86aabSstevel 
6623db86aabSstevel static char *promdev = "/dev/openprom";
6633db86aabSstevel static char *dlprop = "disabled-board-list";
6643db86aabSstevel 
6653db86aabSstevel #define	BUFSIZE		128
6663db86aabSstevel 
6673db86aabSstevel typedef union {
6683db86aabSstevel 	char buf[BUFSIZE];
6693db86aabSstevel 	struct openpromio opp;
6703db86aabSstevel } oppbuf_t;
6713db86aabSstevel 
6723db86aabSstevel static int
prom_get_prop(int prom_fd,char * var,char ** val)6733db86aabSstevel prom_get_prop(int prom_fd, char *var, char **val)
6743db86aabSstevel {
6753db86aabSstevel 	static oppbuf_t oppbuf;
6763db86aabSstevel 	struct openpromio *opp = &(oppbuf.opp);
6773db86aabSstevel 
6783db86aabSstevel 	(void) strncpy(opp->oprom_array, var, OBP_MAXPROPNAME);
6793db86aabSstevel 	opp->oprom_array[OBP_MAXPROPNAME + 1] = '\0';
6803db86aabSstevel 	opp->oprom_size = BUFSIZE;
6813db86aabSstevel 
6823db86aabSstevel 	DBG3("getprop(%s, %d)\n", opp->oprom_array, opp->oprom_size);
6833db86aabSstevel 
6843db86aabSstevel 	if (ioctl(prom_fd, OPROMGETOPT, opp) < 0)
6853db86aabSstevel 		return (ERR_PROM_GETPROP);
6863db86aabSstevel 	else if (opp->oprom_size > 0)
6873db86aabSstevel 		*val = opp->oprom_array;
6883db86aabSstevel 	else
6893db86aabSstevel 		*val = NULL;
6903db86aabSstevel 
6913db86aabSstevel 	return (0);
6923db86aabSstevel }
6933db86aabSstevel 
6943db86aabSstevel static cfga_err_t
prom_set_prop(int prom_fd,char * var,char * val)6953db86aabSstevel prom_set_prop(int prom_fd, char *var, char *val)
6963db86aabSstevel {
6973db86aabSstevel 	oppbuf_t oppbuf;
6983db86aabSstevel 	struct openpromio *opp = &(oppbuf.opp);
6993db86aabSstevel 	int varlen = strlen(var) + 1;
7003db86aabSstevel 	int vallen = strlen(val);
7013db86aabSstevel 
7023db86aabSstevel 	DBG("prom_set_prop(%s)\n", val);
7033db86aabSstevel 
7043db86aabSstevel 	(void) strcpy(opp->oprom_array, var);
7053db86aabSstevel 	(void) strcpy(opp->oprom_array + varlen, val);
7063db86aabSstevel 	opp->oprom_size = varlen + vallen;
7073db86aabSstevel 
7083db86aabSstevel 	if (ioctl(prom_fd, OPROMSETOPT, opp) < 0)
7093db86aabSstevel 		return (ERR_PROM_SETPROP);
7103db86aabSstevel 
7113db86aabSstevel 	return (0);
7123db86aabSstevel }
7133db86aabSstevel 
7143db86aabSstevel static int
dlist_find(int board,char ** dlist,int * disabled)7153db86aabSstevel dlist_find(int board, char **dlist, int *disabled)
7163db86aabSstevel {
7173db86aabSstevel 	int i;
7183db86aabSstevel 	int err;
7193db86aabSstevel 	int prom_fd;
7203db86aabSstevel 	char *p;
7213db86aabSstevel 	char *dl;
7223db86aabSstevel 	char b[2];
7233db86aabSstevel 
7243db86aabSstevel 	if ((prom_fd = open(promdev, O_RDWR, 0)) < 0)
7253db86aabSstevel 		return (ERR_PROM_OPEN);
7263db86aabSstevel 	else if (err = prom_get_prop(prom_fd, dlprop, dlist)) {
7273db86aabSstevel 		(void) close(prom_fd);
7283db86aabSstevel 		return (err);
7293db86aabSstevel 	} else
7303db86aabSstevel 		(void) close(prom_fd);
7313db86aabSstevel 
7323db86aabSstevel 	b[1] = 0;
7333db86aabSstevel 	*disabled = 0;
7343db86aabSstevel 
7353db86aabSstevel 	if ((dl = *dlist) != NULL) {
7363db86aabSstevel 		int len = strlen(dl);
7373db86aabSstevel 
7383db86aabSstevel 		for (i = 0; i < len; i++) {
7393db86aabSstevel 			int bd;
7403db86aabSstevel 
7413db86aabSstevel 			b[0] = dl[i];
7423db86aabSstevel 			bd = strtol(b, &p, 16);
7433db86aabSstevel 
7443db86aabSstevel 			if (p != b && bd == board)
7453db86aabSstevel 				(*disabled)++;
7463db86aabSstevel 		}
7473db86aabSstevel 	}
7483db86aabSstevel 
7493db86aabSstevel 	return (0);
7503db86aabSstevel }
7513db86aabSstevel 
7523db86aabSstevel static int
dlist_update(int board,int disable,char * dlist,struct cfga_msg * msgp,int verbose)7533db86aabSstevel dlist_update(int board, int disable, char *dlist, struct cfga_msg *msgp,
754*13c31a0eSToomas Soome     int verbose)
7553db86aabSstevel {
7563db86aabSstevel 	int i, j, n;
7573db86aabSstevel 	int err;
7583db86aabSstevel 	int found;
7593db86aabSstevel 	int update;
7603db86aabSstevel 	int prom_fd;
7613db86aabSstevel 	char *p;
7623db86aabSstevel 	char b[2];
7633db86aabSstevel 	char ndlist[64];
7643db86aabSstevel 
7653db86aabSstevel 	b[1] = 0;
7663db86aabSstevel 	ndlist[0] = 0;
7673db86aabSstevel 	j = 0;
7683db86aabSstevel 	found = 0;
7693db86aabSstevel 	update = 0;
7703db86aabSstevel 
7713db86aabSstevel 	if ((prom_fd = open(promdev, O_RDWR, 0)) < 0)
7723db86aabSstevel 		return (ERR_PROM_OPEN);
7733db86aabSstevel 
7743db86aabSstevel 	if (dlist) {
7753db86aabSstevel 		int len = strlen(dlist);
7763db86aabSstevel 
7773db86aabSstevel 		for (i = 0; i < len; i++) {
7783db86aabSstevel 			int bd;
7793db86aabSstevel 
7803db86aabSstevel 			b[0] = dlist[i];
7813db86aabSstevel 			bd = strtol(b, &p, 16);
7823db86aabSstevel 
7833db86aabSstevel 			if (p != b && bd == board) {
7843db86aabSstevel 
7853db86aabSstevel 				found++;
7863db86aabSstevel 				if (disable) {
7873db86aabSstevel 					if (verbose)
7883db86aabSstevel 						cfga_msg(msgp, STR_BD,
7893db86aabSstevel 						    DIAG_WAS_DISABLED, 0);
7903db86aabSstevel 				} else {
7913db86aabSstevel 					if (verbose)
7923db86aabSstevel 						cfga_msg(msgp, STR_BD,
7933db86aabSstevel 						    DIAG_WILL_ENABLE, 0);
7943db86aabSstevel 					update++;
7953db86aabSstevel 					continue;
7963db86aabSstevel 				}
7973db86aabSstevel 			}
7983db86aabSstevel 			ndlist[j++] = dlist[i];
7993db86aabSstevel 		}
8003db86aabSstevel 		ndlist[j] = 0;
8013db86aabSstevel 	}
8023db86aabSstevel 
8033db86aabSstevel 	if (!found)
8043db86aabSstevel 		if (disable) {
8053db86aabSstevel 			if (verbose)
8063db86aabSstevel 				cfga_msg(msgp, STR_BD, DIAG_WILL_DISABLE, 0);
8073db86aabSstevel 			p = &ndlist[j];
8083db86aabSstevel 			n = sprintf(p, "%x", board);
8093db86aabSstevel 			p[n] = 0;
8103db86aabSstevel 			update++;
8113db86aabSstevel 		} else {
8123db86aabSstevel 			if (verbose)
8133db86aabSstevel 				cfga_msg(msgp, STR_BD, DIAG_WAS_ENABLED, 0);
8143db86aabSstevel 		}
8153db86aabSstevel 
8163db86aabSstevel 	if (update)
8173db86aabSstevel 		err = prom_set_prop(prom_fd, dlprop, ndlist);
8183db86aabSstevel 	else
8193db86aabSstevel 		err = 0;
8203db86aabSstevel 
8213db86aabSstevel 	(void) close(prom_fd);
8223db86aabSstevel 
8233db86aabSstevel 	return (err);
8243db86aabSstevel }
8253db86aabSstevel 
8263db86aabSstevel static int
ap_idx(const char * ap_id)8273db86aabSstevel ap_idx(const char *ap_id)
8283db86aabSstevel {
8293db86aabSstevel 	int id;
8303db86aabSstevel 	char *s;
8313db86aabSstevel 	static char *slot = "slot";
8323db86aabSstevel 
8333db86aabSstevel 	DBG("ap_idx(%s)\n", ap_id);
8343db86aabSstevel 
8353db86aabSstevel 	if ((s = strstr(ap_id, slot)) == NULL)
8363db86aabSstevel 		return (-1);
8373db86aabSstevel 	else {
8383db86aabSstevel 		int n;
8393db86aabSstevel 
8403db86aabSstevel 		s += strlen(slot);
8413db86aabSstevel 		n = strlen(s);
8423db86aabSstevel 
8433db86aabSstevel 		DBG3("ap_idx: s=%s, n=%d\n", s, n);
8443db86aabSstevel 
8453db86aabSstevel 		switch (n) {
8463db86aabSstevel 		case 2:
8473db86aabSstevel 			if (!isdigit(s[1]))
8483db86aabSstevel 				return (-1);
8493db86aabSstevel 		/* FALLTHROUGH */
8503db86aabSstevel 		case 1:
8513db86aabSstevel 			if (!isdigit(s[0]))
8523db86aabSstevel 				return (-1);
8533db86aabSstevel 			break;
8543db86aabSstevel 		default:
8553db86aabSstevel 			return (-1);
8563db86aabSstevel 		}
8573db86aabSstevel 	}
8583db86aabSstevel 
8593db86aabSstevel 	if ((id = atoi(s)) > MAX_BOARDS)
8603db86aabSstevel 		return (-1);
8613db86aabSstevel 
8623db86aabSstevel 	DBG3("ap_idx(%s)=%d\n", s, id);
8633db86aabSstevel 
8643db86aabSstevel 	return (id);
8653db86aabSstevel }
8663db86aabSstevel 
8673db86aabSstevel /*ARGSUSED*/
8683db86aabSstevel cfga_err_t
cfga_change_state(cfga_cmd_t state_change_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)8693db86aabSstevel cfga_change_state(
8703db86aabSstevel 	cfga_cmd_t state_change_cmd,
8713db86aabSstevel 	const char *ap_id,
8723db86aabSstevel 	const char *options,
8733db86aabSstevel 	struct cfga_confirm *confp,
8743db86aabSstevel 	struct cfga_msg *msgp,
8753db86aabSstevel 	char **errstring,
8763db86aabSstevel 	cfga_flags_t flags)
8773db86aabSstevel {
8783db86aabSstevel 	int fd;
8793db86aabSstevel 	int idx;
8803db86aabSstevel 	int err;
8813db86aabSstevel 	int force;
8823db86aabSstevel 	int verbose;
8833db86aabSstevel 	int opterr;
8843db86aabSstevel 	int disable;
8853db86aabSstevel 	int disabled;
8863db86aabSstevel 	cfga_err_t rc;
8873db86aabSstevel 	sysc_cfga_stat_t *ss;
8883db86aabSstevel 	sysc_cfga_cmd_t *sc, sysc_cmd;
8893db86aabSstevel 	sysc_cfga_rstate_t rs;
8903db86aabSstevel 	sysc_cfga_ostate_t os;
8913db86aabSstevel 	char *dlist;
8923db86aabSstevel 	char outputstr[SYSC_OUTPUT_LEN];
8933db86aabSstevel 
8943db86aabSstevel 	if (errstring != NULL)
8953db86aabSstevel 		*errstring = NULL;
8963db86aabSstevel 
8973db86aabSstevel 	rc = CFGA_ERROR;
8983db86aabSstevel 
8993db86aabSstevel 	if (options) {
9003db86aabSstevel 		disable = 0;
9013db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
9023db86aabSstevel 			disable++;
9033db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
9043db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
9053db86aabSstevel 			return (rc);
9063db86aabSstevel 		}
9073db86aabSstevel 	}
9083db86aabSstevel 
9093db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1) {
9103db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
9113db86aabSstevel 		return (rc);
9123db86aabSstevel 	} else if ((ss = sysc_stat(ap_id, &fd)) == NULL) {
9133db86aabSstevel 		cfga_err(NULL, errstring, CMD_GETSTAT, 0);
9143db86aabSstevel 		return (rc);
9153db86aabSstevel 	}
9163db86aabSstevel #ifdef	SIM
9173db86aabSstevel 	sim_idx = idx;
9183db86aabSstevel #endif
9193db86aabSstevel 	/*
9203db86aabSstevel 	 * We disallow connecting on the disabled list unless
9213db86aabSstevel 	 * either the FORCE flag or the enable-at-boot option
9223db86aabSstevel 	 * is set. The check is made further below
9233db86aabSstevel 	 */
9243db86aabSstevel 	if (opterr = dlist_find(idx, &dlist, &disabled)) {
9253db86aabSstevel 		err = disable ? OPT_DISABLE : OPT_ENABLE;
9263db86aabSstevel 		cfga_err(NULL, errstring, err, opterr, 0);
9273db86aabSstevel 		(void) close(fd);
9283db86aabSstevel 		return (rc);
9293db86aabSstevel 	} else
9303db86aabSstevel 		force = flags & CFGA_FLAG_FORCE;
9313db86aabSstevel 
9323db86aabSstevel 	rs = ss[idx].rstate;
9333db86aabSstevel 	os = ss[idx].ostate;
9343db86aabSstevel 
9353db86aabSstevel 	sc = &sysc_cmd;
9363db86aabSstevel 	sysc_cmd_init(sc, outputstr, force);
9373db86aabSstevel 	verbose = flags & CFGA_FLAG_VERBOSE;
9383db86aabSstevel 
9393db86aabSstevel 	switch (state_change_cmd) {
9403db86aabSstevel 	case CFGA_CMD_CONNECT:
9413db86aabSstevel 		if (rs != SYSC_CFGA_RSTATE_DISCONNECTED)
9423db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
9433db86aabSstevel 		else if (disabled && !(force || (options && !disable)))
9443db86aabSstevel 			cfga_err(NULL, errstring, CMD_CONNECT,
945*13c31a0eSToomas Soome 			    ERR_DISABLED, DIAG_FORCE, 0);
9463db86aabSstevel 		else if (!(*confp->confirm)(confp->appdata_ptr,
9473db86aabSstevel 		    cfga_str(ASK_CONNECT))) {
9483db86aabSstevel 			(void) close(fd);
9493db86aabSstevel 			return (CFGA_NACK);
9503db86aabSstevel 		} else if (ioctl(fd, SYSC_CFGA_CMD_CONNECT, sc) == -1)
9513db86aabSstevel 			cfga_err(sc, errstring, CMD_CONNECT, 0);
9523db86aabSstevel 		else if (options && (opterr = dlist_update(idx, disable,
953*13c31a0eSToomas Soome 		    dlist, msgp, verbose))) {
9543db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
9553db86aabSstevel 			cfga_err(NULL, errstring, err, opterr, 0);
9563db86aabSstevel 		} else
9573db86aabSstevel 			rc = CFGA_OK;
9583db86aabSstevel 		break;
9593db86aabSstevel 
9603db86aabSstevel 	case CFGA_CMD_DISCONNECT:
9613db86aabSstevel 		if ((os == SYSC_CFGA_OSTATE_CONFIGURED) &&
9623db86aabSstevel 		    (ioctl(fd, SYSC_CFGA_CMD_UNCONFIGURE, sc) == -1)) {
9633db86aabSstevel 			cfga_err(sc, errstring, CMD_UNCONFIGURE, 0);
9643db86aabSstevel 			(void) close(fd);
9653db86aabSstevel 			return (CFGA_ERROR);
9663db86aabSstevel 		} else
9673db86aabSstevel 			sysc_cmd_init(sc, outputstr, force);
9683db86aabSstevel 
9693db86aabSstevel 		if (rs == SYSC_CFGA_RSTATE_CONNECTED) {
9703db86aabSstevel 			if (ioctl(fd, SYSC_CFGA_CMD_DISCONNECT, sc) == -1)
9713db86aabSstevel 				cfga_err(sc, errstring, CMD_DISCONNECT, 0);
9723db86aabSstevel 			else if (options && (opterr = dlist_update(idx, disable,
9733db86aabSstevel 			    dlist, msgp, verbose))) {
9743db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
9753db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
9763db86aabSstevel 			} else
9773db86aabSstevel 				rc = CFGA_OK;
9783db86aabSstevel 		} else
9793db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
9803db86aabSstevel 		break;
9813db86aabSstevel 
9823db86aabSstevel 	case CFGA_CMD_CONFIGURE:
9833db86aabSstevel 		if (rs == SYSC_CFGA_RSTATE_DISCONNECTED)
9843db86aabSstevel 			if (disabled && !(force || (options && !disable))) {
9853db86aabSstevel 				cfga_err(NULL, errstring, CMD_CONFIGURE,
986*13c31a0eSToomas Soome 				    ERR_DISABLED, DIAG_FORCE, 0);
9873db86aabSstevel 				(void) close(fd);
9883db86aabSstevel 				return (CFGA_ERROR);
9893db86aabSstevel 			} else if (!(*confp->confirm)(confp->appdata_ptr,
9903db86aabSstevel 			    cfga_str(ASK_CONNECT))) {
9913db86aabSstevel 				(void) close(fd);
9923db86aabSstevel 				return (CFGA_NACK);
9933db86aabSstevel 			} else if (ioctl(fd, SYSC_CFGA_CMD_CONNECT, sc) == -1) {
9943db86aabSstevel 				cfga_err(sc, errstring, CMD_CONNECT, 0);
9953db86aabSstevel 				(void) close(fd);
9963db86aabSstevel 				return (CFGA_ERROR);
9973db86aabSstevel 			} else
9983db86aabSstevel 				sysc_cmd_init(sc, outputstr, force);
9993db86aabSstevel 
10003db86aabSstevel 		if (os == SYSC_CFGA_OSTATE_UNCONFIGURED) {
10013db86aabSstevel 			if (ioctl(fd, SYSC_CFGA_CMD_CONFIGURE, sc) == -1)
10023db86aabSstevel 				cfga_err(sc, errstring, CMD_CONFIGURE, 0);
10033db86aabSstevel 			else if (options && (opterr = dlist_update(idx,
1004*13c31a0eSToomas Soome 			    disable, dlist, msgp, verbose))) {
10053db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
10063db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
10073db86aabSstevel 			} else
10083db86aabSstevel 				rc = CFGA_OK;
10093db86aabSstevel 		} else
10103db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
10113db86aabSstevel 		break;
10123db86aabSstevel 
10133db86aabSstevel 	case CFGA_CMD_UNCONFIGURE:
10143db86aabSstevel 		if (os != SYSC_CFGA_OSTATE_CONFIGURED)
10153db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
10163db86aabSstevel 		else if (ioctl(fd, SYSC_CFGA_CMD_UNCONFIGURE, sc) == -1)
10173db86aabSstevel 			cfga_err(sc, errstring, CMD_UNCONFIGURE, 0);
10183db86aabSstevel 		else if (options && (opterr = dlist_update(idx, disable,
1019*13c31a0eSToomas Soome 		    dlist, msgp, verbose))) {
10203db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
10213db86aabSstevel 			cfga_err(NULL, errstring, err, opterr, 0);
10223db86aabSstevel 		} else
10233db86aabSstevel 			rc = CFGA_OK;
10243db86aabSstevel 		break;
10253db86aabSstevel 
10263db86aabSstevel 	default:
10273db86aabSstevel 		rc = CFGA_OPNOTSUPP;
10283db86aabSstevel 		break;
10293db86aabSstevel 	}
10303db86aabSstevel 
10313db86aabSstevel 	(void) close(fd);
10323db86aabSstevel 	return (rc);
10333db86aabSstevel }
10343db86aabSstevel 
10353db86aabSstevel static int
str2cond(const char * cond)10363db86aabSstevel str2cond(const char *cond)
10373db86aabSstevel {
10383db86aabSstevel 	int c;
10393db86aabSstevel 
10403db86aabSstevel 	if (strcmp(cond, cfga_str(COND_UNKNOWN)) == 0)
10413db86aabSstevel 		c =  SYSC_CFGA_COND_UNKNOWN;
10423db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_OK)) == 0)
10433db86aabSstevel 		c =  SYSC_CFGA_COND_OK;
10443db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_FAILING)) == 0)
10453db86aabSstevel 		c =  SYSC_CFGA_COND_FAILING;
10463db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_FAILED)) == 0)
10473db86aabSstevel 		c =  SYSC_CFGA_COND_FAILED;
10483db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_UNUSABLE)) == 0)
10493db86aabSstevel 		c =  SYSC_CFGA_COND_UNUSABLE;
10503db86aabSstevel 	else
10513db86aabSstevel 		c = -1;
10523db86aabSstevel 
10533db86aabSstevel 	return (c);
10543db86aabSstevel }
10553db86aabSstevel 
10563db86aabSstevel /*ARGSUSED*/
10573db86aabSstevel cfga_err_t
cfga_private_func(const char * function,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)10583db86aabSstevel cfga_private_func(
10593db86aabSstevel 	const char *function,
10603db86aabSstevel 	const char *ap_id,
10613db86aabSstevel 	const char *options,
10623db86aabSstevel 	struct cfga_confirm *confp,
10633db86aabSstevel 	struct cfga_msg *msgp,
10643db86aabSstevel 	char **errstring,
10653db86aabSstevel 	cfga_flags_t flags)
10663db86aabSstevel {
10673db86aabSstevel 	int fd;
10683db86aabSstevel 	int idx;
10693db86aabSstevel 	int len;
10703db86aabSstevel 	int cmd;
10713db86aabSstevel 	int cond;
10723db86aabSstevel 	int err;
10733db86aabSstevel 	int opterr;
10743db86aabSstevel 	int verbose;
10753db86aabSstevel 	int disable;
10763db86aabSstevel 	int disabled;
10773db86aabSstevel 	cfga_err_t rc;
10783db86aabSstevel 	char *str;
10793db86aabSstevel 	char *dlist;
10803db86aabSstevel 	char outputstr[SYSC_OUTPUT_LEN];
10813db86aabSstevel 	sysc_cfga_cmd_t *sc, sysc_cmd;
10823db86aabSstevel 
10833db86aabSstevel 	if (errstring != NULL)
10843db86aabSstevel 		*errstring = NULL;
10853db86aabSstevel 
10863db86aabSstevel 	verbose = flags & CFGA_FLAG_VERBOSE;
10873db86aabSstevel 
10883db86aabSstevel 	rc = CFGA_ERROR;
10893db86aabSstevel 
10903db86aabSstevel 	if (options) {
10913db86aabSstevel 		disable = 0;
10923db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
10933db86aabSstevel 			disable++;
10943db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
10953db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
10963db86aabSstevel 			return (rc);
10973db86aabSstevel 		}
10983db86aabSstevel 	}
10993db86aabSstevel 
11003db86aabSstevel 	sc = &sysc_cmd;
11013db86aabSstevel 	str = cfga_str(CMD_SET_COND);
11023db86aabSstevel 	len = strlen(str);
11033db86aabSstevel 
11043db86aabSstevel 	if ((strncmp(function, str, len) == 0) && (function[len++] == '=') &&
11053db86aabSstevel 	    ((cond = (str2cond(&function[len]))) != -1)) {
11063db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST_SET_COND;
11073db86aabSstevel 		err = CMD_SET_COND;
11083db86aabSstevel 		sc->arg = cond;
11093db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_QUIESCE)) == 0) {
11103db86aabSstevel 		cmd = SYSC_CFGA_CMD_QUIESCE_TEST;
11113db86aabSstevel 		err = CMD_QUIESCE;
11123db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_INSERT)) == 0) {
11133db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST;
11143db86aabSstevel 		err = CMD_INSERT;
11153db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_REMOVE)) == 0) {
11163db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST;
11173db86aabSstevel 		err = CMD_REMOVE;
11183db86aabSstevel 	} else {
11193db86aabSstevel 		cfga_err(NULL, errstring, ERR_CMD_INVAL, (char *)function, 0);
11203db86aabSstevel 		return (rc);
11213db86aabSstevel 	}
11223db86aabSstevel 
11233db86aabSstevel 	sysc_cmd_init(sc, outputstr, 0);
11243db86aabSstevel 
11253db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1)
11263db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
11273db86aabSstevel 	else if (((fd = open(ap_id, O_RDWR, 0)) == -1) ||
1128*13c31a0eSToomas Soome 	    (ioctl(fd, cmd, sc) == -1))
11293db86aabSstevel 		cfga_err(NULL, errstring, err, 0);
11303db86aabSstevel 	else
11313db86aabSstevel 		rc = CFGA_OK;
11323db86aabSstevel 
11333db86aabSstevel 	if (options) {
11343db86aabSstevel 		opterr = (dlist_find(idx, &dlist, &disabled) ||
1135*13c31a0eSToomas Soome 		    dlist_update(idx, disable, dlist, msgp, verbose));
11363db86aabSstevel 		if (opterr) {
11373db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
11383db86aabSstevel 			if (verbose)
11393db86aabSstevel 				cfga_msg(msgp, err, opterr, 0);
11403db86aabSstevel 		}
11413db86aabSstevel 	}
11423db86aabSstevel 
11433db86aabSstevel 	(void) close(fd);
11443db86aabSstevel 	return (rc);
11453db86aabSstevel }
11463db86aabSstevel 
11473db86aabSstevel 
11483db86aabSstevel /*ARGSUSED*/
11493db86aabSstevel cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)11503db86aabSstevel cfga_test(
11513db86aabSstevel 	const char *ap_id,
11523db86aabSstevel 	const char *options,
11533db86aabSstevel 	struct cfga_msg *msgp,
11543db86aabSstevel 	char **errstring,
11553db86aabSstevel 	cfga_flags_t flags)
11563db86aabSstevel {
11573db86aabSstevel 	if (errstring != NULL)
11583db86aabSstevel 		*errstring = NULL;
11593db86aabSstevel 
11603db86aabSstevel 	return (CFGA_OPNOTSUPP);
11613db86aabSstevel }
11623db86aabSstevel 
11633db86aabSstevel static cfga_stat_t
rstate_cvt(sysc_cfga_rstate_t rs)11643db86aabSstevel rstate_cvt(sysc_cfga_rstate_t rs)
11653db86aabSstevel {
11663db86aabSstevel 	cfga_stat_t cs;
11673db86aabSstevel 
11683db86aabSstevel 	switch (rs) {
11693db86aabSstevel 	case SYSC_CFGA_RSTATE_EMPTY:
11703db86aabSstevel 		cs = CFGA_STAT_EMPTY;
11713db86aabSstevel 		break;
11723db86aabSstevel 	case SYSC_CFGA_RSTATE_DISCONNECTED:
11733db86aabSstevel 		cs = CFGA_STAT_DISCONNECTED;
11743db86aabSstevel 		break;
11753db86aabSstevel 	case SYSC_CFGA_RSTATE_CONNECTED:
11763db86aabSstevel 		cs = CFGA_STAT_CONNECTED;
11773db86aabSstevel 		break;
11783db86aabSstevel 	default:
11793db86aabSstevel 		cs = CFGA_STAT_NONE;
11803db86aabSstevel 		break;
11813db86aabSstevel 	}
11823db86aabSstevel 
11833db86aabSstevel 	return (cs);
11843db86aabSstevel }
11853db86aabSstevel 
11863db86aabSstevel static cfga_stat_t
ostate_cvt(sysc_cfga_ostate_t os)11873db86aabSstevel ostate_cvt(sysc_cfga_ostate_t os)
11883db86aabSstevel {
11893db86aabSstevel 	cfga_stat_t cs;
11903db86aabSstevel 
11913db86aabSstevel 	switch (os) {
11923db86aabSstevel 	case SYSC_CFGA_OSTATE_UNCONFIGURED:
11933db86aabSstevel 		cs = CFGA_STAT_UNCONFIGURED;
11943db86aabSstevel 		break;
11953db86aabSstevel 	case SYSC_CFGA_OSTATE_CONFIGURED:
11963db86aabSstevel 		cs = CFGA_STAT_CONFIGURED;
11973db86aabSstevel 		break;
11983db86aabSstevel 	default:
11993db86aabSstevel 		cs = CFGA_STAT_NONE;
12003db86aabSstevel 		break;
12013db86aabSstevel 	}
12023db86aabSstevel 
12033db86aabSstevel 	return (cs);
12043db86aabSstevel }
12053db86aabSstevel 
12063db86aabSstevel static cfga_cond_t
cond_cvt(sysc_cfga_cond_t sc)12073db86aabSstevel cond_cvt(sysc_cfga_cond_t sc)
12083db86aabSstevel {
12093db86aabSstevel 	cfga_cond_t cc;
12103db86aabSstevel 
12113db86aabSstevel 	switch (sc) {
12123db86aabSstevel 	case SYSC_CFGA_COND_OK:
12133db86aabSstevel 		cc = CFGA_COND_OK;
12143db86aabSstevel 		break;
12153db86aabSstevel 	case SYSC_CFGA_COND_FAILING:
12163db86aabSstevel 		cc = CFGA_COND_FAILING;
12173db86aabSstevel 		break;
12183db86aabSstevel 	case SYSC_CFGA_COND_FAILED:
12193db86aabSstevel 		cc = CFGA_COND_FAILED;
12203db86aabSstevel 		break;
12213db86aabSstevel 	case SYSC_CFGA_COND_UNUSABLE:
12223db86aabSstevel 		cc = CFGA_COND_UNUSABLE;
12233db86aabSstevel 		break;
12243db86aabSstevel 	case SYSC_CFGA_COND_UNKNOWN:
12253db86aabSstevel 	default:
12263db86aabSstevel 		cc = CFGA_COND_UNKNOWN;
12273db86aabSstevel 		break;
12283db86aabSstevel 	}
12293db86aabSstevel 
12303db86aabSstevel 	return (cc);
12313db86aabSstevel }
12323db86aabSstevel 
12333db86aabSstevel static char *
type_str(enum board_type type)12343db86aabSstevel type_str(enum board_type type)
12353db86aabSstevel {
12363db86aabSstevel 	char *type_str;
12373db86aabSstevel 
12383db86aabSstevel 	switch (type) {
12393db86aabSstevel 	case MEM_BOARD:
12403db86aabSstevel 		type_str = cfga_str(BD_MEM);
12413db86aabSstevel 		break;
12423db86aabSstevel 	case CPU_BOARD:
12433db86aabSstevel 		type_str = cfga_str(BD_CPU);
12443db86aabSstevel 		break;
12453db86aabSstevel 	case IO_2SBUS_BOARD:
12463db86aabSstevel 		type_str = cfga_str(BD_IO_2SBUS);
12473db86aabSstevel 		break;
12483db86aabSstevel 	case IO_SBUS_FFB_BOARD:
12493db86aabSstevel 		type_str = cfga_str(BD_IO_SBUS_FFB);
12503db86aabSstevel 		break;
12513db86aabSstevel 	case IO_PCI_BOARD:
12523db86aabSstevel 		type_str = cfga_str(BD_IO_PCI);
12533db86aabSstevel 		break;
12543db86aabSstevel 	case DISK_BOARD:
12553db86aabSstevel 		type_str = cfga_str(BD_DISK);
12563db86aabSstevel 		break;
12573db86aabSstevel 	case IO_2SBUS_SOCPLUS_BOARD:
12583db86aabSstevel 		type_str = cfga_str(BD_IO_2SBUS_SOCPLUS);
12593db86aabSstevel 		break;
12603db86aabSstevel 	case IO_SBUS_FFB_SOCPLUS_BOARD:
12613db86aabSstevel 		type_str = cfga_str(BD_IO_SBUS_FFB_SOCPLUS);
12623db86aabSstevel 		break;
12633db86aabSstevel 	case UNKNOWN_BOARD:
12643db86aabSstevel 	default:
12653db86aabSstevel 		type_str = cfga_str(BD_UNKNOWN);
12663db86aabSstevel 		break;
12673db86aabSstevel 	}
12683db86aabSstevel 	return (type_str);
12693db86aabSstevel }
12703db86aabSstevel 
12713db86aabSstevel static void
info_set(sysc_cfga_stat_t * sc,cfga_info_t info,int disabled)12723db86aabSstevel info_set(sysc_cfga_stat_t *sc, cfga_info_t info, int disabled)
12733db86aabSstevel {
12743db86aabSstevel 	int i;
12753db86aabSstevel 	struct cpu_info *cpu;
12763db86aabSstevel 	union bd_un *bd = &sc->bd;
12773db86aabSstevel 
1278*13c31a0eSToomas Soome 	*info = '\0';
12793db86aabSstevel 
12803db86aabSstevel 	switch (sc->type) {
12813db86aabSstevel 	case CPU_BOARD:
12823db86aabSstevel 		for (i = 0, cpu = bd->cpu; i < 2; i++, cpu++) {
12833db86aabSstevel 			if (cpu->cpu_speed > 1) {
12843db86aabSstevel 				info += sprintf(info, "cpu %d: ", i);
12853db86aabSstevel 				info += sprintf(info, "%3d MHz ",
1286*13c31a0eSToomas Soome 				    cpu->cpu_speed);
12873db86aabSstevel 				if (cpu->cache_size)
12883db86aabSstevel 					info += sprintf(info, "%0.1fM ",
1289*13c31a0eSToomas Soome 					    (float)cpu->cache_size /
1290*13c31a0eSToomas Soome 					    (float)(1024 * 1024));
12913db86aabSstevel 			}
12923db86aabSstevel 		}
12933db86aabSstevel 		break;
12943db86aabSstevel 	case IO_SBUS_FFB_BOARD:
12953db86aabSstevel 		switch (bd->io2.ffb_size) {
12963db86aabSstevel 		case FFB_SINGLE:
12973db86aabSstevel 			info += sprintf(info, "single buffered ffb   ");
12983db86aabSstevel 			break;
12993db86aabSstevel 		case FFB_DOUBLE:
13003db86aabSstevel 			info += sprintf(info, "double buffered ffb   ");
13013db86aabSstevel 			break;
13023db86aabSstevel 		case FFB_NOT_FOUND:
13033db86aabSstevel #ifdef FFB_DR_SUPPORT
13043db86aabSstevel 			info += sprintf(info, "no ffb installed   ");
13053db86aabSstevel #endif
13063db86aabSstevel 			break;
13073db86aabSstevel 		default:
13083db86aabSstevel 			info += sprintf(info, "illegal ffb size   ");
13093db86aabSstevel 			break;
13103db86aabSstevel 		}
13113db86aabSstevel 		break;
13123db86aabSstevel 	case DISK_BOARD:
13133db86aabSstevel 		for (i = 0; i < 2; i++)
13143db86aabSstevel 			if (bd->dsk.disk_pres[i])
13153db86aabSstevel 				info += sprintf(info, "target: %2d ",
1316*13c31a0eSToomas Soome 				    bd->dsk.disk_id[i]);
13173db86aabSstevel 			else
13183db86aabSstevel 				info += sprintf(info, "no disk   ");
13193db86aabSstevel 		break;
13203db86aabSstevel 	}
13213db86aabSstevel 
13223db86aabSstevel 	if (disabled)
13233db86aabSstevel 		info += sprintf(info, "disabled at boot   ");
13243db86aabSstevel 
13253db86aabSstevel 	if (sc->no_detach)
13263db86aabSstevel 		info += sprintf(info, "non-detachable   ");
13273db86aabSstevel 
13283db86aabSstevel 	if (sc->plus_board)
13293db86aabSstevel 		info += sprintf(info, "100 MHz capable   ");
13303db86aabSstevel }
13313db86aabSstevel 
13323db86aabSstevel static void
sysc_cvt(sysc_cfga_stat_t * sc,cfga_stat_data_t * cs,int disabled)13333db86aabSstevel sysc_cvt(sysc_cfga_stat_t *sc, cfga_stat_data_t *cs, int disabled)
13343db86aabSstevel {
13353db86aabSstevel 	(void) strcpy(cs->ap_type, type_str(sc->type));
13363db86aabSstevel 	cs->ap_r_state = rstate_cvt(sc->rstate);
13373db86aabSstevel 	cs->ap_o_state = ostate_cvt(sc->ostate);
13383db86aabSstevel 	cs->ap_cond = cond_cvt(sc->condition);
13393db86aabSstevel 	cs->ap_busy = (cfga_busy_t)sc->in_transition;
13403db86aabSstevel 	cs->ap_status_time = sc->last_change;
13413db86aabSstevel 	info_set(sc, cs->ap_info, disabled);
1342*13c31a0eSToomas Soome 	cs->ap_log_id[0] = '\0';
1343*13c31a0eSToomas Soome 	cs->ap_phys_id[0] = '\0';
13443db86aabSstevel }
13453db86aabSstevel 
13463db86aabSstevel /*ARGSUSED*/
13473db86aabSstevel cfga_err_t
cfga_list(const char * ap_id,cfga_stat_data_t ** ap_list,int * nlist,const char * options,char ** errstring)13483db86aabSstevel cfga_list(
13493db86aabSstevel 	const char *ap_id,
13503db86aabSstevel 	cfga_stat_data_t **ap_list,
13513db86aabSstevel 	int *nlist,
13523db86aabSstevel 	const char *options,
13533db86aabSstevel 	char **errstring)
13543db86aabSstevel {
13553db86aabSstevel 	int i;
13563db86aabSstevel 	cfga_err_t rc;
13573db86aabSstevel 	sysc_cfga_stat_t *sc;
13583db86aabSstevel 	cfga_stat_data_t *cs;
13593db86aabSstevel 
13603db86aabSstevel 	if (errstring != NULL)
13613db86aabSstevel 		*errstring = NULL;
13623db86aabSstevel 
13633db86aabSstevel 	rc = CFGA_ERROR;
13643db86aabSstevel 
13653db86aabSstevel 	if (ap_idx(ap_id) == -1)
13663db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
13673db86aabSstevel 	else if ((sc = sysc_stat(ap_id, NULL)) == NULL)
13683db86aabSstevel 		cfga_err(NULL, errstring, CMD_LIST, 0);
13693db86aabSstevel 	else if (!(cs = (cfga_stat_data_t *)malloc(MAX_BOARDS * sizeof (*cs))))
13703db86aabSstevel 		cfga_err(NULL, errstring, CMD_LIST, 0);
13713db86aabSstevel 	else {
13723db86aabSstevel 		*ap_list = cs;
13733db86aabSstevel 
13743db86aabSstevel 		for (*nlist = 0, i = 0; i < MAX_BOARDS; i++, sc++) {
13753db86aabSstevel 			if (sc->board == -1)
13763db86aabSstevel 				continue;
13773db86aabSstevel 			sysc_cvt(sc, cs++, 0); /* XXX - disable */
13783db86aabSstevel 			(*nlist)++;
13793db86aabSstevel 		}
13803db86aabSstevel 
13813db86aabSstevel 		rc = CFGA_OK;
13823db86aabSstevel 	}
13833db86aabSstevel 
13843db86aabSstevel 	return (rc);
13853db86aabSstevel }
13863db86aabSstevel 
13873db86aabSstevel /*ARGSUSED*/
13883db86aabSstevel cfga_err_t
cfga_stat(const char * ap_id,struct cfga_stat_data * cs,const char * options,char ** errstring)13893db86aabSstevel cfga_stat(
13903db86aabSstevel 	const char *ap_id,
13913db86aabSstevel 	struct cfga_stat_data *cs,
13923db86aabSstevel 	const char *options,
13933db86aabSstevel 	char **errstring)
13943db86aabSstevel {
13953db86aabSstevel 	cfga_err_t rc;
13963db86aabSstevel 	int idx;
13973db86aabSstevel 	int err;
13983db86aabSstevel 	int opterr;
13993db86aabSstevel 	int disable;
14003db86aabSstevel 	int disabled;
14013db86aabSstevel 	char *dlist;
14023db86aabSstevel 	sysc_cfga_stat_t *sc;
14033db86aabSstevel 
14043db86aabSstevel 	if (errstring != NULL)
14053db86aabSstevel 		*errstring = NULL;
14063db86aabSstevel 
14073db86aabSstevel 	rc = CFGA_ERROR;
14083db86aabSstevel 
14093db86aabSstevel 	if (options && options[0]) {
14103db86aabSstevel 		disable = 0;
14113db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
14123db86aabSstevel 			disable++;
14133db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
14143db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
14153db86aabSstevel 			return (rc);
14163db86aabSstevel 		}
14173db86aabSstevel 	}
14183db86aabSstevel 
14193db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1)
14203db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
14213db86aabSstevel 	else if ((sc = sysc_stat(ap_id, NULL)) == NULL)
14223db86aabSstevel 		cfga_err(NULL, errstring, CMD_GETSTAT, 0);
14233db86aabSstevel 	else {
14243db86aabSstevel 		opterr = dlist_find(idx, &dlist, &disabled);
14253db86aabSstevel 		sysc_cvt(sc + idx, cs, disabled);
14263db86aabSstevel 
14273db86aabSstevel 		rc = CFGA_OK;
14283db86aabSstevel 
14293db86aabSstevel 		if (options && options[0] && ((opterr != 0) ||
1430*13c31a0eSToomas Soome 		    ((opterr = dlist_update(idx, disable, dlist, NULL, 0))
1431*13c31a0eSToomas Soome 		    != 0))) {
14323db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
14333db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
14343db86aabSstevel 		}
14353db86aabSstevel 	}
14363db86aabSstevel 
14373db86aabSstevel 	return (rc);
14383db86aabSstevel }
14393db86aabSstevel 
14403db86aabSstevel /*ARGSUSED*/
14413db86aabSstevel cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)14423db86aabSstevel cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
14433db86aabSstevel {
14443db86aabSstevel 	int help = 0;
14453db86aabSstevel 
14463db86aabSstevel 	if (options) {
14473db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
14483db86aabSstevel 			help = HELP_DISABLE;
14493db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE)) == 0)
14503db86aabSstevel 			help = HELP_ENABLE;
14513db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_INSERT)) == 0)
14523db86aabSstevel 			help = HELP_INSERT;
14533db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_REMOVE)) == 0)
14543db86aabSstevel 			help = HELP_REMOVE;
14553db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_QUIESCE)) == 0)
14563db86aabSstevel 			help = HELP_QUIESCE;
14573db86aabSstevel 		else
14583db86aabSstevel 			help = HELP_UNKNOWN;
14593db86aabSstevel 	}
14603db86aabSstevel 
14613db86aabSstevel 	if (help)  {
14623db86aabSstevel 		if (help == HELP_UNKNOWN)
14633db86aabSstevel 			cfga_msg(msgp, help, options, 0);
14643db86aabSstevel 		else
14653db86aabSstevel 			cfga_msg(msgp, help, 0);
14663db86aabSstevel 	} else {
14673db86aabSstevel 		cfga_msg(msgp, HELP_HEADER, 0);
14683db86aabSstevel 		cfga_msg(msgp, HELP_DISABLE, 0);
14693db86aabSstevel 		cfga_msg(msgp, HELP_ENABLE, 0);
14703db86aabSstevel 		cfga_msg(msgp, HELP_INSERT, 0);
14713db86aabSstevel 		cfga_msg(msgp, HELP_REMOVE, 0);
14723db86aabSstevel 		cfga_msg(msgp, HELP_QUIESCE, 0);
14733db86aabSstevel 		cfga_msg(msgp, HELP_SET_COND, 0);
14743db86aabSstevel 	}
14753db86aabSstevel 
14763db86aabSstevel 	return (CFGA_OK);
14773db86aabSstevel }
14783db86aabSstevel 
14793db86aabSstevel /*
14803db86aabSstevel  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
14813db86aabSstevel  */
1482