1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <ctype.h>
30*7c478bd9Sstevel@tonic-gate #include <stdio.h>
31*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
32*7c478bd9Sstevel@tonic-gate #include <string.h>
33*7c478bd9Sstevel@tonic-gate #include <unistd.h>
34*7c478bd9Sstevel@tonic-gate #include <macros.h>
35*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
36*7c478bd9Sstevel@tonic-gate #define	CFGA_PLUGIN_LIB
37*7c478bd9Sstevel@tonic-gate #include <config_admin.h>
38*7c478bd9Sstevel@tonic-gate #include "ap.h"
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate int cfga_version = CFGA_HSL_V2;
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
43*7c478bd9Sstevel@tonic-gate cfga_err_t
44*7c478bd9Sstevel@tonic-gate cfga_change_state(
45*7c478bd9Sstevel@tonic-gate 	cfga_cmd_t cfga_cmd,
46*7c478bd9Sstevel@tonic-gate 	const char *ap_id,
47*7c478bd9Sstevel@tonic-gate 	const char *options,
48*7c478bd9Sstevel@tonic-gate 	struct cfga_confirm *confp,
49*7c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
50*7c478bd9Sstevel@tonic-gate 	char **errstring,
51*7c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
52*7c478bd9Sstevel@tonic-gate {
53*7c478bd9Sstevel@tonic-gate 	int cmd;
54*7c478bd9Sstevel@tonic-gate 	const char *name;
55*7c478bd9Sstevel@tonic-gate 	apd_t *a;
56*7c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate 	if ((rc = ap_state_cmd(cfga_cmd, &cmd)) != CFGA_OK)
59*7c478bd9Sstevel@tonic-gate 		return (rc);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
64*7c478bd9Sstevel@tonic-gate 		return (rc);
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	name = ap_cmd_name(cmd);
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate 	if ((rc = ap_cmd_parse(a, name, options, NULL)) == CFGA_OK)
69*7c478bd9Sstevel@tonic-gate 		rc = ap_cmd_seq(a, cmd);
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 	apd_free(a);
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	return (rc);
74*7c478bd9Sstevel@tonic-gate }
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate /*
77*7c478bd9Sstevel@tonic-gate  * Check if this is a valid -x command.
78*7c478bd9Sstevel@tonic-gate  */
79*7c478bd9Sstevel@tonic-gate static int
80*7c478bd9Sstevel@tonic-gate private_func(const char *function)
81*7c478bd9Sstevel@tonic-gate {
82*7c478bd9Sstevel@tonic-gate 	char **f;
83*7c478bd9Sstevel@tonic-gate 	static char *
84*7c478bd9Sstevel@tonic-gate 	private_funcs[] = {
85*7c478bd9Sstevel@tonic-gate 		"assign",
86*7c478bd9Sstevel@tonic-gate 		"unassign",
87*7c478bd9Sstevel@tonic-gate 		"poweron",
88*7c478bd9Sstevel@tonic-gate 		"poweroff",
89*7c478bd9Sstevel@tonic-gate 		"passthru",
90*7c478bd9Sstevel@tonic-gate 		"errtest",
91*7c478bd9Sstevel@tonic-gate 		NULL
92*7c478bd9Sstevel@tonic-gate 	};
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	for (f = private_funcs; *f != NULL; f++)
95*7c478bd9Sstevel@tonic-gate 		if (strcmp(*f, function) == 0)
96*7c478bd9Sstevel@tonic-gate 			break;
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 	return (*f == NULL ? CFGA_INVAL : CFGA_OK);
99*7c478bd9Sstevel@tonic-gate }
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
102*7c478bd9Sstevel@tonic-gate cfga_err_t
103*7c478bd9Sstevel@tonic-gate cfga_private_func(
104*7c478bd9Sstevel@tonic-gate 	const char *function,
105*7c478bd9Sstevel@tonic-gate 	const char *ap_id,
106*7c478bd9Sstevel@tonic-gate 	const char *options,
107*7c478bd9Sstevel@tonic-gate 	struct cfga_confirm *confp,
108*7c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
109*7c478bd9Sstevel@tonic-gate 	char **errstring,
110*7c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
111*7c478bd9Sstevel@tonic-gate {
112*7c478bd9Sstevel@tonic-gate 	int cmd;
113*7c478bd9Sstevel@tonic-gate 	apd_t *a;
114*7c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	DBG("cfga_private_func(%s)\n", ap_id);
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
121*7c478bd9Sstevel@tonic-gate 		return (rc);
122*7c478bd9Sstevel@tonic-gate 	else if ((rc = private_func(function)) != CFGA_OK)  {
123*7c478bd9Sstevel@tonic-gate 		ap_err(a, ERR_CMD_INVAL, function);
124*7c478bd9Sstevel@tonic-gate 		goto done;
125*7c478bd9Sstevel@tonic-gate 	} else if ((rc = ap_cmd_parse(a, function, options, &cmd)) != CFGA_OK)
126*7c478bd9Sstevel@tonic-gate 		goto done;
127*7c478bd9Sstevel@tonic-gate 	else if (cmd == CMD_ERRTEST)
128*7c478bd9Sstevel@tonic-gate 		rc = ap_test_err(a, options);
129*7c478bd9Sstevel@tonic-gate 	else
130*7c478bd9Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
131*7c478bd9Sstevel@tonic-gate done:
132*7c478bd9Sstevel@tonic-gate 	apd_free(a);
133*7c478bd9Sstevel@tonic-gate 	return (rc);
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
138*7c478bd9Sstevel@tonic-gate cfga_err_t
139*7c478bd9Sstevel@tonic-gate cfga_test(
140*7c478bd9Sstevel@tonic-gate 	const char *ap_id,
141*7c478bd9Sstevel@tonic-gate 	const char *options,
142*7c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
143*7c478bd9Sstevel@tonic-gate 	char **errstring,
144*7c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
145*7c478bd9Sstevel@tonic-gate {
146*7c478bd9Sstevel@tonic-gate 	int cmd;
147*7c478bd9Sstevel@tonic-gate 	const char *f;
148*7c478bd9Sstevel@tonic-gate 	apd_t *a;
149*7c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate 	DBG("cfga_test(%s)\n", ap_id);
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 	f = "test";
154*7c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	/*
157*7c478bd9Sstevel@tonic-gate 	 * A test that is not sequenced by a change
158*7c478bd9Sstevel@tonic-gate 	 * state operation should be forced.
159*7c478bd9Sstevel@tonic-gate 	 */
160*7c478bd9Sstevel@tonic-gate 	flags |= CFGA_FLAG_FORCE;
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, NULL)) == NULL)
163*7c478bd9Sstevel@tonic-gate 		return (rc);
164*7c478bd9Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, &cmd)) != CFGA_OK)
165*7c478bd9Sstevel@tonic-gate 		goto done;
166*7c478bd9Sstevel@tonic-gate 	else
167*7c478bd9Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
168*7c478bd9Sstevel@tonic-gate done:
169*7c478bd9Sstevel@tonic-gate 	apd_free(a);
170*7c478bd9Sstevel@tonic-gate 	return (rc);
171*7c478bd9Sstevel@tonic-gate }
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
174*7c478bd9Sstevel@tonic-gate cfga_err_t
175*7c478bd9Sstevel@tonic-gate cfga_list_ext(
176*7c478bd9Sstevel@tonic-gate 	const char *ap_id,
177*7c478bd9Sstevel@tonic-gate 	cfga_list_data_t **ap_id_list,
178*7c478bd9Sstevel@tonic-gate 	int *nlist,
179*7c478bd9Sstevel@tonic-gate 	const char *options,
180*7c478bd9Sstevel@tonic-gate 	const char *listopts,
181*7c478bd9Sstevel@tonic-gate 	char **errstring,
182*7c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
183*7c478bd9Sstevel@tonic-gate {
184*7c478bd9Sstevel@tonic-gate 	int i;
185*7c478bd9Sstevel@tonic-gate 	int apcnt;
186*7c478bd9Sstevel@tonic-gate 	const char *f;
187*7c478bd9Sstevel@tonic-gate 	apd_t *a;
188*7c478bd9Sstevel@tonic-gate 	size_t szl, szp;
189*7c478bd9Sstevel@tonic-gate 	cfga_list_data_t *aplist, *ap;
190*7c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate 	aplist = NULL;
195*7c478bd9Sstevel@tonic-gate 	f = ap_cmd_name(CMD_STATUS);
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	DBG("cfga_list_ext(%s %x)\n", ap_id, flags);
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, NULL, NULL)) == NULL)
200*7c478bd9Sstevel@tonic-gate 		return (rc);
201*7c478bd9Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, NULL)) != CFGA_OK)
202*7c478bd9Sstevel@tonic-gate 		goto done;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	apcnt = ap_cnt(a);
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 	DBG("apcnt=%d\n", apcnt);
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	if ((aplist = calloc(apcnt, sizeof (*aplist))) == NULL) {
209*7c478bd9Sstevel@tonic-gate 		rc = CFGA_LIB_ERROR;
210*7c478bd9Sstevel@tonic-gate 		ap_err(a, ERR_CMD_FAIL, CMD_STATUS);
211*7c478bd9Sstevel@tonic-gate 		goto done;
212*7c478bd9Sstevel@tonic-gate 	}
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	ap = aplist;
215*7c478bd9Sstevel@tonic-gate 	szl = sizeof (ap->ap_log_id);
216*7c478bd9Sstevel@tonic-gate 	szp = sizeof (ap->ap_phys_id);
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 	/*
219*7c478bd9Sstevel@tonic-gate 	 * Initialize the AP specified directly by the caller.
220*7c478bd9Sstevel@tonic-gate 	 * The target ID for the 0th element already includes
221*7c478bd9Sstevel@tonic-gate 	 * the (potential) dynamic portion. The dynamic portion
222*7c478bd9Sstevel@tonic-gate 	 * does need to be appended to the path to form the
223*7c478bd9Sstevel@tonic-gate 	 * physical apid for components.
224*7c478bd9Sstevel@tonic-gate 	 */
225*7c478bd9Sstevel@tonic-gate 	(void) strncpy(ap->ap_log_id, a->target, szl - 1);
226*7c478bd9Sstevel@tonic-gate 	(void) snprintf(ap->ap_phys_id, szp, "%s%s%s", a->path,
227*7c478bd9Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? "::" : "",
228*7c478bd9Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? a->cid : "");
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate 	DBG("ap_phys_id=%s ap_log_id=%s\n", ap->ap_phys_id, ap->ap_log_id);
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	if (a->tgt == AP_BOARD) {
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 		ap_init(a, ap++);
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 		/*
238*7c478bd9Sstevel@tonic-gate 		 * Initialize the components, if any.
239*7c478bd9Sstevel@tonic-gate 		 */
240*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < apcnt - 1; i++, ap++) {
241*7c478bd9Sstevel@tonic-gate 			char dyn[MAXPATHLEN];
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 			ap_cm_id(a, i, dyn, sizeof (dyn));
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 			(void) snprintf(ap->ap_log_id, szl, "%s::%s",
246*7c478bd9Sstevel@tonic-gate 				a->target, dyn);
247*7c478bd9Sstevel@tonic-gate 			(void) snprintf(ap->ap_phys_id, szp, "%s::%s",
248*7c478bd9Sstevel@tonic-gate 				a->path, dyn);
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 			ap_cm_init(a, ap, i);
251*7c478bd9Sstevel@tonic-gate 
252*7c478bd9Sstevel@tonic-gate 			DBG("ap_phys_id=%s ap_log_id=%s\n",
253*7c478bd9Sstevel@tonic-gate 				ap->ap_phys_id, ap->ap_log_id);
254*7c478bd9Sstevel@tonic-gate 		}
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	} else
257*7c478bd9Sstevel@tonic-gate 		ap_cm_init(a, ap, 0);
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate 	apd_free(a);
260*7c478bd9Sstevel@tonic-gate 	*ap_id_list = aplist;
261*7c478bd9Sstevel@tonic-gate 	*nlist = apcnt;
262*7c478bd9Sstevel@tonic-gate 	return (CFGA_OK);
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate done:
265*7c478bd9Sstevel@tonic-gate 	s_free(aplist);
266*7c478bd9Sstevel@tonic-gate 	apd_free(a);
267*7c478bd9Sstevel@tonic-gate 	return (rc);
268*7c478bd9Sstevel@tonic-gate }
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
271*7c478bd9Sstevel@tonic-gate cfga_err_t
272*7c478bd9Sstevel@tonic-gate cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
273*7c478bd9Sstevel@tonic-gate {
274*7c478bd9Sstevel@tonic-gate 	return (ap_help(msgp, options, flags));
275*7c478bd9Sstevel@tonic-gate }
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate /*
279*7c478bd9Sstevel@tonic-gate  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
280*7c478bd9Sstevel@tonic-gate  */
281