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.
28 #include <sys/param.h>
31 #include <pcidr_cfga.h>
35 * misc config_admin(3cfgadm) related routines
41 } pcidr_cfga_stat_nametab
[] = {
42 {CFGA_STAT_NONE
, "CFGA_STAT_NONE"},
43 {CFGA_STAT_EMPTY
, "CFGA_STAT_EMPTY"},
44 {CFGA_STAT_DISCONNECTED
, "CFGA_STAT_DISCONNECTED"},
45 {CFGA_STAT_CONNECTED
, "CFGA_STAT_CONNECTED"},
46 {CFGA_STAT_UNCONFIGURED
, "CFGA_STAT_UNCONFIGURED"},
47 {CFGA_STAT_CONFIGURED
, "CFGA_STAT_CONFIGURED"},
49 static int pcidr_cfga_stat_nametab_len
=
50 sizeof (pcidr_cfga_stat_nametab
) / sizeof (pcidr_cfga_stat_nametab
[0]);
53 pcidr_cfga_stat_name(cfga_stat_t val
)
57 for (i
= 0; i
< pcidr_cfga_stat_nametab_len
; i
++) {
58 if (pcidr_cfga_stat_nametab
[i
].stat
== val
)
59 return (pcidr_cfga_stat_nametab
[i
].name
);
68 } pcidr_cfga_cmd_nametab
[] = {
69 {CFGA_CMD_NONE
, "CFGA_CMD_NONE"},
70 {CFGA_CMD_LOAD
, "CFGA_CMD_LOAD"},
71 {CFGA_CMD_UNLOAD
, "CFGA_CMD_UNLOAD"},
72 {CFGA_CMD_CONNECT
, "CFGA_CMD_CONNECT"},
73 {CFGA_CMD_DISCONNECT
, "CFGA_CMD_DISCONNECT"},
74 {CFGA_CMD_CONFIGURE
, "CFGA_CMD_CONFIGURE"},
75 {CFGA_CMD_UNCONFIGURE
, "CFGA_CMD_UNCONFIGURE"},
77 static int pcidr_cfga_cmd_nametab_len
=
78 sizeof (pcidr_cfga_cmd_nametab
) / sizeof (pcidr_cfga_cmd_nametab
[0]);
81 pcidr_cfga_cmd_name(cfga_cmd_t val
)
85 for (i
= 0; i
< pcidr_cfga_cmd_nametab_len
; i
++) {
86 if (pcidr_cfga_cmd_nametab
[i
].cmd
== val
)
87 return (pcidr_cfga_cmd_nametab
[i
].name
);
96 } pcidr_cfga_cond_nametab
[] = {
97 {CFGA_COND_UNKNOWN
, "CFGA_COND_UNKNOWN"},
98 {CFGA_COND_OK
, "CFGA_COND_OK"},
99 {CFGA_COND_FAILING
, "CFGA_COND_FAILING"},
100 {CFGA_COND_FAILED
, "CFGA_COND_FAILED"},
101 {CFGA_COND_UNUSABLE
, "CFGA_COND_UNUSABLE"},
103 static int pcidr_cfga_cond_nametab_len
=
104 sizeof (pcidr_cfga_cond_nametab
) / sizeof (pcidr_cfga_cond_nametab
[0]);
107 pcidr_cfga_cond_name(cfga_cond_t val
)
111 for (i
= 0; i
< pcidr_cfga_cond_nametab_len
; i
++) {
112 if (pcidr_cfga_cond_nametab
[i
].cond
== val
)
113 return (pcidr_cfga_cond_nametab
[i
].name
);
122 } pcidr_cfga_err_nametab
[] = {
123 {CFGA_OK
, "CFGA_OK"},
124 {CFGA_NACK
, "CFGA_NACK"},
125 {CFGA_NOTSUPP
, "CFGA_NOTSUPP"},
126 {CFGA_OPNOTSUPP
, "CFGA_OPNOTSUPP"},
127 {CFGA_PRIV
, "CFGA_PRIV"},
128 {CFGA_BUSY
, "CFGA_BUSY"},
129 {CFGA_SYSTEM_BUSY
, "CFGA_SYSTEM_BUSY"},
130 {CFGA_DATA_ERROR
, "CFGA_DATA_ERROR"},
131 {CFGA_LIB_ERROR
, "CFGA_LIB_ERROR"},
132 {CFGA_NO_LIB
, "CFGA_NO_LIB"},
133 {CFGA_INSUFFICENT_CONDITION
, "CFGA_INSUFFICENT_CONDITION"},
134 {CFGA_INVAL
, "CFGA_INVAL"},
135 {CFGA_ERROR
, "CFGA_ERROR"},
136 {CFGA_APID_NOEXIST
, "CFGA_APID_NOEXIST"},
137 {CFGA_ATTR_INVAL
, "CFGA_ATTR_INVAL"},
139 static int pcidr_cfga_err_nametab_len
=
140 sizeof (pcidr_cfga_err_nametab
) / sizeof (pcidr_cfga_err_nametab
[0]);
143 pcidr_cfga_err_name(cfga_err_t val
)
147 for (i
= 0; i
< pcidr_cfga_err_nametab_len
; i
++) {
148 if (pcidr_cfga_err_nametab
[i
].err
== val
)
149 return (pcidr_cfga_err_nametab
[i
].name
);
156 pcidr_print_cfga(dlvl_t lvl
, cfga_list_data_t
*datap
, char *prestr
)
163 dprint(lvl
, "%slogical APID = %s\n", prestr
, datap
->ap_log_id
);
164 dprint(lvl
, "%sphyiscal APID = %s\n", prestr
, datap
->ap_phys_id
);
165 dprint(lvl
, "%sAP class = %s\n", prestr
, datap
->ap_class
);
167 str
= pcidr_cfga_stat_name(datap
->ap_r_state
);
169 str
= "(unrecognized cfga_stat_t value!)";
170 dprint(lvl
, "%sAP receptacle state = %s\n", prestr
, str
);
172 str
= pcidr_cfga_stat_name(datap
->ap_o_state
);
174 str
= "(unrecognized cfga_stat_t value!)";
175 dprint(lvl
, "%sAP occupant state = %s\n", prestr
, str
);
177 str
= pcidr_cfga_cond_name(datap
->ap_cond
);
179 str
= "(unrecognized cfga_cond_t value!)";
180 dprint(lvl
, "%sAP condition = %s\n", prestr
, str
);
182 dprint(lvl
, "%sAP busy indicator = %d\n", prestr
, datap
->ap_busy
);
184 str
= ctime(&datap
->ap_status_time
);
185 str
[strlen(str
) - 1] = '\0'; /* get rid of newline */
186 dprint(lvl
, "%sAP last change time = %ld (%s)\n", prestr
,
187 datap
->ap_status_time
, str
);
189 dprint(lvl
, "%sAP info = %s\n", prestr
, datap
->ap_info
);
190 dprint(lvl
, "%sAP type = %s\n", prestr
, datap
->ap_type
);
195 * for use with config_admin(3cfgadm) functions in their
196 * <struct cfga_msg *msgp> parameter
199 pcidr_cfga_msg_func(void *datap
, const char *msg
)
201 pcidr_cfga_msg_data_t
*dp
= (pcidr_cfga_msg_data_t
*)datap
;
202 char *prestr
= dp
->prestr
;
207 dprint(dp
->dlvl
, "%s%s", prestr
, msg
);
213 * for use with config_admin(3cfgadm) functions in their
214 * <struct cfga_confirm *confp> parameter
218 pcidr_cfga_confirm_func(void *datap
, const char *msg
)
225 * returns 0 if successful, -1 if unusuccesful, 1 if the AP already had
226 * <cmd> performed on it
229 pcidr_cfga_do_cmd(cfga_cmd_t cmd
, cfga_list_data_t
*cfga_listp
)
231 char *fn
= "pcidr_cfga_do_cmd";
233 char *cmdnm
, *cfga_errstr
, *apid
, *str
;
235 int cmdarr_len
= sizeof (cmdarr
) / sizeof (cmdarr
[0]);
237 struct cfga_msg cfga_msg
;
238 pcidr_cfga_msg_data_t cfga_msg_data
;
239 struct cfga_confirm cfga_confirm
;
240 cfga_flags_t cfga_flags
;
242 cmdnm
= pcidr_cfga_cmd_name(cmd
);
243 assert(cmdnm
!= NULL
);
245 apid
= cfga_listp
->ap_phys_id
;
246 cfga_msg_data
.dlvl
= DDEBUG
;
247 cfga_msg_data
.prestr
= "pcidr_cfga_do_cmd(msg): ";
248 cfga_msg
.message_routine
= pcidr_cfga_msg_func
;
249 cfga_msg
.appdata_ptr
= (void *)&cfga_msg_data
;
250 cfga_confirm
.confirm
= pcidr_cfga_confirm_func
;
251 cfga_confirm
.appdata_ptr
= NULL
;
252 cfga_flags
= CFGA_FLAG_VERBOSE
;
254 if (cfga_listp
->ap_busy
!= 0) {
255 dprint(DDEBUG
, "%s: apid = %s is busy\n",
256 fn
, cfga_listp
->ap_phys_id
);
261 * explicitly perform each step that would otherwise be done
262 * implicitly by cfgadm to isolate errors
266 case CFGA_CMD_CONFIGURE
:
267 if (cfga_listp
->ap_o_state
< CFGA_STAT_CONNECTED
) {
268 cmdarr
[j
] = CFGA_CMD_CONNECT
;
271 if (cfga_listp
->ap_o_state
< CFGA_STAT_CONFIGURED
) {
272 cmdarr
[j
] = CFGA_CMD_CONFIGURE
;
275 if (cfga_listp
->ap_o_state
>= CFGA_STAT_CONFIGURED
)
278 case CFGA_CMD_DISCONNECT
:
279 if (cfga_listp
->ap_o_state
>= CFGA_STAT_CONFIGURED
) {
280 cmdarr
[j
] = CFGA_CMD_UNCONFIGURE
;
283 if (cfga_listp
->ap_o_state
>= CFGA_STAT_CONNECTED
) {
284 cmdarr
[j
] = CFGA_CMD_DISCONNECT
;
287 if (cfga_listp
->ap_r_state
<= CFGA_STAT_DISCONNECTED
)
291 dprint(DDEBUG
, "%s: unsupported cmd %d\n", cmd
);
294 assert(j
<= cmdarr_len
);
296 for (i
= 0; i
< j
; i
++) {
298 cmdnm
= pcidr_cfga_cmd_name(cmd
);
299 assert(cmdnm
!= NULL
);
301 rv
= config_change_state(cmd
, 1, &apid
, NULL
, &cfga_confirm
,
302 &cfga_msg
, &cfga_errstr
, cfga_flags
);
304 dprint(DDEBUG
, "%s: command %s failed on apid %s",
307 str
= pcidr_cfga_err_name(rv
);
309 str
= "unrecognized rv!";
310 dprint(DDEBUG
, ": rv = %d (%s)", rv
, str
);
312 if (cfga_errstr
!= NULL
) {
313 dprint(DDEBUG
, ", error string = "
314 "\"%s\"", cfga_errstr
);
317 dprint(DDEBUG
, "\n");
325 dprint(DDEBUG
, "%s: command %s already done on apid %s\n",