4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <sys/types.h>
43 #include <sys/ioctl.h>
44 #include <sys/dditypes.h>
45 #include <sys/modctl.h>
46 #include <sys/obpdefs.h>
48 #include <sys/sysctrl.h>
49 #include <sys/openpromio.h>
53 #define CFGA_PLUGIN_LIB
54 #include <config_admin.h>
65 #define DBG4(a, b, c, d)
71 #define BD_IO_SBUS_FFB 4
74 #define BD_IO_2SBUS_SOCPLUS 7
75 #define BD_IO_SBUS_FFB_SOCPLUS 8
77 #define CMD_GETSTAT 10
79 #define CMD_CONNECT 12
80 #define CMD_DISCONNECT 13
81 #define CMD_CONFIGURE 14
82 #define CMD_UNCONFIGURE 15
83 #define CMD_QUIESCE 16
86 #define CMD_SET_COND 19
88 #define OPT_DISABLE 21
89 #define ERR_PROM_OPEN 22
90 #define ERR_PROM_GETPROP 23
91 #define ERR_PROM_SETPROP 24
93 #define ERR_CMD_INVAL 26
94 #define ERR_OPT_INVAL 27
95 #define ERR_AP_INVAL 28
96 #define ERR_DISABLED 29
98 #define DIAG_TRANS_OK 31
99 #define DIAG_FAILED 32
100 #define DIAG_WAS_ENABLED 33
101 #define DIAG_WAS_DISABLED 34
102 #define DIAG_WILL_ENABLE 35
103 #define DIAG_WILL_DISABLE 36
104 #define HELP_HEADER 37
105 #define HELP_QUIESCE 38
106 #define HELP_INSERT 39
107 #define HELP_REMOVE 40
108 #define HELP_SET_COND 41
109 #define HELP_ENABLE 42
110 #define HELP_DISABLE 43
111 #define HELP_UNKNOWN 44
112 #define ASK_CONNECT 45
115 #define COND_UNKNOWN 48
117 #define COND_FAILING 50
118 #define COND_FAILED 51
119 #define COND_UNUSABLE 52
120 #define SYSC_COOLING 53
121 #define SYSC_POWER 54
122 #define SYSC_PRECHARGE 55
123 #define SYSC_INTRANS 56
124 #define SYSC_UTHREAD 57
125 #define SYSC_KTHREAD 58
126 #define SYSC_DEV_ATTACH 59
127 #define SYSC_DEV_DETACH 60
128 #define SYSC_NDI_ATTACH 61
129 #define SYSC_NDI_DETACH 62
130 #define SYSC_CORE_RESOURCE 63
131 #define SYSC_OSTATE 64
132 #define SYSC_RSTATE 65
135 #define SYSC_NOMEM 68
136 #define SYSC_HOTPLUG 69
137 #define SYSC_HW_COMPAT 70
138 #define SYSC_NON_DR_PROM 71
139 #define SYSC_SUSPEND 72
140 #define SYSC_RESUME 73
141 #define SYSC_UNKNOWN 74
142 #define SYSC_DEVSTR 75
145 * The string table contains all the strings used by the platform
146 * library. The comment next to each string specifies whether the
147 * string should be internationalized (y) or not (n).
148 * Note that there are calls to dgettext() with strings other than
149 * the ones below, they are marked by the li18 symbol.
156 /* n */ "dual-sbus ",
163 /* n */ "get-status",
166 /* n */ "disconnect",
168 /* n */ "unconfigure",
169 /* n */ "quiesce-test",
170 /* n */ "insert-test",
171 /* n */ "remove-test",
172 /* n */ "set-condition-test",
173 /* n */ "enable-at-boot",
174 /* n */ "disable-at-boot",
176 /* n */ "prom getprop",
177 /* n */ "prom setprop",
178 /* y */ "invalid transition",
179 /* y */ "invalid command: ",
180 /* y */ "invalid option: ",
181 /* y */ "invalid attachment point: ",
182 /* y */ "board is disabled: must override with ",
183 /* n */ "[-f][-o enable-at-boot]",
184 /* y */ "transition succeeded but ",
186 /* y */ "was already enabled at boot time",
187 /* y */ "was already disabled at boot time",
188 /* y */ "will be enabled at boot time",
189 /* y */ "will be disabled at boot time",
190 /* y */ "\nSysctrl specific commands/options:",
191 /* n */ "\t-x quiesce-test ap_id [ap_id...]",
192 /* n */ "\t-x insert-test ap_id [ap_id...]",
193 /* n */ "\t-x remove-test ap_id [ap_id...]",
194 /* n */ "\t-x set-condition-test=<condition>",
195 /* n */ "\t-o enable-at-boot",
196 /* n */ "\t-o disable-at-boot",
197 /* y */ "\tunknown command or option: ",
199 "system will be temporarily suspended to connect a board: proceed",
207 /* y */ "not enough cooling for a new board",
208 /* y */ "not enough power for a new board",
209 /* y */ "not enough precharge power for a new board",
210 /* y */ "configuration operation already in progress on this board",
211 /* y */ "could not suspend user process: ",
212 /* y */ "could not suspend system processes",
213 /* y */ "device did not attach",
214 /* y */ "device did not detach",
215 /* y */ "nexus error during attach",
216 /* y */ "nexus error during detach",
217 /* y */ "attempt to remove core system resource",
218 /* y */ "invalid occupant state",
219 /* y */ "invalid receptacle state",
220 /* y */ "insufficient condition",
221 /* y */ "firmware operation error",
222 /* y */ "not enough memory",
223 /* y */ "hotplug feature unavailable on this machine",
224 /* y */ "board does not support dynamic reconfiguration",
225 /* y */ "firmware does not support dynamic reconfiguration",
226 /* y */ "system suspend error",
227 /* y */ "system resume error",
228 /* y */ "unknown system error",
232 #define cfga_str(i) cfga_strs[(i)]
234 #define cfga_eid(a, b) (((a) << 8) + (b))
238 * Translation table for mapping from an <errno,sysc_err>
239 * pair to an error string.
242 * SYSC_COOLING, EAGAIN, SYSC_ERR_COOLING
243 * SYSC_POWER, EAGAIN, SYSC_ERR_POWER
244 * SYSC_PRECHARGE, EAGAIN, SYSC_ERR_PRECHARGE
245 * SYSC_INTRANS, EBUSY, SYSC_ERR_INTRANS
246 * SYSC_KTHREAD, EBUSY, SYSC_ERR_KTHREAD
247 * SYSC_DEV_ATTACH, EBUSY, SYSC_ERR_NDI_ATTACH
248 * SYSC_DEV_DETACH, EBUSY, SYSC_ERR_NDI_DETACH
249 * SYSC_NDI_ATTACH, EFAULT, SYSC_ERR_NDI_ATTACH
250 * SYSC_NDI_DETACH, EFAULT, SYSC_ERR_NDI_DETACH
251 * SYSC_CORE_RESOURCE, EINVAL, SYSC_ERR_CORE_RESOURCE
252 * SYSC_OSTATE, EINVAL, SYSC_ERR_OSTATE
253 * SYSC_RSTATE, EINVAL, SYSC_ERR_RSTATE
254 * SYSC_COND, EINVAL, SYSC_ERR_COND
255 * SYSC_PROM, EIO, SYSC_ERR_PROM
256 * SYSC_NOMEM, ENOMEM, SYSC_ERR_DR_INIT
257 * SYSC_NOMEM, ENOMEM, SYSC_ERR_NDI_ATTACH
258 * SYSC_NOMEM, ENOMEM, SYSC_ERR_NDI_DETACH
259 * SYSC_HOTPLUG, ENOTSUP, SYSC_ERR_HOTPLUG
260 * SYSC_HW_COMPAT, ENOTSUP, SYSC_ERR_HW_COMPAT
261 * SYSC_NON_DR_PROM, ENOTSUP, SYSC_ERR_NON_DR_PROM
262 * SYSC_SUSPEND, ENXIO, SYSC_ERR_SUSPEND
263 * SYSC_RESUME, ENXIO, SYSC_ERR_RESUME
264 * SYSC_UTHREAD, ESRCH, SYSC_ERR_UTHREAD
267 cfga_sid(int err
, int scerr
)
269 if (scerr
== SYSC_ERR_DEFAULT
)
270 return (SYSC_UNKNOWN
);
272 switch (cfga_eid(err
, scerr
)) {
273 case cfga_eid(EAGAIN
, SYSC_ERR_COOLING
):
274 return (SYSC_COOLING
);
275 case cfga_eid(EAGAIN
, SYSC_ERR_POWER
):
277 case cfga_eid(EAGAIN
, SYSC_ERR_PRECHARGE
):
278 return (SYSC_PRECHARGE
);
279 case cfga_eid(EBUSY
, SYSC_ERR_INTRANS
):
280 return (SYSC_INTRANS
);
281 case cfga_eid(EBUSY
, SYSC_ERR_KTHREAD
):
282 return (SYSC_KTHREAD
);
283 case cfga_eid(EBUSY
, SYSC_ERR_NDI_ATTACH
):
284 return (SYSC_DEV_ATTACH
);
285 case cfga_eid(EBUSY
, SYSC_ERR_NDI_DETACH
):
286 return (SYSC_DEV_DETACH
);
287 case cfga_eid(EFAULT
, SYSC_ERR_NDI_ATTACH
):
288 return (SYSC_NDI_ATTACH
);
289 case cfga_eid(EFAULT
, SYSC_ERR_NDI_DETACH
):
290 return (SYSC_NDI_DETACH
);
291 case cfga_eid(EINVAL
, SYSC_ERR_CORE_RESOURCE
):
292 return (SYSC_CORE_RESOURCE
);
293 case cfga_eid(EINVAL
, SYSC_ERR_OSTATE
):
294 return (SYSC_OSTATE
);
295 case cfga_eid(EINVAL
, SYSC_ERR_RSTATE
):
296 return (SYSC_RSTATE
);
297 case cfga_eid(EINVAL
, SYSC_ERR_COND
):
299 case cfga_eid(EIO
, SYSC_ERR_PROM
):
301 case cfga_eid(ENOMEM
, SYSC_ERR_DR_INIT
):
303 case cfga_eid(ENOMEM
, SYSC_ERR_NDI_ATTACH
):
305 case cfga_eid(ENOMEM
, SYSC_ERR_NDI_DETACH
):
307 case cfga_eid(ENOTSUP
, SYSC_ERR_HOTPLUG
):
308 return (SYSC_HOTPLUG
);
309 case cfga_eid(ENOTSUP
, SYSC_ERR_HW_COMPAT
):
310 return (SYSC_HW_COMPAT
);
311 case cfga_eid(ENOTSUP
, SYSC_ERR_NON_DR_PROM
):
312 return (SYSC_NON_DR_PROM
);
313 case cfga_eid(ENXIO
, SYSC_ERR_SUSPEND
):
314 return (SYSC_SUSPEND
);
315 case cfga_eid(ENXIO
, SYSC_ERR_RESUME
):
316 return (SYSC_RESUME
);
317 case cfga_eid(ESRCH
, SYSC_ERR_UTHREAD
):
318 return (SYSC_UTHREAD
);
323 return (SYSC_UNKNOWN
);
327 sysc_cmd_init(sysc_cfga_cmd_t
*sc
, char *outputstr
, int force
)
330 sc
->outputstr
= outputstr
;
331 sc
->errtype
= SYSC_ERR_DEFAULT
;
333 (void) memset((void *)outputstr
, 0, sizeof (outputstr
));
335 cfga_str(SYSC_DEVSTR
) = outputstr
;
339 * cfga_err() accepts a variable number of message IDs and constructs
340 * a corresponding error string which is returned via the errstring argument.
341 * cfga_err() calls dgettext() to internationalize proper messages.
344 cfga_err(sysc_cfga_cmd_t
*sc
, char **errstring
, ...)
359 * If errstring is null it means user in not interested in getting
360 * error status. So we don't do all the work
362 if (errstring
== NULL
) {
365 va_start(ap
, errstring
);
367 failed
= dgettext(TEXT_DOMAIN
, cfga_str(DIAG_FAILED
));
368 flen
= strlen(failed
);
370 for (n
= len
= 0; (a
= va_arg(ap
, int)) != 0; n
++) {
374 case ERR_PROM_GETPROP
:
375 case ERR_PROM_SETPROP
:
381 case CMD_UNCONFIGURE
:
387 len
+= (strlen(p
) + flen
);
397 p
= dgettext(TEXT_DOMAIN
, cfga_str(DIAG_TRANS_OK
));
399 len
+= (strlen(p
) + strlen(q
) + flen
);
412 p
= dgettext(TEXT_DOMAIN
, cfga_str(a
));
413 q
= va_arg(ap
, char *);
414 len
+= (strlen(p
) + strlen(q
));
424 p
= dgettext(TEXT_DOMAIN
, cfga_str(a
));
447 i
= cfga_sid(errno
, (int)sc
->errtype
);
451 DBG4("cfga_sid(%d,%d)=%d\n", errno
, sc
->errtype
, i
);
453 if (i
== SYSC_UNKNOWN
) {
456 (void) sprintf(syserr_num
, "errno=%d", errno
);
460 p
= dgettext(TEXT_DOMAIN
, cfga_str(i
));
464 p
= cfga_str(SYSC_DEVSTR
);
466 q
= cfga_str(STR_COL
);
475 if ((p
= (char *)calloc(len
, 1)) == NULL
)
478 for (i
= 0; i
< n
; i
++)
479 (void) strcat(p
, s
[i
]);
483 printf("%s\n", *errstring
);
488 * This routine accepts a variable number of message IDs and constructs
489 * a corresponding error string which is printed via the message print routine
490 * argument. The HELP_UNKNOWN message ID has an argument string (the unknown
491 * help topic) that follows.
494 cfga_msg(struct cfga_msg
*msgp
, ...)
506 for (n
= len
= 0; (a
= va_arg(ap
, int)) != 0; n
++) {
508 p
= dgettext(TEXT_DOMAIN
, cfga_str(a
));
511 if (a
== HELP_UNKNOWN
) {
512 p
= va_arg(ap
, char *);
520 if ((p
= (char *)calloc(len
+ 1, 1)) == NULL
)
523 for (i
= 0; i
< n
; i
++)
524 (void) strcat(p
, s
[i
]);
525 (void) strcat(p
, "\n");
530 (*msgp
->message_routine
)(msgp
->appdata_ptr
, p
);
535 static sysc_cfga_stat_t
*
536 sysc_stat(const char *ap_id
, int *fdp
)
539 static sysc_cfga_stat_t sc_list
[MAX_BOARDS
];
542 if ((fd
= open(ap_id
, O_RDWR
, 0)) == -1)
544 else if (ioctl(fd
, SYSC_CFGA_CMD_GETSTATUS
, sc_list
) == -1) {
556 * This code implementes the simulation of the ioctls that transition state.
557 * The GETSTAT ioctl is not simulated. In this way a snapshot of the system
558 * state is read and manipulated by the simulation routines. It is basically
559 * a useful debugging tool.
563 static int sim_fd
= -1;
564 static int sim_size
= MAX_BOARDS
* sizeof (sysc_cfga_stat_t
);
565 static sysc_cfga_stat_t sim_sc_list
[MAX_BOARDS
];
567 static sysc_cfga_stat_t
*
568 sim_sysc_stat(const char *ap_id
, int *fdp
)
574 return (sim_sc_list
);
576 if ((sim_fd
= open("/tmp/cfga_simdata", O_RDWR
|O_CREAT
)) == -1) {
579 } else if (fstat(sim_fd
, &buf
) == -1) {
585 if (buf
.st_size
!= sim_size
) {
588 } else if (read(sim_fd
, sim_sc_list
, sim_size
) == -1) {
592 } else if ((fd
= open(ap_id
, O_RDWR
, 0)) == -1)
594 else if (ioctl(fd
, SYSC_CFGA_CMD_GETSTATUS
, sim_sc_list
) == -1) {
600 return (sim_sc_list
);
604 sim_open(char *a
, int b
, int c
)
606 printf("sim_open(%s)\n", a
);
608 if (strcmp(a
, "/dev/openprom") == 0)
609 return (open(a
, b
, c
));
614 sim_close(int a
) { return (0); }
617 sim_ioctl(int fd
, int cmd
, void *a
)
619 printf("sim_ioctl(%d)\n", sim_idx
);
622 case SYSC_CFGA_CMD_CONNECT
:
623 sim_sc_list
[sim_idx
].rstate
= SYSC_CFGA_RSTATE_CONNECTED
;
625 case SYSC_CFGA_CMD_CONFIGURE
:
626 sim_sc_list
[sim_idx
].ostate
= SYSC_CFGA_OSTATE_CONFIGURED
;
628 case SYSC_CFGA_CMD_UNCONFIGURE
:
629 sim_sc_list
[sim_idx
].ostate
= SYSC_CFGA_OSTATE_UNCONFIGURED
;
631 case SYSC_CFGA_CMD_DISCONNECT
:
632 sim_sc_list
[sim_idx
].rstate
= SYSC_CFGA_RSTATE_DISCONNECTED
;
634 case SYSC_CFGA_CMD_QUIESCE_TEST
:
635 case SYSC_CFGA_CMD_TEST
:
638 return (ioctl(fd
, OPROMGETOPT
, a
));
640 return (ioctl(fd
, OPROMSETOPT
, a
));
643 if (lseek(sim_fd
, SEEK_SET
, 0) == -1) {
647 if (write(sim_fd
, sim_sc_list
, sim_size
) == -1) {
655 #define open(a, b, c) sim_open((char *)(a), (int)(b), (int)(c))
656 #define close(a) sim_close(a)
657 #define ioctl(a, b, c) sim_ioctl((int)(a), (int)(b), (void *)(c))
658 #define sysc_stat(a, b) sim_sysc_stat(a, b)
661 static char *promdev
= "/dev/openprom";
662 static char *dlprop
= "disabled-board-list";
668 struct openpromio opp
;
672 prom_get_prop(int prom_fd
, char *var
, char **val
)
674 static oppbuf_t oppbuf
;
675 struct openpromio
*opp
= &(oppbuf
.opp
);
677 (void) strncpy(opp
->oprom_array
, var
, OBP_MAXPROPNAME
);
678 opp
->oprom_array
[OBP_MAXPROPNAME
+ 1] = '\0';
679 opp
->oprom_size
= BUFSIZE
;
681 DBG3("getprop(%s, %d)\n", opp
->oprom_array
, opp
->oprom_size
);
683 if (ioctl(prom_fd
, OPROMGETOPT
, opp
) < 0)
684 return (ERR_PROM_GETPROP
);
685 else if (opp
->oprom_size
> 0)
686 *val
= opp
->oprom_array
;
694 prom_set_prop(int prom_fd
, char *var
, char *val
)
697 struct openpromio
*opp
= &(oppbuf
.opp
);
698 int varlen
= strlen(var
) + 1;
699 int vallen
= strlen(val
);
701 DBG("prom_set_prop(%s)\n", val
);
703 (void) strcpy(opp
->oprom_array
, var
);
704 (void) strcpy(opp
->oprom_array
+ varlen
, val
);
705 opp
->oprom_size
= varlen
+ vallen
;
707 if (ioctl(prom_fd
, OPROMSETOPT
, opp
) < 0)
708 return (ERR_PROM_SETPROP
);
714 dlist_find(int board
, char **dlist
, int *disabled
)
723 if ((prom_fd
= open(promdev
, O_RDWR
, 0)) < 0)
724 return (ERR_PROM_OPEN
);
725 else if (err
= prom_get_prop(prom_fd
, dlprop
, dlist
)) {
726 (void) close(prom_fd
);
729 (void) close(prom_fd
);
734 if ((dl
= *dlist
) != NULL
) {
735 int len
= strlen(dl
);
737 for (i
= 0; i
< len
; i
++) {
741 bd
= strtol(b
, &p
, 16);
743 if (p
!= b
&& bd
== board
)
752 dlist_update(int board
, int disable
, char *dlist
, struct cfga_msg
*msgp
,
770 if ((prom_fd
= open(promdev
, O_RDWR
, 0)) < 0)
771 return (ERR_PROM_OPEN
);
774 int len
= strlen(dlist
);
776 for (i
= 0; i
< len
; i
++) {
780 bd
= strtol(b
, &p
, 16);
782 if (p
!= b
&& bd
== board
) {
787 cfga_msg(msgp
, STR_BD
,
788 DIAG_WAS_DISABLED
, 0);
791 cfga_msg(msgp
, STR_BD
,
792 DIAG_WILL_ENABLE
, 0);
797 ndlist
[j
++] = dlist
[i
];
805 cfga_msg(msgp
, STR_BD
, DIAG_WILL_DISABLE
, 0);
807 n
= sprintf(p
, "%x", board
);
812 cfga_msg(msgp
, STR_BD
, DIAG_WAS_ENABLED
, 0);
816 err
= prom_set_prop(prom_fd
, dlprop
, ndlist
);
820 (void) close(prom_fd
);
826 ap_idx(const char *ap_id
)
830 static char *slot
= "slot";
832 DBG("ap_idx(%s)\n", ap_id
);
834 if ((s
= strstr(ap_id
, slot
)) == NULL
)
842 DBG3("ap_idx: s=%s, n=%d\n", s
, n
);
858 if ((id
= atoi(s
)) > MAX_BOARDS
)
861 DBG3("ap_idx(%s)=%d\n", s
, id
);
869 cfga_cmd_t state_change_cmd
,
872 struct cfga_confirm
*confp
,
873 struct cfga_msg
*msgp
,
886 sysc_cfga_stat_t
*ss
;
887 sysc_cfga_cmd_t
*sc
, sysc_cmd
;
888 sysc_cfga_rstate_t rs
;
889 sysc_cfga_ostate_t os
;
891 char outputstr
[SYSC_OUTPUT_LEN
];
893 if (errstring
!= NULL
)
900 if (strcmp(options
, cfga_str(OPT_DISABLE
)) == 0)
902 else if (strcmp(options
, cfga_str(OPT_ENABLE
))) {
903 cfga_err(NULL
, errstring
, ERR_OPT_INVAL
, options
, 0);
908 if ((idx
= ap_idx(ap_id
)) == -1) {
909 cfga_err(NULL
, errstring
, ERR_AP_INVAL
, ap_id
, 0);
911 } else if ((ss
= sysc_stat(ap_id
, &fd
)) == NULL
) {
912 cfga_err(NULL
, errstring
, CMD_GETSTAT
, 0);
919 * We disallow connecting on the disabled list unless
920 * either the FORCE flag or the enable-at-boot option
921 * is set. The check is made further below
923 if (opterr
= dlist_find(idx
, &dlist
, &disabled
)) {
924 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
925 cfga_err(NULL
, errstring
, err
, opterr
, 0);
929 force
= flags
& CFGA_FLAG_FORCE
;
935 sysc_cmd_init(sc
, outputstr
, force
);
936 verbose
= flags
& CFGA_FLAG_VERBOSE
;
938 switch (state_change_cmd
) {
939 case CFGA_CMD_CONNECT
:
940 if (rs
!= SYSC_CFGA_RSTATE_DISCONNECTED
)
941 cfga_err(NULL
, errstring
, ERR_TRANS
, 0);
942 else if (disabled
&& !(force
|| (options
&& !disable
)))
943 cfga_err(NULL
, errstring
, CMD_CONNECT
,
944 ERR_DISABLED
, DIAG_FORCE
, 0);
945 else if (!(*confp
->confirm
)(confp
->appdata_ptr
,
946 cfga_str(ASK_CONNECT
))) {
949 } else if (ioctl(fd
, SYSC_CFGA_CMD_CONNECT
, sc
) == -1)
950 cfga_err(sc
, errstring
, CMD_CONNECT
, 0);
951 else if (options
&& (opterr
= dlist_update(idx
, disable
,
952 dlist
, msgp
, verbose
))) {
953 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
954 cfga_err(NULL
, errstring
, err
, opterr
, 0);
959 case CFGA_CMD_DISCONNECT
:
960 if ((os
== SYSC_CFGA_OSTATE_CONFIGURED
) &&
961 (ioctl(fd
, SYSC_CFGA_CMD_UNCONFIGURE
, sc
) == -1)) {
962 cfga_err(sc
, errstring
, CMD_UNCONFIGURE
, 0);
966 sysc_cmd_init(sc
, outputstr
, force
);
968 if (rs
== SYSC_CFGA_RSTATE_CONNECTED
) {
969 if (ioctl(fd
, SYSC_CFGA_CMD_DISCONNECT
, sc
) == -1)
970 cfga_err(sc
, errstring
, CMD_DISCONNECT
, 0);
971 else if (options
&& (opterr
= dlist_update(idx
, disable
,
972 dlist
, msgp
, verbose
))) {
973 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
974 cfga_err(NULL
, errstring
, err
, opterr
, 0);
978 cfga_err(NULL
, errstring
, ERR_TRANS
, 0);
981 case CFGA_CMD_CONFIGURE
:
982 if (rs
== SYSC_CFGA_RSTATE_DISCONNECTED
)
983 if (disabled
&& !(force
|| (options
&& !disable
))) {
984 cfga_err(NULL
, errstring
, CMD_CONFIGURE
,
985 ERR_DISABLED
, DIAG_FORCE
, 0);
988 } else if (!(*confp
->confirm
)(confp
->appdata_ptr
,
989 cfga_str(ASK_CONNECT
))) {
992 } else if (ioctl(fd
, SYSC_CFGA_CMD_CONNECT
, sc
) == -1) {
993 cfga_err(sc
, errstring
, CMD_CONNECT
, 0);
997 sysc_cmd_init(sc
, outputstr
, force
);
999 if (os
== SYSC_CFGA_OSTATE_UNCONFIGURED
) {
1000 if (ioctl(fd
, SYSC_CFGA_CMD_CONFIGURE
, sc
) == -1)
1001 cfga_err(sc
, errstring
, CMD_CONFIGURE
, 0);
1002 else if (options
&& (opterr
= dlist_update(idx
,
1003 disable
, dlist
, msgp
, verbose
))) {
1004 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
1005 cfga_err(NULL
, errstring
, err
, opterr
, 0);
1009 cfga_err(NULL
, errstring
, ERR_TRANS
, 0);
1012 case CFGA_CMD_UNCONFIGURE
:
1013 if (os
!= SYSC_CFGA_OSTATE_CONFIGURED
)
1014 cfga_err(NULL
, errstring
, ERR_TRANS
, 0);
1015 else if (ioctl(fd
, SYSC_CFGA_CMD_UNCONFIGURE
, sc
) == -1)
1016 cfga_err(sc
, errstring
, CMD_UNCONFIGURE
, 0);
1017 else if (options
&& (opterr
= dlist_update(idx
, disable
,
1018 dlist
, msgp
, verbose
))) {
1019 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
1020 cfga_err(NULL
, errstring
, err
, opterr
, 0);
1026 rc
= CFGA_OPNOTSUPP
;
1035 str2cond(const char *cond
)
1039 if (strcmp(cond
, cfga_str(COND_UNKNOWN
)) == 0)
1040 c
= SYSC_CFGA_COND_UNKNOWN
;
1041 else if (strcmp(cond
, cfga_str(COND_OK
)) == 0)
1042 c
= SYSC_CFGA_COND_OK
;
1043 else if (strcmp(cond
, cfga_str(COND_FAILING
)) == 0)
1044 c
= SYSC_CFGA_COND_FAILING
;
1045 else if (strcmp(cond
, cfga_str(COND_FAILED
)) == 0)
1046 c
= SYSC_CFGA_COND_FAILED
;
1047 else if (strcmp(cond
, cfga_str(COND_UNUSABLE
)) == 0)
1048 c
= SYSC_CFGA_COND_UNUSABLE
;
1058 const char *function
,
1060 const char *options
,
1061 struct cfga_confirm
*confp
,
1062 struct cfga_msg
*msgp
,
1079 char outputstr
[SYSC_OUTPUT_LEN
];
1080 sysc_cfga_cmd_t
*sc
, sysc_cmd
;
1082 if (errstring
!= NULL
)
1085 verbose
= flags
& CFGA_FLAG_VERBOSE
;
1091 if (strcmp(options
, cfga_str(OPT_DISABLE
)) == 0)
1093 else if (strcmp(options
, cfga_str(OPT_ENABLE
))) {
1094 cfga_err(NULL
, errstring
, ERR_OPT_INVAL
, options
, 0);
1100 str
= cfga_str(CMD_SET_COND
);
1103 if ((strncmp(function
, str
, len
) == 0) && (function
[len
++] == '=') &&
1104 ((cond
= (str2cond(&function
[len
]))) != -1)) {
1105 cmd
= SYSC_CFGA_CMD_TEST_SET_COND
;
1108 } else if (strcmp(function
, cfga_str(CMD_QUIESCE
)) == 0) {
1109 cmd
= SYSC_CFGA_CMD_QUIESCE_TEST
;
1111 } else if (strcmp(function
, cfga_str(CMD_INSERT
)) == 0) {
1112 cmd
= SYSC_CFGA_CMD_TEST
;
1114 } else if (strcmp(function
, cfga_str(CMD_REMOVE
)) == 0) {
1115 cmd
= SYSC_CFGA_CMD_TEST
;
1118 cfga_err(NULL
, errstring
, ERR_CMD_INVAL
, (char *)function
, 0);
1122 sysc_cmd_init(sc
, outputstr
, 0);
1124 if ((idx
= ap_idx(ap_id
)) == -1)
1125 cfga_err(NULL
, errstring
, ERR_AP_INVAL
, ap_id
, 0);
1126 else if (((fd
= open(ap_id
, O_RDWR
, 0)) == -1) ||
1127 (ioctl(fd
, cmd
, sc
) == -1))
1128 cfga_err(NULL
, errstring
, err
, 0);
1133 opterr
= (dlist_find(idx
, &dlist
, &disabled
) ||
1134 dlist_update(idx
, disable
, dlist
, msgp
, verbose
));
1136 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
1138 cfga_msg(msgp
, err
, opterr
, 0);
1151 const char *options
,
1152 struct cfga_msg
*msgp
,
1156 if (errstring
!= NULL
)
1159 return (CFGA_OPNOTSUPP
);
1163 rstate_cvt(sysc_cfga_rstate_t rs
)
1168 case SYSC_CFGA_RSTATE_EMPTY
:
1169 cs
= CFGA_STAT_EMPTY
;
1171 case SYSC_CFGA_RSTATE_DISCONNECTED
:
1172 cs
= CFGA_STAT_DISCONNECTED
;
1174 case SYSC_CFGA_RSTATE_CONNECTED
:
1175 cs
= CFGA_STAT_CONNECTED
;
1178 cs
= CFGA_STAT_NONE
;
1186 ostate_cvt(sysc_cfga_ostate_t os
)
1191 case SYSC_CFGA_OSTATE_UNCONFIGURED
:
1192 cs
= CFGA_STAT_UNCONFIGURED
;
1194 case SYSC_CFGA_OSTATE_CONFIGURED
:
1195 cs
= CFGA_STAT_CONFIGURED
;
1198 cs
= CFGA_STAT_NONE
;
1206 cond_cvt(sysc_cfga_cond_t sc
)
1211 case SYSC_CFGA_COND_OK
:
1214 case SYSC_CFGA_COND_FAILING
:
1215 cc
= CFGA_COND_FAILING
;
1217 case SYSC_CFGA_COND_FAILED
:
1218 cc
= CFGA_COND_FAILED
;
1220 case SYSC_CFGA_COND_UNUSABLE
:
1221 cc
= CFGA_COND_UNUSABLE
;
1223 case SYSC_CFGA_COND_UNKNOWN
:
1225 cc
= CFGA_COND_UNKNOWN
;
1233 type_str(enum board_type type
)
1239 type_str
= cfga_str(BD_MEM
);
1242 type_str
= cfga_str(BD_CPU
);
1244 case IO_2SBUS_BOARD
:
1245 type_str
= cfga_str(BD_IO_2SBUS
);
1247 case IO_SBUS_FFB_BOARD
:
1248 type_str
= cfga_str(BD_IO_SBUS_FFB
);
1251 type_str
= cfga_str(BD_IO_PCI
);
1254 type_str
= cfga_str(BD_DISK
);
1256 case IO_2SBUS_SOCPLUS_BOARD
:
1257 type_str
= cfga_str(BD_IO_2SBUS_SOCPLUS
);
1259 case IO_SBUS_FFB_SOCPLUS_BOARD
:
1260 type_str
= cfga_str(BD_IO_SBUS_FFB_SOCPLUS
);
1264 type_str
= cfga_str(BD_UNKNOWN
);
1271 info_set(sysc_cfga_stat_t
*sc
, cfga_info_t info
, int disabled
)
1274 struct cpu_info
*cpu
;
1275 union bd_un
*bd
= &sc
->bd
;
1281 for (i
= 0, cpu
= bd
->cpu
; i
< 2; i
++, cpu
++) {
1282 if (cpu
->cpu_speed
> 1) {
1283 info
+= sprintf(info
, "cpu %d: ", i
);
1284 info
+= sprintf(info
, "%3d MHz ",
1286 if (cpu
->cache_size
)
1287 info
+= sprintf(info
, "%0.1fM ",
1288 (float)cpu
->cache_size
/
1289 (float)(1024 * 1024));
1293 case IO_SBUS_FFB_BOARD
:
1294 switch (bd
->io2
.ffb_size
) {
1296 info
+= sprintf(info
, "single buffered ffb ");
1299 info
+= sprintf(info
, "double buffered ffb ");
1302 #ifdef FFB_DR_SUPPORT
1303 info
+= sprintf(info
, "no ffb installed ");
1307 info
+= sprintf(info
, "illegal ffb size ");
1312 for (i
= 0; i
< 2; i
++)
1313 if (bd
->dsk
.disk_pres
[i
])
1314 info
+= sprintf(info
, "target: %2d ",
1315 bd
->dsk
.disk_id
[i
]);
1317 info
+= sprintf(info
, "no disk ");
1322 info
+= sprintf(info
, "disabled at boot ");
1325 info
+= sprintf(info
, "non-detachable ");
1328 info
+= sprintf(info
, "100 MHz capable ");
1332 sysc_cvt(sysc_cfga_stat_t
*sc
, cfga_stat_data_t
*cs
, int disabled
)
1334 (void) strcpy(cs
->ap_type
, type_str(sc
->type
));
1335 cs
->ap_r_state
= rstate_cvt(sc
->rstate
);
1336 cs
->ap_o_state
= ostate_cvt(sc
->ostate
);
1337 cs
->ap_cond
= cond_cvt(sc
->condition
);
1338 cs
->ap_busy
= (cfga_busy_t
)sc
->in_transition
;
1339 cs
->ap_status_time
= sc
->last_change
;
1340 info_set(sc
, cs
->ap_info
, disabled
);
1341 cs
->ap_log_id
[0] = NULL
;
1342 cs
->ap_phys_id
[0] = NULL
;
1349 cfga_stat_data_t
**ap_list
,
1351 const char *options
,
1356 sysc_cfga_stat_t
*sc
;
1357 cfga_stat_data_t
*cs
;
1359 if (errstring
!= NULL
)
1364 if (ap_idx(ap_id
) == -1)
1365 cfga_err(NULL
, errstring
, ERR_AP_INVAL
, ap_id
, 0);
1366 else if ((sc
= sysc_stat(ap_id
, NULL
)) == NULL
)
1367 cfga_err(NULL
, errstring
, CMD_LIST
, 0);
1368 else if (!(cs
= (cfga_stat_data_t
*)malloc(MAX_BOARDS
* sizeof (*cs
))))
1369 cfga_err(NULL
, errstring
, CMD_LIST
, 0);
1373 for (*nlist
= 0, i
= 0; i
< MAX_BOARDS
; i
++, sc
++) {
1374 if (sc
->board
== -1)
1376 sysc_cvt(sc
, cs
++, 0); /* XXX - disable */
1390 struct cfga_stat_data
*cs
,
1391 const char *options
,
1401 sysc_cfga_stat_t
*sc
;
1403 if (errstring
!= NULL
)
1408 if (options
&& options
[0]) {
1410 if (strcmp(options
, cfga_str(OPT_DISABLE
)) == 0)
1412 else if (strcmp(options
, cfga_str(OPT_ENABLE
))) {
1413 cfga_err(NULL
, errstring
, ERR_OPT_INVAL
, options
, 0);
1418 if ((idx
= ap_idx(ap_id
)) == -1)
1419 cfga_err(NULL
, errstring
, ERR_AP_INVAL
, ap_id
, 0);
1420 else if ((sc
= sysc_stat(ap_id
, NULL
)) == NULL
)
1421 cfga_err(NULL
, errstring
, CMD_GETSTAT
, 0);
1423 opterr
= dlist_find(idx
, &dlist
, &disabled
);
1424 sysc_cvt(sc
+ idx
, cs
, disabled
);
1428 if (options
&& options
[0] && ((opterr
!= 0) ||
1429 ((opterr
= dlist_update(idx
, disable
, dlist
, NULL
, 0))
1431 err
= disable
? OPT_DISABLE
: OPT_ENABLE
;
1432 cfga_err(NULL
, errstring
, err
, opterr
, 0);
1441 cfga_help(struct cfga_msg
*msgp
, const char *options
, cfga_flags_t flags
)
1446 if (strcmp(options
, cfga_str(OPT_DISABLE
)) == 0)
1447 help
= HELP_DISABLE
;
1448 else if (strcmp(options
, cfga_str(OPT_ENABLE
)) == 0)
1450 else if (strcmp(options
, cfga_str(CMD_INSERT
)) == 0)
1452 else if (strcmp(options
, cfga_str(CMD_REMOVE
)) == 0)
1454 else if (strcmp(options
, cfga_str(CMD_QUIESCE
)) == 0)
1455 help
= HELP_QUIESCE
;
1457 help
= HELP_UNKNOWN
;
1461 if (help
== HELP_UNKNOWN
)
1462 cfga_msg(msgp
, help
, options
, 0);
1464 cfga_msg(msgp
, help
, 0);
1466 cfga_msg(msgp
, HELP_HEADER
, 0);
1467 cfga_msg(msgp
, HELP_DISABLE
, 0);
1468 cfga_msg(msgp
, HELP_ENABLE
, 0);
1469 cfga_msg(msgp
, HELP_INSERT
, 0);
1470 cfga_msg(msgp
, HELP_REMOVE
, 0);
1471 cfga_msg(msgp
, HELP_QUIESCE
, 0);
1472 cfga_msg(msgp
, HELP_SET_COND
, 0);
1479 * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm