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