xref: /titanic_52/usr/src/lib/cfgadm_plugins/sysctrl/common/cfga.c (revision 3db86aab554edbb4244c8d1a1c90f152eee768af)
1*3db86aabSstevel /*
2*3db86aabSstevel  * CDDL HEADER START
3*3db86aabSstevel  *
4*3db86aabSstevel  * The contents of this file are subject to the terms of the
5*3db86aabSstevel  * Common Development and Distribution License, Version 1.0 only
6*3db86aabSstevel  * (the "License").  You may not use this file except in compliance
7*3db86aabSstevel  * with the License.
8*3db86aabSstevel  *
9*3db86aabSstevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*3db86aabSstevel  * or http://www.opensolaris.org/os/licensing.
11*3db86aabSstevel  * See the License for the specific language governing permissions
12*3db86aabSstevel  * and limitations under the License.
13*3db86aabSstevel  *
14*3db86aabSstevel  * When distributing Covered Code, include this CDDL HEADER in each
15*3db86aabSstevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*3db86aabSstevel  * If applicable, add the following below this CDDL HEADER, with the
17*3db86aabSstevel  * fields enclosed by brackets "[]" replaced with your own identifying
18*3db86aabSstevel  * information: Portions Copyright [yyyy] [name of copyright owner]
19*3db86aabSstevel  *
20*3db86aabSstevel  * CDDL HEADER END
21*3db86aabSstevel  */
22*3db86aabSstevel /*
23*3db86aabSstevel  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*3db86aabSstevel  * Use is subject to license terms.
25*3db86aabSstevel  */
26*3db86aabSstevel 
27*3db86aabSstevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*3db86aabSstevel 
29*3db86aabSstevel #include <stddef.h>
30*3db86aabSstevel #include <locale.h>
31*3db86aabSstevel #include <ctype.h>
32*3db86aabSstevel #include <stdio.h>
33*3db86aabSstevel #include <stdlib.h>
34*3db86aabSstevel #include <string.h>
35*3db86aabSstevel #include <fcntl.h>
36*3db86aabSstevel #include <unistd.h>
37*3db86aabSstevel #include <errno.h>
38*3db86aabSstevel #include <locale.h>
39*3db86aabSstevel #include <langinfo.h>
40*3db86aabSstevel #include <time.h>
41*3db86aabSstevel #include <stdarg.h>
42*3db86aabSstevel #include <sys/types.h>
43*3db86aabSstevel #include <sys/ioctl.h>
44*3db86aabSstevel #include <sys/dditypes.h>
45*3db86aabSstevel #include <sys/modctl.h>
46*3db86aabSstevel #include <sys/obpdefs.h>
47*3db86aabSstevel #include <sys/fhc.h>
48*3db86aabSstevel #include <sys/sysctrl.h>
49*3db86aabSstevel #include <sys/openpromio.h>
50*3db86aabSstevel #ifdef	SIM
51*3db86aabSstevel #include <sys/stat.h>
52*3db86aabSstevel #endif
53*3db86aabSstevel #define	CFGA_PLUGIN_LIB
54*3db86aabSstevel #include <config_admin.h>
55*3db86aabSstevel 
56*3db86aabSstevel #ifdef	DEBUG
57*3db86aabSstevel #define	DBG	printf
58*3db86aabSstevel #define	DBG1	printf
59*3db86aabSstevel #define	DBG3	printf
60*3db86aabSstevel #define	DBG4	printf
61*3db86aabSstevel #else
62*3db86aabSstevel #define	DBG(a, b)
63*3db86aabSstevel #define	DBG1(a)
64*3db86aabSstevel #define	DBG3(a, b, c)
65*3db86aabSstevel #define	DBG4(a, b, c, d)
66*3db86aabSstevel #endif
67*3db86aabSstevel 
68*3db86aabSstevel #define	BD_CPU			1
69*3db86aabSstevel #define	BD_MEM			2
70*3db86aabSstevel #define	BD_IO_2SBUS		3
71*3db86aabSstevel #define	BD_IO_SBUS_FFB		4
72*3db86aabSstevel #define	BD_IO_PCI		5
73*3db86aabSstevel #define	BD_DISK			6
74*3db86aabSstevel #define	BD_IO_2SBUS_SOCPLUS	7
75*3db86aabSstevel #define	BD_IO_SBUS_FFB_SOCPLUS	8
76*3db86aabSstevel #define	BD_UNKNOWN		9
77*3db86aabSstevel #define	CMD_GETSTAT		10
78*3db86aabSstevel #define	CMD_LIST		11
79*3db86aabSstevel #define	CMD_CONNECT		12
80*3db86aabSstevel #define	CMD_DISCONNECT		13
81*3db86aabSstevel #define	CMD_CONFIGURE		14
82*3db86aabSstevel #define	CMD_UNCONFIGURE		15
83*3db86aabSstevel #define	CMD_QUIESCE		16
84*3db86aabSstevel #define	CMD_INSERT		17
85*3db86aabSstevel #define	CMD_REMOVE		18
86*3db86aabSstevel #define	CMD_SET_COND		19
87*3db86aabSstevel #define	OPT_ENABLE		20
88*3db86aabSstevel #define	OPT_DISABLE		21
89*3db86aabSstevel #define	ERR_PROM_OPEN		22
90*3db86aabSstevel #define	ERR_PROM_GETPROP	23
91*3db86aabSstevel #define	ERR_PROM_SETPROP	24
92*3db86aabSstevel #define	ERR_TRANS		25
93*3db86aabSstevel #define	ERR_CMD_INVAL		26
94*3db86aabSstevel #define	ERR_OPT_INVAL		27
95*3db86aabSstevel #define	ERR_AP_INVAL		28
96*3db86aabSstevel #define	ERR_DISABLED		29
97*3db86aabSstevel #define	DIAG_FORCE		30
98*3db86aabSstevel #define	DIAG_TRANS_OK		31
99*3db86aabSstevel #define	DIAG_FAILED		32
100*3db86aabSstevel #define	DIAG_WAS_ENABLED	33
101*3db86aabSstevel #define	DIAG_WAS_DISABLED	34
102*3db86aabSstevel #define	DIAG_WILL_ENABLE	35
103*3db86aabSstevel #define	DIAG_WILL_DISABLE	36
104*3db86aabSstevel #define	HELP_HEADER		37
105*3db86aabSstevel #define	HELP_QUIESCE		38
106*3db86aabSstevel #define	HELP_INSERT		39
107*3db86aabSstevel #define	HELP_REMOVE		40
108*3db86aabSstevel #define	HELP_SET_COND		41
109*3db86aabSstevel #define	HELP_ENABLE		42
110*3db86aabSstevel #define	HELP_DISABLE		43
111*3db86aabSstevel #define	HELP_UNKNOWN		44
112*3db86aabSstevel #define	ASK_CONNECT		45
113*3db86aabSstevel #define	STR_BD			46
114*3db86aabSstevel #define	STR_COL			47
115*3db86aabSstevel #define	COND_UNKNOWN		48
116*3db86aabSstevel #define	COND_OK			49
117*3db86aabSstevel #define	COND_FAILING		50
118*3db86aabSstevel #define	COND_FAILED		51
119*3db86aabSstevel #define	COND_UNUSABLE		52
120*3db86aabSstevel #define	SYSC_COOLING		53
121*3db86aabSstevel #define	SYSC_POWER		54
122*3db86aabSstevel #define	SYSC_PRECHARGE		55
123*3db86aabSstevel #define	SYSC_INTRANS		56
124*3db86aabSstevel #define	SYSC_UTHREAD		57
125*3db86aabSstevel #define	SYSC_KTHREAD		58
126*3db86aabSstevel #define	SYSC_DEV_ATTACH		59
127*3db86aabSstevel #define	SYSC_DEV_DETACH		60
128*3db86aabSstevel #define	SYSC_NDI_ATTACH		61
129*3db86aabSstevel #define	SYSC_NDI_DETACH		62
130*3db86aabSstevel #define	SYSC_CORE_RESOURCE	63
131*3db86aabSstevel #define	SYSC_OSTATE		64
132*3db86aabSstevel #define	SYSC_RSTATE		65
133*3db86aabSstevel #define	SYSC_COND		66
134*3db86aabSstevel #define	SYSC_PROM		67
135*3db86aabSstevel #define	SYSC_NOMEM		68
136*3db86aabSstevel #define	SYSC_HOTPLUG		69
137*3db86aabSstevel #define	SYSC_HW_COMPAT		70
138*3db86aabSstevel #define	SYSC_NON_DR_PROM	71
139*3db86aabSstevel #define	SYSC_SUSPEND		72
140*3db86aabSstevel #define	SYSC_RESUME		73
141*3db86aabSstevel #define	SYSC_UNKNOWN		74
142*3db86aabSstevel #define	SYSC_DEVSTR		75
143*3db86aabSstevel 
144*3db86aabSstevel /*
145*3db86aabSstevel  * The string table contains all the strings used by the platform
146*3db86aabSstevel  * library.  The comment next to each string specifies whether the
147*3db86aabSstevel  * string should be internationalized (y) or not (n).
148*3db86aabSstevel  * Note that there are calls to dgettext() with strings other than
149*3db86aabSstevel  * the ones below, they are marked by the li18 symbol.
150*3db86aabSstevel  */
151*3db86aabSstevel static char *
152*3db86aabSstevel cfga_strs[] = {
153*3db86aabSstevel 	/*   */ NULL,
154*3db86aabSstevel 	/* n */ "cpu/mem   ",
155*3db86aabSstevel 	/* n */ "mem       ",
156*3db86aabSstevel 	/* n */ "dual-sbus ",
157*3db86aabSstevel 	/* n */ "sbus-upa  ",
158*3db86aabSstevel 	/* n */ "dual-pci  ",
159*3db86aabSstevel 	/* n */ "disk      ",
160*3db86aabSstevel 	/* n */ "soc+sbus  ",
161*3db86aabSstevel 	/* n */ "soc+upa   ",
162*3db86aabSstevel 	/* n */ "unknown   ",
163*3db86aabSstevel 	/* n */ "get-status",
164*3db86aabSstevel 	/* n */ "list",
165*3db86aabSstevel 	/* n */ "connect",
166*3db86aabSstevel 	/* n */ "disconnect",
167*3db86aabSstevel 	/* n */ "configure",
168*3db86aabSstevel 	/* n */ "unconfigure",
169*3db86aabSstevel 	/* n */ "quiesce-test",
170*3db86aabSstevel 	/* n */ "insert-test",
171*3db86aabSstevel 	/* n */ "remove-test",
172*3db86aabSstevel 	/* n */ "set-condition-test",
173*3db86aabSstevel 	/* n */ "enable-at-boot",
174*3db86aabSstevel 	/* n */ "disable-at-boot",
175*3db86aabSstevel 	/* n */ "prom open",
176*3db86aabSstevel 	/* n */ "prom getprop",
177*3db86aabSstevel 	/* n */ "prom setprop",
178*3db86aabSstevel 	/* y */ "invalid transition",
179*3db86aabSstevel 	/* y */ "invalid command: ",
180*3db86aabSstevel 	/* y */ "invalid option: ",
181*3db86aabSstevel 	/* y */ "invalid attachment point: ",
182*3db86aabSstevel 	/* y */ "board is disabled: must override with ",
183*3db86aabSstevel 	/* n */ "[-f][-o enable-at-boot]",
184*3db86aabSstevel 	/* y */ "transition succeeded but ",
185*3db86aabSstevel 	/* y */ " failed: ",
186*3db86aabSstevel 	/* y */ "was already enabled at boot time",
187*3db86aabSstevel 	/* y */ "was already disabled at boot time",
188*3db86aabSstevel 	/* y */ "will be enabled at boot time",
189*3db86aabSstevel 	/* y */ "will be disabled at boot time",
190*3db86aabSstevel 	/* y */ "\nSysctrl specific commands/options:",
191*3db86aabSstevel 	/* n */ "\t-x quiesce-test ap_id [ap_id...]",
192*3db86aabSstevel 	/* n */ "\t-x insert-test  ap_id [ap_id...]",
193*3db86aabSstevel 	/* n */ "\t-x remove-test  ap_id [ap_id...]",
194*3db86aabSstevel 	/* n */ "\t-x set-condition-test=<condition>",
195*3db86aabSstevel 	/* n */ "\t-o enable-at-boot",
196*3db86aabSstevel 	/* n */ "\t-o disable-at-boot",
197*3db86aabSstevel 	/* y */ "\tunknown command or option: ",
198*3db86aabSstevel 	/* y */
199*3db86aabSstevel 	"system will be temporarily suspended to connect a board: proceed",
200*3db86aabSstevel 	/* y */ "board ",
201*3db86aabSstevel 	/* y */ ": ",
202*3db86aabSstevel 	/* n */ "unknown",
203*3db86aabSstevel 	/* n */ "ok",
204*3db86aabSstevel 	/* n */ "failing",
205*3db86aabSstevel 	/* n */ "failed",
206*3db86aabSstevel 	/* n */ "unusable",
207*3db86aabSstevel 	/* y */ "not enough cooling for a new board",
208*3db86aabSstevel 	/* y */ "not enough power for a new board",
209*3db86aabSstevel 	/* y */ "not enough precharge power for a new board",
210*3db86aabSstevel 	/* y */ "configuration operation already in progress on this board",
211*3db86aabSstevel 	/* y */ "could not suspend user process: ",
212*3db86aabSstevel 	/* y */ "could not suspend system processes",
213*3db86aabSstevel 	/* y */ "device did not attach",
214*3db86aabSstevel 	/* y */ "device did not detach",
215*3db86aabSstevel 	/* y */ "nexus error during attach",
216*3db86aabSstevel 	/* y */ "nexus error during detach",
217*3db86aabSstevel 	/* y */ "attempt to remove core system resource",
218*3db86aabSstevel 	/* y */ "invalid occupant state",
219*3db86aabSstevel 	/* y */ "invalid receptacle state",
220*3db86aabSstevel 	/* y */ "insufficient condition",
221*3db86aabSstevel 	/* y */ "firmware operation error",
222*3db86aabSstevel 	/* y */ "not enough memory",
223*3db86aabSstevel 	/* y */ "hotplug feature unavailable on this machine",
224*3db86aabSstevel 	/* y */ "board does not support dynamic reconfiguration",
225*3db86aabSstevel 	/* y */ "firmware does not support dynamic reconfiguration",
226*3db86aabSstevel 	/* y */ "system suspend error",
227*3db86aabSstevel 	/* y */ "system resume error",
228*3db86aabSstevel 	/* y */ "unknown system error",
229*3db86aabSstevel 	/*   */ NULL
230*3db86aabSstevel };
231*3db86aabSstevel 
232*3db86aabSstevel #define	cfga_str(i)		cfga_strs[(i)]
233*3db86aabSstevel 
234*3db86aabSstevel #define	cfga_eid(a, b)		(((a) << 8) + (b))
235*3db86aabSstevel 
236*3db86aabSstevel /*
237*3db86aabSstevel  *
238*3db86aabSstevel  *	Translation table for mapping from an <errno,sysc_err>
239*3db86aabSstevel  *	pair to an error string.
240*3db86aabSstevel  *
241*3db86aabSstevel  *
242*3db86aabSstevel  *	SYSC_COOLING,		EAGAIN,  SYSC_ERR_COOLING
243*3db86aabSstevel  *	SYSC_POWER,		EAGAIN,  SYSC_ERR_POWER
244*3db86aabSstevel  *	SYSC_PRECHARGE,		EAGAIN,  SYSC_ERR_PRECHARGE
245*3db86aabSstevel  *	SYSC_INTRANS,		EBUSY,   SYSC_ERR_INTRANS
246*3db86aabSstevel  *	SYSC_KTHREAD,		EBUSY,   SYSC_ERR_KTHREAD
247*3db86aabSstevel  *	SYSC_DEV_ATTACH,	EBUSY,   SYSC_ERR_NDI_ATTACH
248*3db86aabSstevel  *	SYSC_DEV_DETACH,	EBUSY,   SYSC_ERR_NDI_DETACH
249*3db86aabSstevel  *	SYSC_NDI_ATTACH,	EFAULT,  SYSC_ERR_NDI_ATTACH
250*3db86aabSstevel  *	SYSC_NDI_DETACH,	EFAULT,  SYSC_ERR_NDI_DETACH
251*3db86aabSstevel  *	SYSC_CORE_RESOURCE,	EINVAL,  SYSC_ERR_CORE_RESOURCE
252*3db86aabSstevel  *	SYSC_OSTATE,		EINVAL,  SYSC_ERR_OSTATE
253*3db86aabSstevel  *	SYSC_RSTATE,		EINVAL,  SYSC_ERR_RSTATE
254*3db86aabSstevel  *	SYSC_COND,		EINVAL,  SYSC_ERR_COND
255*3db86aabSstevel  *	SYSC_PROM,		EIO,     SYSC_ERR_PROM
256*3db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_DR_INIT
257*3db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_NDI_ATTACH
258*3db86aabSstevel  *	SYSC_NOMEM,		ENOMEM,  SYSC_ERR_NDI_DETACH
259*3db86aabSstevel  *	SYSC_HOTPLUG,		ENOTSUP, SYSC_ERR_HOTPLUG
260*3db86aabSstevel  *	SYSC_HW_COMPAT,		ENOTSUP, SYSC_ERR_HW_COMPAT
261*3db86aabSstevel  *	SYSC_NON_DR_PROM,	ENOTSUP, SYSC_ERR_NON_DR_PROM
262*3db86aabSstevel  *	SYSC_SUSPEND,		ENXIO,   SYSC_ERR_SUSPEND
263*3db86aabSstevel  *	SYSC_RESUME,		ENXIO,   SYSC_ERR_RESUME
264*3db86aabSstevel  *	SYSC_UTHREAD,		ESRCH,   SYSC_ERR_UTHREAD
265*3db86aabSstevel  */
266*3db86aabSstevel static int
267*3db86aabSstevel cfga_sid(int err, int scerr)
268*3db86aabSstevel {
269*3db86aabSstevel 	if (scerr == SYSC_ERR_DEFAULT)
270*3db86aabSstevel 		return (SYSC_UNKNOWN);
271*3db86aabSstevel 
272*3db86aabSstevel 	switch (cfga_eid(err, scerr)) {
273*3db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_COOLING):
274*3db86aabSstevel 		return (SYSC_COOLING);
275*3db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_POWER):
276*3db86aabSstevel 		return (SYSC_POWER);
277*3db86aabSstevel 	case cfga_eid(EAGAIN, SYSC_ERR_PRECHARGE):
278*3db86aabSstevel 		return (SYSC_PRECHARGE);
279*3db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_INTRANS):
280*3db86aabSstevel 		return (SYSC_INTRANS);
281*3db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_KTHREAD):
282*3db86aabSstevel 		return (SYSC_KTHREAD);
283*3db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_NDI_ATTACH):
284*3db86aabSstevel 		return (SYSC_DEV_ATTACH);
285*3db86aabSstevel 	case cfga_eid(EBUSY, SYSC_ERR_NDI_DETACH):
286*3db86aabSstevel 		return (SYSC_DEV_DETACH);
287*3db86aabSstevel 	case cfga_eid(EFAULT, SYSC_ERR_NDI_ATTACH):
288*3db86aabSstevel 		return (SYSC_NDI_ATTACH);
289*3db86aabSstevel 	case cfga_eid(EFAULT, SYSC_ERR_NDI_DETACH):
290*3db86aabSstevel 		return (SYSC_NDI_DETACH);
291*3db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_CORE_RESOURCE):
292*3db86aabSstevel 		return (SYSC_CORE_RESOURCE);
293*3db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_OSTATE):
294*3db86aabSstevel 		return (SYSC_OSTATE);
295*3db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_RSTATE):
296*3db86aabSstevel 		return (SYSC_RSTATE);
297*3db86aabSstevel 	case cfga_eid(EINVAL, SYSC_ERR_COND):
298*3db86aabSstevel 		return (SYSC_COND);
299*3db86aabSstevel 	case cfga_eid(EIO, SYSC_ERR_PROM):
300*3db86aabSstevel 		return (SYSC_PROM);
301*3db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_DR_INIT):
302*3db86aabSstevel 		return (SYSC_NOMEM);
303*3db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_NDI_ATTACH):
304*3db86aabSstevel 		return (SYSC_NOMEM);
305*3db86aabSstevel 	case cfga_eid(ENOMEM, SYSC_ERR_NDI_DETACH):
306*3db86aabSstevel 		return (SYSC_NOMEM);
307*3db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_HOTPLUG):
308*3db86aabSstevel 		return (SYSC_HOTPLUG);
309*3db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_HW_COMPAT):
310*3db86aabSstevel 		return (SYSC_HW_COMPAT);
311*3db86aabSstevel 	case cfga_eid(ENOTSUP, SYSC_ERR_NON_DR_PROM):
312*3db86aabSstevel 		return (SYSC_NON_DR_PROM);
313*3db86aabSstevel 	case cfga_eid(ENXIO, SYSC_ERR_SUSPEND):
314*3db86aabSstevel 		return (SYSC_SUSPEND);
315*3db86aabSstevel 	case cfga_eid(ENXIO, SYSC_ERR_RESUME):
316*3db86aabSstevel 		return (SYSC_RESUME);
317*3db86aabSstevel 	case cfga_eid(ESRCH, SYSC_ERR_UTHREAD):
318*3db86aabSstevel 		return (SYSC_UTHREAD);
319*3db86aabSstevel 	default:
320*3db86aabSstevel 		break;
321*3db86aabSstevel 	}
322*3db86aabSstevel 
323*3db86aabSstevel 	return (SYSC_UNKNOWN);
324*3db86aabSstevel }
325*3db86aabSstevel 
326*3db86aabSstevel static void
327*3db86aabSstevel sysc_cmd_init(sysc_cfga_cmd_t *sc, char *outputstr, int force)
328*3db86aabSstevel {
329*3db86aabSstevel 	sc->force = force;
330*3db86aabSstevel 	sc->outputstr = outputstr;
331*3db86aabSstevel 	sc->errtype = SYSC_ERR_DEFAULT;
332*3db86aabSstevel 
333*3db86aabSstevel 	(void) memset((void *)outputstr, 0, sizeof (outputstr));
334*3db86aabSstevel 
335*3db86aabSstevel 	cfga_str(SYSC_DEVSTR) = outputstr;
336*3db86aabSstevel }
337*3db86aabSstevel 
338*3db86aabSstevel /*
339*3db86aabSstevel  * cfga_err() accepts a variable number of message IDs and constructs
340*3db86aabSstevel  * a corresponding error string which is returned via the errstring argument.
341*3db86aabSstevel  * cfga_err() calls dgettext() to internationalize proper messages.
342*3db86aabSstevel  */
343*3db86aabSstevel static void
344*3db86aabSstevel cfga_err(sysc_cfga_cmd_t *sc, char **errstring, ...)
345*3db86aabSstevel {
346*3db86aabSstevel 	int a;
347*3db86aabSstevel 	int i;
348*3db86aabSstevel 	int n;
349*3db86aabSstevel 	int len;
350*3db86aabSstevel 	int flen;
351*3db86aabSstevel 	char *p;
352*3db86aabSstevel 	char *q;
353*3db86aabSstevel 	char *s[32];
354*3db86aabSstevel 	char *failed;
355*3db86aabSstevel 	va_list ap;
356*3db86aabSstevel 	char syserr_num[20];
357*3db86aabSstevel 
358*3db86aabSstevel 	/*
359*3db86aabSstevel 	 * If errstring is null it means user in not interested in getting
360*3db86aabSstevel 	 * error status. So we don't do all the work
361*3db86aabSstevel 	 */
362*3db86aabSstevel 	if (errstring == NULL) {
363*3db86aabSstevel 		return;
364*3db86aabSstevel 	}
365*3db86aabSstevel 	va_start(ap, errstring);
366*3db86aabSstevel 
367*3db86aabSstevel 	failed = dgettext(TEXT_DOMAIN, cfga_str(DIAG_FAILED));
368*3db86aabSstevel 	flen = strlen(failed);
369*3db86aabSstevel 
370*3db86aabSstevel 	for (n = len = 0; (a = va_arg(ap, int)) != 0; n++) {
371*3db86aabSstevel 
372*3db86aabSstevel 		switch (a) {
373*3db86aabSstevel 		case ERR_PROM_OPEN:
374*3db86aabSstevel 		case ERR_PROM_GETPROP:
375*3db86aabSstevel 		case ERR_PROM_SETPROP:
376*3db86aabSstevel 		case CMD_GETSTAT:
377*3db86aabSstevel 		case CMD_LIST:
378*3db86aabSstevel 		case CMD_CONNECT:
379*3db86aabSstevel 		case CMD_DISCONNECT:
380*3db86aabSstevel 		case CMD_CONFIGURE:
381*3db86aabSstevel 		case CMD_UNCONFIGURE:
382*3db86aabSstevel 		case CMD_QUIESCE:
383*3db86aabSstevel 		case CMD_INSERT:
384*3db86aabSstevel 		case CMD_REMOVE:
385*3db86aabSstevel 		case CMD_SET_COND:
386*3db86aabSstevel 			p =  cfga_str(a);
387*3db86aabSstevel 			len += (strlen(p) + flen);
388*3db86aabSstevel 			s[n] = p;
389*3db86aabSstevel 			s[++n] = failed;
390*3db86aabSstevel 
391*3db86aabSstevel 			DBG("<%s>", p);
392*3db86aabSstevel 			DBG("<%s>", failed);
393*3db86aabSstevel 			break;
394*3db86aabSstevel 
395*3db86aabSstevel 		case OPT_ENABLE:
396*3db86aabSstevel 		case OPT_DISABLE:
397*3db86aabSstevel 			p = dgettext(TEXT_DOMAIN, cfga_str(DIAG_TRANS_OK));
398*3db86aabSstevel 			q = cfga_str(a);
399*3db86aabSstevel 			len += (strlen(p) + strlen(q) + flen);
400*3db86aabSstevel 			s[n] = p;
401*3db86aabSstevel 			s[++n] = q;
402*3db86aabSstevel 			s[++n] = failed;
403*3db86aabSstevel 
404*3db86aabSstevel 			DBG("<%s>", p);
405*3db86aabSstevel 			DBG("<%s>", q);
406*3db86aabSstevel 			DBG("<%s>", failed);
407*3db86aabSstevel 			break;
408*3db86aabSstevel 
409*3db86aabSstevel 		case ERR_CMD_INVAL:
410*3db86aabSstevel 		case ERR_AP_INVAL:
411*3db86aabSstevel 		case ERR_OPT_INVAL:
412*3db86aabSstevel 			p =  dgettext(TEXT_DOMAIN, cfga_str(a));
413*3db86aabSstevel 			q = va_arg(ap, char *);
414*3db86aabSstevel 			len += (strlen(p) + strlen(q));
415*3db86aabSstevel 			s[n] = p;
416*3db86aabSstevel 			s[++n] = q;
417*3db86aabSstevel 
418*3db86aabSstevel 			DBG("<%s>", p);
419*3db86aabSstevel 			DBG("<%s>", q);
420*3db86aabSstevel 			break;
421*3db86aabSstevel 
422*3db86aabSstevel 		case ERR_TRANS:
423*3db86aabSstevel 		case ERR_DISABLED:
424*3db86aabSstevel 			p =  dgettext(TEXT_DOMAIN, cfga_str(a));
425*3db86aabSstevel 			len += strlen(p);
426*3db86aabSstevel 			s[n] = p;
427*3db86aabSstevel 
428*3db86aabSstevel 			DBG("<%s>", p);
429*3db86aabSstevel 			break;
430*3db86aabSstevel 
431*3db86aabSstevel 		case DIAG_FORCE:
432*3db86aabSstevel 		default:
433*3db86aabSstevel 			p =  cfga_str(a);
434*3db86aabSstevel 			len += strlen(p);
435*3db86aabSstevel 			s[n] = p;
436*3db86aabSstevel 
437*3db86aabSstevel 			DBG("<%s>", p);
438*3db86aabSstevel 			break;
439*3db86aabSstevel 		}
440*3db86aabSstevel 	}
441*3db86aabSstevel 
442*3db86aabSstevel 	DBG1("\n");
443*3db86aabSstevel 	va_end(ap);
444*3db86aabSstevel 
445*3db86aabSstevel 	if (errno) {
446*3db86aabSstevel 		if (sc)
447*3db86aabSstevel 			i = cfga_sid(errno, (int)sc->errtype);
448*3db86aabSstevel 		else
449*3db86aabSstevel 			i = SYSC_UNKNOWN;
450*3db86aabSstevel 
451*3db86aabSstevel 		DBG4("cfga_sid(%d,%d)=%d\n", errno, sc->errtype, i);
452*3db86aabSstevel 
453*3db86aabSstevel 		if (i == SYSC_UNKNOWN) {
454*3db86aabSstevel 			p = strerror(errno);
455*3db86aabSstevel 			if (p == NULL) {
456*3db86aabSstevel 				(void) sprintf(syserr_num, "errno=%d", errno);
457*3db86aabSstevel 				p = syserr_num;
458*3db86aabSstevel 			}
459*3db86aabSstevel 		} else
460*3db86aabSstevel 			p = dgettext(TEXT_DOMAIN, cfga_str(i));
461*3db86aabSstevel 
462*3db86aabSstevel 		len += strlen(p);
463*3db86aabSstevel 		s[n++] = p;
464*3db86aabSstevel 		p = cfga_str(SYSC_DEVSTR);
465*3db86aabSstevel 		if (p && p[0]) {
466*3db86aabSstevel 			q = cfga_str(STR_COL);
467*3db86aabSstevel 
468*3db86aabSstevel 			len += strlen(q);
469*3db86aabSstevel 			s[n++] = q;
470*3db86aabSstevel 			len += strlen(p);
471*3db86aabSstevel 			s[n++] = p;
472*3db86aabSstevel 		}
473*3db86aabSstevel 	}
474*3db86aabSstevel 
475*3db86aabSstevel 	if ((p = (char *)calloc(len, 1)) == NULL)
476*3db86aabSstevel 		return;
477*3db86aabSstevel 
478*3db86aabSstevel 	for (i = 0; i < n; i++)
479*3db86aabSstevel 		(void) strcat(p, s[i]);
480*3db86aabSstevel 
481*3db86aabSstevel 	*errstring = p;
482*3db86aabSstevel #ifdef	SIM_MSG
483*3db86aabSstevel 	printf("%s\n", *errstring);
484*3db86aabSstevel #endif
485*3db86aabSstevel }
486*3db86aabSstevel 
487*3db86aabSstevel /*
488*3db86aabSstevel  * This routine accepts a variable number of message IDs and constructs
489*3db86aabSstevel  * a corresponding error string which is printed via the message print routine
490*3db86aabSstevel  * argument.  The HELP_UNKNOWN message ID has an argument string (the unknown
491*3db86aabSstevel  * help topic) that follows.
492*3db86aabSstevel  */
493*3db86aabSstevel static void
494*3db86aabSstevel cfga_msg(struct cfga_msg *msgp, ...)
495*3db86aabSstevel {
496*3db86aabSstevel 	int a;
497*3db86aabSstevel 	int i;
498*3db86aabSstevel 	int n;
499*3db86aabSstevel 	int len;
500*3db86aabSstevel 	char *p;
501*3db86aabSstevel 	char *s[32];
502*3db86aabSstevel 	va_list ap;
503*3db86aabSstevel 
504*3db86aabSstevel 	va_start(ap, msgp);
505*3db86aabSstevel 
506*3db86aabSstevel 	for (n = len = 0; (a = va_arg(ap, int)) != 0; n++) {
507*3db86aabSstevel 		DBG("<%d>", a);
508*3db86aabSstevel 		p =  dgettext(TEXT_DOMAIN, cfga_str(a));
509*3db86aabSstevel 		len += strlen(p);
510*3db86aabSstevel 		s[n] = p;
511*3db86aabSstevel 		if (a == HELP_UNKNOWN) {
512*3db86aabSstevel 			p = va_arg(ap, char *);
513*3db86aabSstevel 			len += strlen(p);
514*3db86aabSstevel 			s[++n] = p;
515*3db86aabSstevel 		}
516*3db86aabSstevel 	}
517*3db86aabSstevel 
518*3db86aabSstevel 	va_end(ap);
519*3db86aabSstevel 
520*3db86aabSstevel 	if ((p = (char *)calloc(len + 1, 1)) == NULL)
521*3db86aabSstevel 		return;
522*3db86aabSstevel 
523*3db86aabSstevel 	for (i = 0; i < n; i++)
524*3db86aabSstevel 		(void) strcat(p, s[i]);
525*3db86aabSstevel 	(void) strcat(p, "\n");
526*3db86aabSstevel 
527*3db86aabSstevel #ifdef	SIM_MSG
528*3db86aabSstevel 	printf("%s", p);
529*3db86aabSstevel #else
530*3db86aabSstevel 	(*msgp->message_routine)(msgp->appdata_ptr, p);
531*3db86aabSstevel #endif
532*3db86aabSstevel 	free(p);
533*3db86aabSstevel }
534*3db86aabSstevel 
535*3db86aabSstevel static sysc_cfga_stat_t *
536*3db86aabSstevel sysc_stat(const char *ap_id, int *fdp)
537*3db86aabSstevel {
538*3db86aabSstevel 	int fd;
539*3db86aabSstevel 	static sysc_cfga_stat_t sc_list[MAX_BOARDS];
540*3db86aabSstevel 
541*3db86aabSstevel 
542*3db86aabSstevel 	if ((fd = open(ap_id, O_RDWR, 0)) == -1)
543*3db86aabSstevel 		return (NULL);
544*3db86aabSstevel 	else if (ioctl(fd, SYSC_CFGA_CMD_GETSTATUS, sc_list) == -1) {
545*3db86aabSstevel 		(void) close(fd);
546*3db86aabSstevel 		return (NULL);
547*3db86aabSstevel 	} else if (fdp)
548*3db86aabSstevel 		*fdp = fd;
549*3db86aabSstevel 	else
550*3db86aabSstevel 		(void) close(fd);
551*3db86aabSstevel 
552*3db86aabSstevel 	return (sc_list);
553*3db86aabSstevel }
554*3db86aabSstevel 
555*3db86aabSstevel /*
556*3db86aabSstevel  * This code implementes the simulation of the ioctls that transition state.
557*3db86aabSstevel  * The GETSTAT ioctl is not simulated.  In this way a snapshot of the system
558*3db86aabSstevel  * state is read and manipulated by the simulation routines.  It is basically
559*3db86aabSstevel  * a useful debugging tool.
560*3db86aabSstevel  */
561*3db86aabSstevel #ifdef	SIM
562*3db86aabSstevel static int sim_idx;
563*3db86aabSstevel static int sim_fd = -1;
564*3db86aabSstevel static int sim_size = MAX_BOARDS * sizeof (sysc_cfga_stat_t);
565*3db86aabSstevel static sysc_cfga_stat_t sim_sc_list[MAX_BOARDS];
566*3db86aabSstevel 
567*3db86aabSstevel static sysc_cfga_stat_t *
568*3db86aabSstevel sim_sysc_stat(const char *ap_id, int *fdp)
569*3db86aabSstevel {
570*3db86aabSstevel 	int fd;
571*3db86aabSstevel 	struct stat buf;
572*3db86aabSstevel 
573*3db86aabSstevel 	if (sim_fd != -1)
574*3db86aabSstevel 		return (sim_sc_list);
575*3db86aabSstevel 
576*3db86aabSstevel 	if ((sim_fd = open("/tmp/cfga_simdata", O_RDWR|O_CREAT)) == -1) {
577*3db86aabSstevel 		perror("sim_open");
578*3db86aabSstevel 		exit(1);
579*3db86aabSstevel 	} else if (fstat(sim_fd, &buf) == -1) {
580*3db86aabSstevel 		perror("sim_stat");
581*3db86aabSstevel 		exit(1);
582*3db86aabSstevel 	}
583*3db86aabSstevel 
584*3db86aabSstevel 	if (buf.st_size) {
585*3db86aabSstevel 		if (buf.st_size != sim_size) {
586*3db86aabSstevel 			perror("sim_size");
587*3db86aabSstevel 			exit(1);
588*3db86aabSstevel 		} else if (read(sim_fd, sim_sc_list, sim_size) == -1) {
589*3db86aabSstevel 			perror("sim_read");
590*3db86aabSstevel 			exit(1);
591*3db86aabSstevel 		}
592*3db86aabSstevel 	} else if ((fd = open(ap_id, O_RDWR, 0)) == -1)
593*3db86aabSstevel 		return (NULL);
594*3db86aabSstevel 	else if (ioctl(fd, SYSC_CFGA_CMD_GETSTATUS, sim_sc_list) == -1) {
595*3db86aabSstevel 		(void) close(fd);
596*3db86aabSstevel 		return (NULL);
597*3db86aabSstevel 	} else if (fdp)
598*3db86aabSstevel 		*fdp = fd;
599*3db86aabSstevel 
600*3db86aabSstevel 	return (sim_sc_list);
601*3db86aabSstevel }
602*3db86aabSstevel 
603*3db86aabSstevel static int
604*3db86aabSstevel sim_open(char *a, int b, int c)
605*3db86aabSstevel {
606*3db86aabSstevel 	printf("sim_open(%s)\n", a);
607*3db86aabSstevel 
608*3db86aabSstevel 	if (strcmp(a, "/dev/openprom") == 0)
609*3db86aabSstevel 		return (open(a, b, c));
610*3db86aabSstevel 	return (0);
611*3db86aabSstevel }
612*3db86aabSstevel 
613*3db86aabSstevel static int
614*3db86aabSstevel sim_close(int a) { return (0); }
615*3db86aabSstevel 
616*3db86aabSstevel static int
617*3db86aabSstevel sim_ioctl(int fd, int cmd, void *a)
618*3db86aabSstevel {
619*3db86aabSstevel 	printf("sim_ioctl(%d)\n", sim_idx);
620*3db86aabSstevel 
621*3db86aabSstevel 	switch (cmd) {
622*3db86aabSstevel 	case SYSC_CFGA_CMD_CONNECT:
623*3db86aabSstevel 		sim_sc_list[sim_idx].rstate = SYSC_CFGA_RSTATE_CONNECTED;
624*3db86aabSstevel 		break;
625*3db86aabSstevel 	case SYSC_CFGA_CMD_CONFIGURE:
626*3db86aabSstevel 		sim_sc_list[sim_idx].ostate = SYSC_CFGA_OSTATE_CONFIGURED;
627*3db86aabSstevel 		break;
628*3db86aabSstevel 	case SYSC_CFGA_CMD_UNCONFIGURE:
629*3db86aabSstevel 		sim_sc_list[sim_idx].ostate = SYSC_CFGA_OSTATE_UNCONFIGURED;
630*3db86aabSstevel 		break;
631*3db86aabSstevel 	case SYSC_CFGA_CMD_DISCONNECT:
632*3db86aabSstevel 		sim_sc_list[sim_idx].rstate = SYSC_CFGA_RSTATE_DISCONNECTED;
633*3db86aabSstevel 		break;
634*3db86aabSstevel 	case SYSC_CFGA_CMD_QUIESCE_TEST:
635*3db86aabSstevel 	case SYSC_CFGA_CMD_TEST:
636*3db86aabSstevel 		return (0);
637*3db86aabSstevel 	case OPROMGETOPT:
638*3db86aabSstevel 		return (ioctl(fd, OPROMGETOPT, a));
639*3db86aabSstevel 	case OPROMSETOPT:
640*3db86aabSstevel 		return (ioctl(fd, OPROMSETOPT, a));
641*3db86aabSstevel 	}
642*3db86aabSstevel 
643*3db86aabSstevel 	if (lseek(sim_fd, SEEK_SET, 0) == -1) {
644*3db86aabSstevel 		perror("sim_seek");
645*3db86aabSstevel 		exit(1);
646*3db86aabSstevel 	}
647*3db86aabSstevel 	if (write(sim_fd, sim_sc_list, sim_size) == -1) {
648*3db86aabSstevel 		perror("sim_write");
649*3db86aabSstevel 		exit(1);
650*3db86aabSstevel 	}
651*3db86aabSstevel 
652*3db86aabSstevel 	return (0);
653*3db86aabSstevel }
654*3db86aabSstevel 
655*3db86aabSstevel #define	open(a, b, c)	sim_open((char *)(a), (int)(b), (int)(c))
656*3db86aabSstevel #define	close(a)	sim_close(a)
657*3db86aabSstevel #define	ioctl(a, b, c)	sim_ioctl((int)(a), (int)(b), (void *)(c))
658*3db86aabSstevel #define	sysc_stat(a, b)	sim_sysc_stat(a, b)
659*3db86aabSstevel #endif	/* SIM */
660*3db86aabSstevel 
661*3db86aabSstevel static char *promdev = "/dev/openprom";
662*3db86aabSstevel static char *dlprop = "disabled-board-list";
663*3db86aabSstevel 
664*3db86aabSstevel #define	BUFSIZE		128
665*3db86aabSstevel 
666*3db86aabSstevel typedef union {
667*3db86aabSstevel 	char buf[BUFSIZE];
668*3db86aabSstevel 	struct openpromio opp;
669*3db86aabSstevel } oppbuf_t;
670*3db86aabSstevel 
671*3db86aabSstevel static int
672*3db86aabSstevel prom_get_prop(int prom_fd, char *var, char **val)
673*3db86aabSstevel {
674*3db86aabSstevel 	static oppbuf_t oppbuf;
675*3db86aabSstevel 	struct openpromio *opp = &(oppbuf.opp);
676*3db86aabSstevel 
677*3db86aabSstevel 	(void) strncpy(opp->oprom_array, var, OBP_MAXPROPNAME);
678*3db86aabSstevel 	opp->oprom_array[OBP_MAXPROPNAME + 1] = '\0';
679*3db86aabSstevel 	opp->oprom_size = BUFSIZE;
680*3db86aabSstevel 
681*3db86aabSstevel 	DBG3("getprop(%s, %d)\n", opp->oprom_array, opp->oprom_size);
682*3db86aabSstevel 
683*3db86aabSstevel 	if (ioctl(prom_fd, OPROMGETOPT, opp) < 0)
684*3db86aabSstevel 		return (ERR_PROM_GETPROP);
685*3db86aabSstevel 	else if (opp->oprom_size > 0)
686*3db86aabSstevel 		*val = opp->oprom_array;
687*3db86aabSstevel 	else
688*3db86aabSstevel 		*val = NULL;
689*3db86aabSstevel 
690*3db86aabSstevel 	return (0);
691*3db86aabSstevel }
692*3db86aabSstevel 
693*3db86aabSstevel static cfga_err_t
694*3db86aabSstevel prom_set_prop(int prom_fd, char *var, char *val)
695*3db86aabSstevel {
696*3db86aabSstevel 	oppbuf_t oppbuf;
697*3db86aabSstevel 	struct openpromio *opp = &(oppbuf.opp);
698*3db86aabSstevel 	int varlen = strlen(var) + 1;
699*3db86aabSstevel 	int vallen = strlen(val);
700*3db86aabSstevel 
701*3db86aabSstevel 	DBG("prom_set_prop(%s)\n", val);
702*3db86aabSstevel 
703*3db86aabSstevel 	(void) strcpy(opp->oprom_array, var);
704*3db86aabSstevel 	(void) strcpy(opp->oprom_array + varlen, val);
705*3db86aabSstevel 	opp->oprom_size = varlen + vallen;
706*3db86aabSstevel 
707*3db86aabSstevel 	if (ioctl(prom_fd, OPROMSETOPT, opp) < 0)
708*3db86aabSstevel 		return (ERR_PROM_SETPROP);
709*3db86aabSstevel 
710*3db86aabSstevel 	return (0);
711*3db86aabSstevel }
712*3db86aabSstevel 
713*3db86aabSstevel static int
714*3db86aabSstevel dlist_find(int board, char **dlist, int *disabled)
715*3db86aabSstevel {
716*3db86aabSstevel 	int i;
717*3db86aabSstevel 	int err;
718*3db86aabSstevel 	int prom_fd;
719*3db86aabSstevel 	char *p;
720*3db86aabSstevel 	char *dl;
721*3db86aabSstevel 	char b[2];
722*3db86aabSstevel 
723*3db86aabSstevel 	if ((prom_fd = open(promdev, O_RDWR, 0)) < 0)
724*3db86aabSstevel 		return (ERR_PROM_OPEN);
725*3db86aabSstevel 	else if (err = prom_get_prop(prom_fd, dlprop, dlist)) {
726*3db86aabSstevel 		(void) close(prom_fd);
727*3db86aabSstevel 		return (err);
728*3db86aabSstevel 	} else
729*3db86aabSstevel 		(void) close(prom_fd);
730*3db86aabSstevel 
731*3db86aabSstevel 	b[1] = 0;
732*3db86aabSstevel 	*disabled = 0;
733*3db86aabSstevel 
734*3db86aabSstevel 	if ((dl = *dlist) != NULL) {
735*3db86aabSstevel 		int len = strlen(dl);
736*3db86aabSstevel 
737*3db86aabSstevel 		for (i = 0; i < len; i++) {
738*3db86aabSstevel 			int bd;
739*3db86aabSstevel 
740*3db86aabSstevel 			b[0] = dl[i];
741*3db86aabSstevel 			bd = strtol(b, &p, 16);
742*3db86aabSstevel 
743*3db86aabSstevel 			if (p != b && bd == board)
744*3db86aabSstevel 				(*disabled)++;
745*3db86aabSstevel 		}
746*3db86aabSstevel 	}
747*3db86aabSstevel 
748*3db86aabSstevel 	return (0);
749*3db86aabSstevel }
750*3db86aabSstevel 
751*3db86aabSstevel static int
752*3db86aabSstevel dlist_update(int board, int disable, char *dlist, struct cfga_msg *msgp,
753*3db86aabSstevel 	int verbose)
754*3db86aabSstevel {
755*3db86aabSstevel 	int i, j, n;
756*3db86aabSstevel 	int err;
757*3db86aabSstevel 	int found;
758*3db86aabSstevel 	int update;
759*3db86aabSstevel 	int prom_fd;
760*3db86aabSstevel 	char *p;
761*3db86aabSstevel 	char b[2];
762*3db86aabSstevel 	char ndlist[64];
763*3db86aabSstevel 
764*3db86aabSstevel 	b[1] = 0;
765*3db86aabSstevel 	ndlist[0] = 0;
766*3db86aabSstevel 	j = 0;
767*3db86aabSstevel 	found = 0;
768*3db86aabSstevel 	update = 0;
769*3db86aabSstevel 
770*3db86aabSstevel 	if ((prom_fd = open(promdev, O_RDWR, 0)) < 0)
771*3db86aabSstevel 		return (ERR_PROM_OPEN);
772*3db86aabSstevel 
773*3db86aabSstevel 	if (dlist) {
774*3db86aabSstevel 		int len = strlen(dlist);
775*3db86aabSstevel 
776*3db86aabSstevel 		for (i = 0; i < len; i++) {
777*3db86aabSstevel 			int bd;
778*3db86aabSstevel 
779*3db86aabSstevel 			b[0] = dlist[i];
780*3db86aabSstevel 			bd = strtol(b, &p, 16);
781*3db86aabSstevel 
782*3db86aabSstevel 			if (p != b && bd == board) {
783*3db86aabSstevel 
784*3db86aabSstevel 				found++;
785*3db86aabSstevel 				if (disable) {
786*3db86aabSstevel 					if (verbose)
787*3db86aabSstevel 						cfga_msg(msgp, STR_BD,
788*3db86aabSstevel 						    DIAG_WAS_DISABLED, 0);
789*3db86aabSstevel 				} else {
790*3db86aabSstevel 					if (verbose)
791*3db86aabSstevel 						cfga_msg(msgp, STR_BD,
792*3db86aabSstevel 						    DIAG_WILL_ENABLE, 0);
793*3db86aabSstevel 					update++;
794*3db86aabSstevel 					continue;
795*3db86aabSstevel 				}
796*3db86aabSstevel 			}
797*3db86aabSstevel 			ndlist[j++] = dlist[i];
798*3db86aabSstevel 		}
799*3db86aabSstevel 		ndlist[j] = 0;
800*3db86aabSstevel 	}
801*3db86aabSstevel 
802*3db86aabSstevel 	if (!found)
803*3db86aabSstevel 		if (disable) {
804*3db86aabSstevel 			if (verbose)
805*3db86aabSstevel 				cfga_msg(msgp, STR_BD, DIAG_WILL_DISABLE, 0);
806*3db86aabSstevel 			p = &ndlist[j];
807*3db86aabSstevel 			n = sprintf(p, "%x", board);
808*3db86aabSstevel 			p[n] = 0;
809*3db86aabSstevel 			update++;
810*3db86aabSstevel 		} else {
811*3db86aabSstevel 			if (verbose)
812*3db86aabSstevel 				cfga_msg(msgp, STR_BD, DIAG_WAS_ENABLED, 0);
813*3db86aabSstevel 		}
814*3db86aabSstevel 
815*3db86aabSstevel 	if (update)
816*3db86aabSstevel 		err = prom_set_prop(prom_fd, dlprop, ndlist);
817*3db86aabSstevel 	else
818*3db86aabSstevel 		err = 0;
819*3db86aabSstevel 
820*3db86aabSstevel 	(void) close(prom_fd);
821*3db86aabSstevel 
822*3db86aabSstevel 	return (err);
823*3db86aabSstevel }
824*3db86aabSstevel 
825*3db86aabSstevel static int
826*3db86aabSstevel ap_idx(const char *ap_id)
827*3db86aabSstevel {
828*3db86aabSstevel 	int id;
829*3db86aabSstevel 	char *s;
830*3db86aabSstevel 	static char *slot = "slot";
831*3db86aabSstevel 
832*3db86aabSstevel 	DBG("ap_idx(%s)\n", ap_id);
833*3db86aabSstevel 
834*3db86aabSstevel 	if ((s = strstr(ap_id, slot)) == NULL)
835*3db86aabSstevel 		return (-1);
836*3db86aabSstevel 	else {
837*3db86aabSstevel 		int n;
838*3db86aabSstevel 
839*3db86aabSstevel 		s += strlen(slot);
840*3db86aabSstevel 		n = strlen(s);
841*3db86aabSstevel 
842*3db86aabSstevel 		DBG3("ap_idx: s=%s, n=%d\n", s, n);
843*3db86aabSstevel 
844*3db86aabSstevel 		switch (n) {
845*3db86aabSstevel 		case 2:
846*3db86aabSstevel 			if (!isdigit(s[1]))
847*3db86aabSstevel 				return (-1);
848*3db86aabSstevel 		/* FALLTHROUGH */
849*3db86aabSstevel 		case 1:
850*3db86aabSstevel 			if (!isdigit(s[0]))
851*3db86aabSstevel 				return (-1);
852*3db86aabSstevel 			break;
853*3db86aabSstevel 		default:
854*3db86aabSstevel 			return (-1);
855*3db86aabSstevel 		}
856*3db86aabSstevel 	}
857*3db86aabSstevel 
858*3db86aabSstevel 	if ((id = atoi(s)) > MAX_BOARDS)
859*3db86aabSstevel 		return (-1);
860*3db86aabSstevel 
861*3db86aabSstevel 	DBG3("ap_idx(%s)=%d\n", s, id);
862*3db86aabSstevel 
863*3db86aabSstevel 	return (id);
864*3db86aabSstevel }
865*3db86aabSstevel 
866*3db86aabSstevel /*ARGSUSED*/
867*3db86aabSstevel cfga_err_t
868*3db86aabSstevel cfga_change_state(
869*3db86aabSstevel 	cfga_cmd_t state_change_cmd,
870*3db86aabSstevel 	const char *ap_id,
871*3db86aabSstevel 	const char *options,
872*3db86aabSstevel 	struct cfga_confirm *confp,
873*3db86aabSstevel 	struct cfga_msg *msgp,
874*3db86aabSstevel 	char **errstring,
875*3db86aabSstevel 	cfga_flags_t flags)
876*3db86aabSstevel {
877*3db86aabSstevel 	int fd;
878*3db86aabSstevel 	int idx;
879*3db86aabSstevel 	int err;
880*3db86aabSstevel 	int force;
881*3db86aabSstevel 	int verbose;
882*3db86aabSstevel 	int opterr;
883*3db86aabSstevel 	int disable;
884*3db86aabSstevel 	int disabled;
885*3db86aabSstevel 	cfga_err_t rc;
886*3db86aabSstevel 	sysc_cfga_stat_t *ss;
887*3db86aabSstevel 	sysc_cfga_cmd_t *sc, sysc_cmd;
888*3db86aabSstevel 	sysc_cfga_rstate_t rs;
889*3db86aabSstevel 	sysc_cfga_ostate_t os;
890*3db86aabSstevel 	char *dlist;
891*3db86aabSstevel 	char outputstr[SYSC_OUTPUT_LEN];
892*3db86aabSstevel 
893*3db86aabSstevel 	if (errstring != NULL)
894*3db86aabSstevel 		*errstring = NULL;
895*3db86aabSstevel 
896*3db86aabSstevel 	rc = CFGA_ERROR;
897*3db86aabSstevel 
898*3db86aabSstevel 	if (options) {
899*3db86aabSstevel 		disable = 0;
900*3db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
901*3db86aabSstevel 			disable++;
902*3db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
903*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
904*3db86aabSstevel 			return (rc);
905*3db86aabSstevel 		}
906*3db86aabSstevel 	}
907*3db86aabSstevel 
908*3db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1) {
909*3db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
910*3db86aabSstevel 		return (rc);
911*3db86aabSstevel 	} else if ((ss = sysc_stat(ap_id, &fd)) == NULL) {
912*3db86aabSstevel 		cfga_err(NULL, errstring, CMD_GETSTAT, 0);
913*3db86aabSstevel 		return (rc);
914*3db86aabSstevel 	}
915*3db86aabSstevel #ifdef	SIM
916*3db86aabSstevel 	sim_idx = idx;
917*3db86aabSstevel #endif
918*3db86aabSstevel 	/*
919*3db86aabSstevel 	 * We disallow connecting on the disabled list unless
920*3db86aabSstevel 	 * either the FORCE flag or the enable-at-boot option
921*3db86aabSstevel 	 * is set. The check is made further below
922*3db86aabSstevel 	 */
923*3db86aabSstevel 	if (opterr = dlist_find(idx, &dlist, &disabled)) {
924*3db86aabSstevel 		err = disable ? OPT_DISABLE : OPT_ENABLE;
925*3db86aabSstevel 		cfga_err(NULL, errstring, err, opterr, 0);
926*3db86aabSstevel 		(void) close(fd);
927*3db86aabSstevel 		return (rc);
928*3db86aabSstevel 	} else
929*3db86aabSstevel 		force = flags & CFGA_FLAG_FORCE;
930*3db86aabSstevel 
931*3db86aabSstevel 	rs = ss[idx].rstate;
932*3db86aabSstevel 	os = ss[idx].ostate;
933*3db86aabSstevel 
934*3db86aabSstevel 	sc = &sysc_cmd;
935*3db86aabSstevel 	sysc_cmd_init(sc, outputstr, force);
936*3db86aabSstevel 	verbose = flags & CFGA_FLAG_VERBOSE;
937*3db86aabSstevel 
938*3db86aabSstevel 	switch (state_change_cmd) {
939*3db86aabSstevel 	case CFGA_CMD_CONNECT:
940*3db86aabSstevel 		if (rs != SYSC_CFGA_RSTATE_DISCONNECTED)
941*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
942*3db86aabSstevel 		else if (disabled && !(force || (options && !disable)))
943*3db86aabSstevel 			cfga_err(NULL, errstring, CMD_CONNECT,
944*3db86aabSstevel 				ERR_DISABLED, DIAG_FORCE, 0);
945*3db86aabSstevel 		else if (!(*confp->confirm)(confp->appdata_ptr,
946*3db86aabSstevel 		    cfga_str(ASK_CONNECT))) {
947*3db86aabSstevel 			(void) close(fd);
948*3db86aabSstevel 			return (CFGA_NACK);
949*3db86aabSstevel 		} else if (ioctl(fd, SYSC_CFGA_CMD_CONNECT, sc) == -1)
950*3db86aabSstevel 			cfga_err(sc, errstring, CMD_CONNECT, 0);
951*3db86aabSstevel 		else if (options && (opterr = dlist_update(idx, disable,
952*3db86aabSstevel 			dlist, msgp, verbose))) {
953*3db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
954*3db86aabSstevel 			cfga_err(NULL, errstring, err, opterr, 0);
955*3db86aabSstevel 		} else
956*3db86aabSstevel 			rc = CFGA_OK;
957*3db86aabSstevel 		break;
958*3db86aabSstevel 
959*3db86aabSstevel 	case CFGA_CMD_DISCONNECT:
960*3db86aabSstevel 		if ((os == SYSC_CFGA_OSTATE_CONFIGURED) &&
961*3db86aabSstevel 		    (ioctl(fd, SYSC_CFGA_CMD_UNCONFIGURE, sc) == -1)) {
962*3db86aabSstevel 			cfga_err(sc, errstring, CMD_UNCONFIGURE, 0);
963*3db86aabSstevel 			(void) close(fd);
964*3db86aabSstevel 			return (CFGA_ERROR);
965*3db86aabSstevel 		} else
966*3db86aabSstevel 			sysc_cmd_init(sc, outputstr, force);
967*3db86aabSstevel 
968*3db86aabSstevel 		if (rs == SYSC_CFGA_RSTATE_CONNECTED) {
969*3db86aabSstevel 			if (ioctl(fd, SYSC_CFGA_CMD_DISCONNECT, sc) == -1)
970*3db86aabSstevel 				cfga_err(sc, errstring, CMD_DISCONNECT, 0);
971*3db86aabSstevel 			else if (options && (opterr = dlist_update(idx, disable,
972*3db86aabSstevel 			    dlist, msgp, verbose))) {
973*3db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
974*3db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
975*3db86aabSstevel 			} else
976*3db86aabSstevel 				rc = CFGA_OK;
977*3db86aabSstevel 		} else
978*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
979*3db86aabSstevel 		break;
980*3db86aabSstevel 
981*3db86aabSstevel 	case CFGA_CMD_CONFIGURE:
982*3db86aabSstevel 		if (rs == SYSC_CFGA_RSTATE_DISCONNECTED)
983*3db86aabSstevel 			if (disabled && !(force || (options && !disable))) {
984*3db86aabSstevel 				cfga_err(NULL, errstring, CMD_CONFIGURE,
985*3db86aabSstevel 					ERR_DISABLED, DIAG_FORCE, 0);
986*3db86aabSstevel 				(void) close(fd);
987*3db86aabSstevel 				return (CFGA_ERROR);
988*3db86aabSstevel 			} else if (!(*confp->confirm)(confp->appdata_ptr,
989*3db86aabSstevel 			    cfga_str(ASK_CONNECT))) {
990*3db86aabSstevel 				(void) close(fd);
991*3db86aabSstevel 				return (CFGA_NACK);
992*3db86aabSstevel 			} else if (ioctl(fd, SYSC_CFGA_CMD_CONNECT, sc) == -1) {
993*3db86aabSstevel 				cfga_err(sc, errstring, CMD_CONNECT, 0);
994*3db86aabSstevel 				(void) close(fd);
995*3db86aabSstevel 				return (CFGA_ERROR);
996*3db86aabSstevel 			} else
997*3db86aabSstevel 				sysc_cmd_init(sc, outputstr, force);
998*3db86aabSstevel 
999*3db86aabSstevel 		if (os == SYSC_CFGA_OSTATE_UNCONFIGURED) {
1000*3db86aabSstevel 			if (ioctl(fd, SYSC_CFGA_CMD_CONFIGURE, sc) == -1)
1001*3db86aabSstevel 				cfga_err(sc, errstring, CMD_CONFIGURE, 0);
1002*3db86aabSstevel 			else if (options && (opterr = dlist_update(idx,
1003*3db86aabSstevel 				disable, dlist, msgp, verbose))) {
1004*3db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
1005*3db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
1006*3db86aabSstevel 			} else
1007*3db86aabSstevel 				rc = CFGA_OK;
1008*3db86aabSstevel 		} else
1009*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
1010*3db86aabSstevel 		break;
1011*3db86aabSstevel 
1012*3db86aabSstevel 	case CFGA_CMD_UNCONFIGURE:
1013*3db86aabSstevel 		if (os != SYSC_CFGA_OSTATE_CONFIGURED)
1014*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_TRANS, 0);
1015*3db86aabSstevel 		else if (ioctl(fd, SYSC_CFGA_CMD_UNCONFIGURE, sc) == -1)
1016*3db86aabSstevel 			cfga_err(sc, errstring, CMD_UNCONFIGURE, 0);
1017*3db86aabSstevel 		else if (options && (opterr = dlist_update(idx, disable,
1018*3db86aabSstevel 			dlist, msgp, verbose))) {
1019*3db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
1020*3db86aabSstevel 			cfga_err(NULL, errstring, err, opterr, 0);
1021*3db86aabSstevel 		} else
1022*3db86aabSstevel 			rc = CFGA_OK;
1023*3db86aabSstevel 		break;
1024*3db86aabSstevel 
1025*3db86aabSstevel 	default:
1026*3db86aabSstevel 		rc = CFGA_OPNOTSUPP;
1027*3db86aabSstevel 		break;
1028*3db86aabSstevel 	}
1029*3db86aabSstevel 
1030*3db86aabSstevel 	(void) close(fd);
1031*3db86aabSstevel 	return (rc);
1032*3db86aabSstevel }
1033*3db86aabSstevel 
1034*3db86aabSstevel static int
1035*3db86aabSstevel str2cond(const char *cond)
1036*3db86aabSstevel {
1037*3db86aabSstevel 	int c;
1038*3db86aabSstevel 
1039*3db86aabSstevel 	if (strcmp(cond, cfga_str(COND_UNKNOWN)) == 0)
1040*3db86aabSstevel 		c =  SYSC_CFGA_COND_UNKNOWN;
1041*3db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_OK)) == 0)
1042*3db86aabSstevel 		c =  SYSC_CFGA_COND_OK;
1043*3db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_FAILING)) == 0)
1044*3db86aabSstevel 		c =  SYSC_CFGA_COND_FAILING;
1045*3db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_FAILED)) == 0)
1046*3db86aabSstevel 		c =  SYSC_CFGA_COND_FAILED;
1047*3db86aabSstevel 	else if (strcmp(cond, cfga_str(COND_UNUSABLE)) == 0)
1048*3db86aabSstevel 		c =  SYSC_CFGA_COND_UNUSABLE;
1049*3db86aabSstevel 	else
1050*3db86aabSstevel 		c = -1;
1051*3db86aabSstevel 
1052*3db86aabSstevel 	return (c);
1053*3db86aabSstevel }
1054*3db86aabSstevel 
1055*3db86aabSstevel /*ARGSUSED*/
1056*3db86aabSstevel cfga_err_t
1057*3db86aabSstevel cfga_private_func(
1058*3db86aabSstevel 	const char *function,
1059*3db86aabSstevel 	const char *ap_id,
1060*3db86aabSstevel 	const char *options,
1061*3db86aabSstevel 	struct cfga_confirm *confp,
1062*3db86aabSstevel 	struct cfga_msg *msgp,
1063*3db86aabSstevel 	char **errstring,
1064*3db86aabSstevel 	cfga_flags_t flags)
1065*3db86aabSstevel {
1066*3db86aabSstevel 	int fd;
1067*3db86aabSstevel 	int idx;
1068*3db86aabSstevel 	int len;
1069*3db86aabSstevel 	int cmd;
1070*3db86aabSstevel 	int cond;
1071*3db86aabSstevel 	int err;
1072*3db86aabSstevel 	int opterr;
1073*3db86aabSstevel 	int verbose;
1074*3db86aabSstevel 	int disable;
1075*3db86aabSstevel 	int disabled;
1076*3db86aabSstevel 	cfga_err_t rc;
1077*3db86aabSstevel 	char *str;
1078*3db86aabSstevel 	char *dlist;
1079*3db86aabSstevel 	char outputstr[SYSC_OUTPUT_LEN];
1080*3db86aabSstevel 	sysc_cfga_cmd_t *sc, sysc_cmd;
1081*3db86aabSstevel 
1082*3db86aabSstevel 	if (errstring != NULL)
1083*3db86aabSstevel 		*errstring = NULL;
1084*3db86aabSstevel 
1085*3db86aabSstevel 	verbose = flags & CFGA_FLAG_VERBOSE;
1086*3db86aabSstevel 
1087*3db86aabSstevel 	rc = CFGA_ERROR;
1088*3db86aabSstevel 
1089*3db86aabSstevel 	if (options) {
1090*3db86aabSstevel 		disable = 0;
1091*3db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
1092*3db86aabSstevel 			disable++;
1093*3db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
1094*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
1095*3db86aabSstevel 			return (rc);
1096*3db86aabSstevel 		}
1097*3db86aabSstevel 	}
1098*3db86aabSstevel 
1099*3db86aabSstevel 	sc = &sysc_cmd;
1100*3db86aabSstevel 	str = cfga_str(CMD_SET_COND);
1101*3db86aabSstevel 	len = strlen(str);
1102*3db86aabSstevel 
1103*3db86aabSstevel 	if ((strncmp(function, str, len) == 0) && (function[len++] == '=') &&
1104*3db86aabSstevel 	    ((cond = (str2cond(&function[len]))) != -1)) {
1105*3db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST_SET_COND;
1106*3db86aabSstevel 		err = CMD_SET_COND;
1107*3db86aabSstevel 		sc->arg = cond;
1108*3db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_QUIESCE)) == 0) {
1109*3db86aabSstevel 		cmd = SYSC_CFGA_CMD_QUIESCE_TEST;
1110*3db86aabSstevel 		err = CMD_QUIESCE;
1111*3db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_INSERT)) == 0) {
1112*3db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST;
1113*3db86aabSstevel 		err = CMD_INSERT;
1114*3db86aabSstevel 	} else if (strcmp(function, cfga_str(CMD_REMOVE)) == 0) {
1115*3db86aabSstevel 		cmd = SYSC_CFGA_CMD_TEST;
1116*3db86aabSstevel 		err = CMD_REMOVE;
1117*3db86aabSstevel 	} else {
1118*3db86aabSstevel 		cfga_err(NULL, errstring, ERR_CMD_INVAL, (char *)function, 0);
1119*3db86aabSstevel 		return (rc);
1120*3db86aabSstevel 	}
1121*3db86aabSstevel 
1122*3db86aabSstevel 	sysc_cmd_init(sc, outputstr, 0);
1123*3db86aabSstevel 
1124*3db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1)
1125*3db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
1126*3db86aabSstevel 	else if (((fd = open(ap_id, O_RDWR, 0)) == -1) ||
1127*3db86aabSstevel 		(ioctl(fd, cmd, sc) == -1))
1128*3db86aabSstevel 		cfga_err(NULL, errstring, err, 0);
1129*3db86aabSstevel 	else
1130*3db86aabSstevel 		rc = CFGA_OK;
1131*3db86aabSstevel 
1132*3db86aabSstevel 	if (options) {
1133*3db86aabSstevel 		opterr = (dlist_find(idx, &dlist, &disabled) ||
1134*3db86aabSstevel 			dlist_update(idx, disable, dlist, msgp, verbose));
1135*3db86aabSstevel 		if (opterr) {
1136*3db86aabSstevel 			err = disable ? OPT_DISABLE : OPT_ENABLE;
1137*3db86aabSstevel 			if (verbose)
1138*3db86aabSstevel 				cfga_msg(msgp, err, opterr, 0);
1139*3db86aabSstevel 		}
1140*3db86aabSstevel 	}
1141*3db86aabSstevel 
1142*3db86aabSstevel 	(void) close(fd);
1143*3db86aabSstevel 	return (rc);
1144*3db86aabSstevel }
1145*3db86aabSstevel 
1146*3db86aabSstevel 
1147*3db86aabSstevel /*ARGSUSED*/
1148*3db86aabSstevel cfga_err_t
1149*3db86aabSstevel cfga_test(
1150*3db86aabSstevel 	const char *ap_id,
1151*3db86aabSstevel 	const char *options,
1152*3db86aabSstevel 	struct cfga_msg *msgp,
1153*3db86aabSstevel 	char **errstring,
1154*3db86aabSstevel 	cfga_flags_t flags)
1155*3db86aabSstevel {
1156*3db86aabSstevel 	if (errstring != NULL)
1157*3db86aabSstevel 		*errstring = NULL;
1158*3db86aabSstevel 
1159*3db86aabSstevel 	return (CFGA_OPNOTSUPP);
1160*3db86aabSstevel }
1161*3db86aabSstevel 
1162*3db86aabSstevel static cfga_stat_t
1163*3db86aabSstevel rstate_cvt(sysc_cfga_rstate_t rs)
1164*3db86aabSstevel {
1165*3db86aabSstevel 	cfga_stat_t cs;
1166*3db86aabSstevel 
1167*3db86aabSstevel 	switch (rs) {
1168*3db86aabSstevel 	case SYSC_CFGA_RSTATE_EMPTY:
1169*3db86aabSstevel 		cs = CFGA_STAT_EMPTY;
1170*3db86aabSstevel 		break;
1171*3db86aabSstevel 	case SYSC_CFGA_RSTATE_DISCONNECTED:
1172*3db86aabSstevel 		cs = CFGA_STAT_DISCONNECTED;
1173*3db86aabSstevel 		break;
1174*3db86aabSstevel 	case SYSC_CFGA_RSTATE_CONNECTED:
1175*3db86aabSstevel 		cs = CFGA_STAT_CONNECTED;
1176*3db86aabSstevel 		break;
1177*3db86aabSstevel 	default:
1178*3db86aabSstevel 		cs = CFGA_STAT_NONE;
1179*3db86aabSstevel 		break;
1180*3db86aabSstevel 	}
1181*3db86aabSstevel 
1182*3db86aabSstevel 	return (cs);
1183*3db86aabSstevel }
1184*3db86aabSstevel 
1185*3db86aabSstevel static cfga_stat_t
1186*3db86aabSstevel ostate_cvt(sysc_cfga_ostate_t os)
1187*3db86aabSstevel {
1188*3db86aabSstevel 	cfga_stat_t cs;
1189*3db86aabSstevel 
1190*3db86aabSstevel 	switch (os) {
1191*3db86aabSstevel 	case SYSC_CFGA_OSTATE_UNCONFIGURED:
1192*3db86aabSstevel 		cs = CFGA_STAT_UNCONFIGURED;
1193*3db86aabSstevel 		break;
1194*3db86aabSstevel 	case SYSC_CFGA_OSTATE_CONFIGURED:
1195*3db86aabSstevel 		cs = CFGA_STAT_CONFIGURED;
1196*3db86aabSstevel 		break;
1197*3db86aabSstevel 	default:
1198*3db86aabSstevel 		cs = CFGA_STAT_NONE;
1199*3db86aabSstevel 		break;
1200*3db86aabSstevel 	}
1201*3db86aabSstevel 
1202*3db86aabSstevel 	return (cs);
1203*3db86aabSstevel }
1204*3db86aabSstevel 
1205*3db86aabSstevel static cfga_cond_t
1206*3db86aabSstevel cond_cvt(sysc_cfga_cond_t sc)
1207*3db86aabSstevel {
1208*3db86aabSstevel 	cfga_cond_t cc;
1209*3db86aabSstevel 
1210*3db86aabSstevel 	switch (sc) {
1211*3db86aabSstevel 	case SYSC_CFGA_COND_OK:
1212*3db86aabSstevel 		cc = CFGA_COND_OK;
1213*3db86aabSstevel 		break;
1214*3db86aabSstevel 	case SYSC_CFGA_COND_FAILING:
1215*3db86aabSstevel 		cc = CFGA_COND_FAILING;
1216*3db86aabSstevel 		break;
1217*3db86aabSstevel 	case SYSC_CFGA_COND_FAILED:
1218*3db86aabSstevel 		cc = CFGA_COND_FAILED;
1219*3db86aabSstevel 		break;
1220*3db86aabSstevel 	case SYSC_CFGA_COND_UNUSABLE:
1221*3db86aabSstevel 		cc = CFGA_COND_UNUSABLE;
1222*3db86aabSstevel 		break;
1223*3db86aabSstevel 	case SYSC_CFGA_COND_UNKNOWN:
1224*3db86aabSstevel 	default:
1225*3db86aabSstevel 		cc = CFGA_COND_UNKNOWN;
1226*3db86aabSstevel 		break;
1227*3db86aabSstevel 	}
1228*3db86aabSstevel 
1229*3db86aabSstevel 	return (cc);
1230*3db86aabSstevel }
1231*3db86aabSstevel 
1232*3db86aabSstevel static char *
1233*3db86aabSstevel type_str(enum board_type type)
1234*3db86aabSstevel {
1235*3db86aabSstevel 	char *type_str;
1236*3db86aabSstevel 
1237*3db86aabSstevel 	switch (type) {
1238*3db86aabSstevel 	case MEM_BOARD:
1239*3db86aabSstevel 		type_str = cfga_str(BD_MEM);
1240*3db86aabSstevel 		break;
1241*3db86aabSstevel 	case CPU_BOARD:
1242*3db86aabSstevel 		type_str = cfga_str(BD_CPU);
1243*3db86aabSstevel 		break;
1244*3db86aabSstevel 	case IO_2SBUS_BOARD:
1245*3db86aabSstevel 		type_str = cfga_str(BD_IO_2SBUS);
1246*3db86aabSstevel 		break;
1247*3db86aabSstevel 	case IO_SBUS_FFB_BOARD:
1248*3db86aabSstevel 		type_str = cfga_str(BD_IO_SBUS_FFB);
1249*3db86aabSstevel 		break;
1250*3db86aabSstevel 	case IO_PCI_BOARD:
1251*3db86aabSstevel 		type_str = cfga_str(BD_IO_PCI);
1252*3db86aabSstevel 		break;
1253*3db86aabSstevel 	case DISK_BOARD:
1254*3db86aabSstevel 		type_str = cfga_str(BD_DISK);
1255*3db86aabSstevel 		break;
1256*3db86aabSstevel 	case IO_2SBUS_SOCPLUS_BOARD:
1257*3db86aabSstevel 		type_str = cfga_str(BD_IO_2SBUS_SOCPLUS);
1258*3db86aabSstevel 		break;
1259*3db86aabSstevel 	case IO_SBUS_FFB_SOCPLUS_BOARD:
1260*3db86aabSstevel 		type_str = cfga_str(BD_IO_SBUS_FFB_SOCPLUS);
1261*3db86aabSstevel 		break;
1262*3db86aabSstevel 	case UNKNOWN_BOARD:
1263*3db86aabSstevel 	default:
1264*3db86aabSstevel 		type_str = cfga_str(BD_UNKNOWN);
1265*3db86aabSstevel 		break;
1266*3db86aabSstevel 	}
1267*3db86aabSstevel 	return (type_str);
1268*3db86aabSstevel }
1269*3db86aabSstevel 
1270*3db86aabSstevel static void
1271*3db86aabSstevel info_set(sysc_cfga_stat_t *sc, cfga_info_t info, int disabled)
1272*3db86aabSstevel {
1273*3db86aabSstevel 	int i;
1274*3db86aabSstevel 	struct cpu_info *cpu;
1275*3db86aabSstevel 	union bd_un *bd = &sc->bd;
1276*3db86aabSstevel 
1277*3db86aabSstevel 	*info = NULL;
1278*3db86aabSstevel 
1279*3db86aabSstevel 	switch (sc->type) {
1280*3db86aabSstevel 	case CPU_BOARD:
1281*3db86aabSstevel 		for (i = 0, cpu = bd->cpu; i < 2; i++, cpu++) {
1282*3db86aabSstevel 			if (cpu->cpu_speed > 1) {
1283*3db86aabSstevel 				info += sprintf(info, "cpu %d: ", i);
1284*3db86aabSstevel 				info += sprintf(info, "%3d MHz ",
1285*3db86aabSstevel 						cpu->cpu_speed);
1286*3db86aabSstevel 				if (cpu->cache_size)
1287*3db86aabSstevel 					info += sprintf(info, "%0.1fM ",
1288*3db86aabSstevel 						(float)cpu->cache_size /
1289*3db86aabSstevel 						(float)(1024 * 1024));
1290*3db86aabSstevel 			}
1291*3db86aabSstevel 		}
1292*3db86aabSstevel 		break;
1293*3db86aabSstevel 	case IO_SBUS_FFB_BOARD:
1294*3db86aabSstevel 		switch (bd->io2.ffb_size) {
1295*3db86aabSstevel 		case FFB_SINGLE:
1296*3db86aabSstevel 			info += sprintf(info, "single buffered ffb   ");
1297*3db86aabSstevel 			break;
1298*3db86aabSstevel 		case FFB_DOUBLE:
1299*3db86aabSstevel 			info += sprintf(info, "double buffered ffb   ");
1300*3db86aabSstevel 			break;
1301*3db86aabSstevel 		case FFB_NOT_FOUND:
1302*3db86aabSstevel #ifdef FFB_DR_SUPPORT
1303*3db86aabSstevel 			info += sprintf(info, "no ffb installed   ");
1304*3db86aabSstevel #endif
1305*3db86aabSstevel 			break;
1306*3db86aabSstevel 		default:
1307*3db86aabSstevel 			info += sprintf(info, "illegal ffb size   ");
1308*3db86aabSstevel 			break;
1309*3db86aabSstevel 		}
1310*3db86aabSstevel 		break;
1311*3db86aabSstevel 	case DISK_BOARD:
1312*3db86aabSstevel 		for (i = 0; i < 2; i++)
1313*3db86aabSstevel 			if (bd->dsk.disk_pres[i])
1314*3db86aabSstevel 				info += sprintf(info, "target: %2d ",
1315*3db86aabSstevel 						bd->dsk.disk_id[i]);
1316*3db86aabSstevel 			else
1317*3db86aabSstevel 				info += sprintf(info, "no disk   ");
1318*3db86aabSstevel 		break;
1319*3db86aabSstevel 	}
1320*3db86aabSstevel 
1321*3db86aabSstevel 	if (disabled)
1322*3db86aabSstevel 		info += sprintf(info, "disabled at boot   ");
1323*3db86aabSstevel 
1324*3db86aabSstevel 	if (sc->no_detach)
1325*3db86aabSstevel 		info += sprintf(info, "non-detachable   ");
1326*3db86aabSstevel 
1327*3db86aabSstevel 	if (sc->plus_board)
1328*3db86aabSstevel 		info += sprintf(info, "100 MHz capable   ");
1329*3db86aabSstevel }
1330*3db86aabSstevel 
1331*3db86aabSstevel static void
1332*3db86aabSstevel sysc_cvt(sysc_cfga_stat_t *sc, cfga_stat_data_t *cs, int disabled)
1333*3db86aabSstevel {
1334*3db86aabSstevel 	(void) strcpy(cs->ap_type, type_str(sc->type));
1335*3db86aabSstevel 	cs->ap_r_state = rstate_cvt(sc->rstate);
1336*3db86aabSstevel 	cs->ap_o_state = ostate_cvt(sc->ostate);
1337*3db86aabSstevel 	cs->ap_cond = cond_cvt(sc->condition);
1338*3db86aabSstevel 	cs->ap_busy = (cfga_busy_t)sc->in_transition;
1339*3db86aabSstevel 	cs->ap_status_time = sc->last_change;
1340*3db86aabSstevel 	info_set(sc, cs->ap_info, disabled);
1341*3db86aabSstevel 	cs->ap_log_id[0] = NULL;
1342*3db86aabSstevel 	cs->ap_phys_id[0] = NULL;
1343*3db86aabSstevel }
1344*3db86aabSstevel 
1345*3db86aabSstevel /*ARGSUSED*/
1346*3db86aabSstevel cfga_err_t
1347*3db86aabSstevel cfga_list(
1348*3db86aabSstevel 	const char *ap_id,
1349*3db86aabSstevel 	cfga_stat_data_t **ap_list,
1350*3db86aabSstevel 	int *nlist,
1351*3db86aabSstevel 	const char *options,
1352*3db86aabSstevel 	char **errstring)
1353*3db86aabSstevel {
1354*3db86aabSstevel 	int i;
1355*3db86aabSstevel 	cfga_err_t rc;
1356*3db86aabSstevel 	sysc_cfga_stat_t *sc;
1357*3db86aabSstevel 	cfga_stat_data_t *cs;
1358*3db86aabSstevel 
1359*3db86aabSstevel 	if (errstring != NULL)
1360*3db86aabSstevel 		*errstring = NULL;
1361*3db86aabSstevel 
1362*3db86aabSstevel 	rc = CFGA_ERROR;
1363*3db86aabSstevel 
1364*3db86aabSstevel 	if (ap_idx(ap_id) == -1)
1365*3db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
1366*3db86aabSstevel 	else if ((sc = sysc_stat(ap_id, NULL)) == NULL)
1367*3db86aabSstevel 		cfga_err(NULL, errstring, CMD_LIST, 0);
1368*3db86aabSstevel 	else if (!(cs = (cfga_stat_data_t *)malloc(MAX_BOARDS * sizeof (*cs))))
1369*3db86aabSstevel 		cfga_err(NULL, errstring, CMD_LIST, 0);
1370*3db86aabSstevel 	else {
1371*3db86aabSstevel 		*ap_list = cs;
1372*3db86aabSstevel 
1373*3db86aabSstevel 		for (*nlist = 0, i = 0; i < MAX_BOARDS; i++, sc++) {
1374*3db86aabSstevel 			if (sc->board == -1)
1375*3db86aabSstevel 				continue;
1376*3db86aabSstevel 			sysc_cvt(sc, cs++, 0); /* XXX - disable */
1377*3db86aabSstevel 			(*nlist)++;
1378*3db86aabSstevel 		}
1379*3db86aabSstevel 
1380*3db86aabSstevel 		rc = CFGA_OK;
1381*3db86aabSstevel 	}
1382*3db86aabSstevel 
1383*3db86aabSstevel 	return (rc);
1384*3db86aabSstevel }
1385*3db86aabSstevel 
1386*3db86aabSstevel /*ARGSUSED*/
1387*3db86aabSstevel cfga_err_t
1388*3db86aabSstevel cfga_stat(
1389*3db86aabSstevel 	const char *ap_id,
1390*3db86aabSstevel 	struct cfga_stat_data *cs,
1391*3db86aabSstevel 	const char *options,
1392*3db86aabSstevel 	char **errstring)
1393*3db86aabSstevel {
1394*3db86aabSstevel 	cfga_err_t rc;
1395*3db86aabSstevel 	int idx;
1396*3db86aabSstevel 	int err;
1397*3db86aabSstevel 	int opterr;
1398*3db86aabSstevel 	int disable;
1399*3db86aabSstevel 	int disabled;
1400*3db86aabSstevel 	char *dlist;
1401*3db86aabSstevel 	sysc_cfga_stat_t *sc;
1402*3db86aabSstevel 
1403*3db86aabSstevel 	if (errstring != NULL)
1404*3db86aabSstevel 		*errstring = NULL;
1405*3db86aabSstevel 
1406*3db86aabSstevel 	rc = CFGA_ERROR;
1407*3db86aabSstevel 
1408*3db86aabSstevel 	if (options && options[0]) {
1409*3db86aabSstevel 		disable = 0;
1410*3db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
1411*3db86aabSstevel 			disable++;
1412*3db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE))) {
1413*3db86aabSstevel 			cfga_err(NULL, errstring, ERR_OPT_INVAL, options, 0);
1414*3db86aabSstevel 			return (rc);
1415*3db86aabSstevel 		}
1416*3db86aabSstevel 	}
1417*3db86aabSstevel 
1418*3db86aabSstevel 	if ((idx = ap_idx(ap_id)) == -1)
1419*3db86aabSstevel 		cfga_err(NULL, errstring, ERR_AP_INVAL, ap_id, 0);
1420*3db86aabSstevel 	else if ((sc = sysc_stat(ap_id, NULL)) == NULL)
1421*3db86aabSstevel 		cfga_err(NULL, errstring, CMD_GETSTAT, 0);
1422*3db86aabSstevel 	else {
1423*3db86aabSstevel 		opterr = dlist_find(idx, &dlist, &disabled);
1424*3db86aabSstevel 		sysc_cvt(sc + idx, cs, disabled);
1425*3db86aabSstevel 
1426*3db86aabSstevel 		rc = CFGA_OK;
1427*3db86aabSstevel 
1428*3db86aabSstevel 		if (options && options[0] && ((opterr != 0) ||
1429*3db86aabSstevel 			((opterr = dlist_update(idx, disable, dlist, NULL, 0))
1430*3db86aabSstevel 			!= 0))) {
1431*3db86aabSstevel 				err = disable ? OPT_DISABLE : OPT_ENABLE;
1432*3db86aabSstevel 				cfga_err(NULL, errstring, err, opterr, 0);
1433*3db86aabSstevel 		}
1434*3db86aabSstevel 	}
1435*3db86aabSstevel 
1436*3db86aabSstevel 	return (rc);
1437*3db86aabSstevel }
1438*3db86aabSstevel 
1439*3db86aabSstevel /*ARGSUSED*/
1440*3db86aabSstevel cfga_err_t
1441*3db86aabSstevel cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
1442*3db86aabSstevel {
1443*3db86aabSstevel 	int help = 0;
1444*3db86aabSstevel 
1445*3db86aabSstevel 	if (options) {
1446*3db86aabSstevel 		if (strcmp(options, cfga_str(OPT_DISABLE)) == 0)
1447*3db86aabSstevel 			help = HELP_DISABLE;
1448*3db86aabSstevel 		else if (strcmp(options, cfga_str(OPT_ENABLE)) == 0)
1449*3db86aabSstevel 			help = HELP_ENABLE;
1450*3db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_INSERT)) == 0)
1451*3db86aabSstevel 			help = HELP_INSERT;
1452*3db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_REMOVE)) == 0)
1453*3db86aabSstevel 			help = HELP_REMOVE;
1454*3db86aabSstevel 		else if (strcmp(options, cfga_str(CMD_QUIESCE)) == 0)
1455*3db86aabSstevel 			help = HELP_QUIESCE;
1456*3db86aabSstevel 		else
1457*3db86aabSstevel 			help = HELP_UNKNOWN;
1458*3db86aabSstevel 	}
1459*3db86aabSstevel 
1460*3db86aabSstevel 	if (help)  {
1461*3db86aabSstevel 		if (help == HELP_UNKNOWN)
1462*3db86aabSstevel 			cfga_msg(msgp, help, options, 0);
1463*3db86aabSstevel 		else
1464*3db86aabSstevel 			cfga_msg(msgp, help, 0);
1465*3db86aabSstevel 	} else {
1466*3db86aabSstevel 		cfga_msg(msgp, HELP_HEADER, 0);
1467*3db86aabSstevel 		cfga_msg(msgp, HELP_DISABLE, 0);
1468*3db86aabSstevel 		cfga_msg(msgp, HELP_ENABLE, 0);
1469*3db86aabSstevel 		cfga_msg(msgp, HELP_INSERT, 0);
1470*3db86aabSstevel 		cfga_msg(msgp, HELP_REMOVE, 0);
1471*3db86aabSstevel 		cfga_msg(msgp, HELP_QUIESCE, 0);
1472*3db86aabSstevel 		cfga_msg(msgp, HELP_SET_COND, 0);
1473*3db86aabSstevel 	}
1474*3db86aabSstevel 
1475*3db86aabSstevel 	return (CFGA_OK);
1476*3db86aabSstevel }
1477*3db86aabSstevel 
1478*3db86aabSstevel /*
1479*3db86aabSstevel  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
1480*3db86aabSstevel  */
1481