17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*a3114836SGerry Liu  * Common Development and Distribution License (the "License").
6*a3114836SGerry Liu  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <ctype.h>
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <stdlib.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <macros.h>
327c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
337c478bd9Sstevel@tonic-gate #define	CFGA_PLUGIN_LIB
347c478bd9Sstevel@tonic-gate #include <config_admin.h>
357c478bd9Sstevel@tonic-gate #include "ap.h"
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate int cfga_version = CFGA_HSL_V2;
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*ARGSUSED*/
407c478bd9Sstevel@tonic-gate cfga_err_t
cfga_change_state(cfga_cmd_t cfga_cmd,const char * ap_id,const char * options,struct cfga_confirm * confp,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)417c478bd9Sstevel@tonic-gate cfga_change_state(
427c478bd9Sstevel@tonic-gate 	cfga_cmd_t cfga_cmd,
437c478bd9Sstevel@tonic-gate 	const char *ap_id,
447c478bd9Sstevel@tonic-gate 	const char *options,
457c478bd9Sstevel@tonic-gate 	struct cfga_confirm *confp,
467c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
477c478bd9Sstevel@tonic-gate 	char **errstring,
487c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
497c478bd9Sstevel@tonic-gate {
507c478bd9Sstevel@tonic-gate 	int cmd;
517c478bd9Sstevel@tonic-gate 	const char *name;
527c478bd9Sstevel@tonic-gate 	apd_t *a;
537c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate 	if ((rc = ap_state_cmd(cfga_cmd, &cmd)) != CFGA_OK)
567c478bd9Sstevel@tonic-gate 		return (rc);
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
617c478bd9Sstevel@tonic-gate 		return (rc);
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate 	name = ap_cmd_name(cmd);
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	if ((rc = ap_cmd_parse(a, name, options, NULL)) == CFGA_OK)
667c478bd9Sstevel@tonic-gate 		rc = ap_cmd_seq(a, cmd);
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	apd_free(a);
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 	return (rc);
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * Check if this is a valid -x command.
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate static int
private_func(const char * function)777c478bd9Sstevel@tonic-gate private_func(const char *function)
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate 	char **f;
807c478bd9Sstevel@tonic-gate 	static char *
817c478bd9Sstevel@tonic-gate 	private_funcs[] = {
827c478bd9Sstevel@tonic-gate 		"assign",
837c478bd9Sstevel@tonic-gate 		"unassign",
847c478bd9Sstevel@tonic-gate 		"poweron",
857c478bd9Sstevel@tonic-gate 		"poweroff",
867c478bd9Sstevel@tonic-gate 		"passthru",
877c478bd9Sstevel@tonic-gate 		"errtest",
887c478bd9Sstevel@tonic-gate 		NULL
897c478bd9Sstevel@tonic-gate 	};
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	for (f = private_funcs; *f != NULL; f++)
927c478bd9Sstevel@tonic-gate 		if (strcmp(*f, function) == 0)
937c478bd9Sstevel@tonic-gate 			break;
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	return (*f == NULL ? CFGA_INVAL : CFGA_OK);
967c478bd9Sstevel@tonic-gate }
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate /*ARGSUSED*/
997c478bd9Sstevel@tonic-gate 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)1007c478bd9Sstevel@tonic-gate cfga_private_func(
1017c478bd9Sstevel@tonic-gate 	const char *function,
1027c478bd9Sstevel@tonic-gate 	const char *ap_id,
1037c478bd9Sstevel@tonic-gate 	const char *options,
1047c478bd9Sstevel@tonic-gate 	struct cfga_confirm *confp,
1057c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
1067c478bd9Sstevel@tonic-gate 	char **errstring,
1077c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	int cmd;
1107c478bd9Sstevel@tonic-gate 	apd_t *a;
1117c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	DBG("cfga_private_func(%s)\n", ap_id);
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
1187c478bd9Sstevel@tonic-gate 		return (rc);
1197c478bd9Sstevel@tonic-gate 	else if ((rc = private_func(function)) != CFGA_OK)  {
1207c478bd9Sstevel@tonic-gate 		ap_err(a, ERR_CMD_INVAL, function);
1217c478bd9Sstevel@tonic-gate 		goto done;
1227c478bd9Sstevel@tonic-gate 	} else if ((rc = ap_cmd_parse(a, function, options, &cmd)) != CFGA_OK)
1237c478bd9Sstevel@tonic-gate 		goto done;
1247c478bd9Sstevel@tonic-gate 	else if (cmd == CMD_ERRTEST)
1257c478bd9Sstevel@tonic-gate 		rc = ap_test_err(a, options);
1267c478bd9Sstevel@tonic-gate 	else
1277c478bd9Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
1287c478bd9Sstevel@tonic-gate done:
1297c478bd9Sstevel@tonic-gate 	apd_free(a);
1307c478bd9Sstevel@tonic-gate 	return (rc);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1357c478bd9Sstevel@tonic-gate cfga_err_t
cfga_test(const char * ap_id,const char * options,struct cfga_msg * msgp,char ** errstring,cfga_flags_t flags)1367c478bd9Sstevel@tonic-gate cfga_test(
1377c478bd9Sstevel@tonic-gate 	const char *ap_id,
1387c478bd9Sstevel@tonic-gate 	const char *options,
1397c478bd9Sstevel@tonic-gate 	struct cfga_msg *msgp,
1407c478bd9Sstevel@tonic-gate 	char **errstring,
1417c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
1427c478bd9Sstevel@tonic-gate {
1437c478bd9Sstevel@tonic-gate 	int cmd;
1447c478bd9Sstevel@tonic-gate 	const char *f;
1457c478bd9Sstevel@tonic-gate 	apd_t *a;
1467c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	DBG("cfga_test(%s)\n", ap_id);
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	f = "test";
1517c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	/*
1547c478bd9Sstevel@tonic-gate 	 * A test that is not sequenced by a change
1557c478bd9Sstevel@tonic-gate 	 * state operation should be forced.
1567c478bd9Sstevel@tonic-gate 	 */
1577c478bd9Sstevel@tonic-gate 	flags |= CFGA_FLAG_FORCE;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, msgp, NULL)) == NULL)
1607c478bd9Sstevel@tonic-gate 		return (rc);
1617c478bd9Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, &cmd)) != CFGA_OK)
1627c478bd9Sstevel@tonic-gate 		goto done;
1637c478bd9Sstevel@tonic-gate 	else
1647c478bd9Sstevel@tonic-gate 		rc = ap_cmd_exec(a, cmd);
1657c478bd9Sstevel@tonic-gate done:
1667c478bd9Sstevel@tonic-gate 	apd_free(a);
1677c478bd9Sstevel@tonic-gate 	return (rc);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1717c478bd9Sstevel@tonic-gate cfga_err_t
cfga_list_ext(const char * ap_id,cfga_list_data_t ** ap_id_list,int * nlist,const char * options,const char * listopts,char ** errstring,cfga_flags_t flags)1727c478bd9Sstevel@tonic-gate cfga_list_ext(
1737c478bd9Sstevel@tonic-gate 	const char *ap_id,
1747c478bd9Sstevel@tonic-gate 	cfga_list_data_t **ap_id_list,
1757c478bd9Sstevel@tonic-gate 	int *nlist,
1767c478bd9Sstevel@tonic-gate 	const char *options,
1777c478bd9Sstevel@tonic-gate 	const char *listopts,
1787c478bd9Sstevel@tonic-gate 	char **errstring,
1797c478bd9Sstevel@tonic-gate 	cfga_flags_t flags)
1807c478bd9Sstevel@tonic-gate {
1817c478bd9Sstevel@tonic-gate 	int i;
1827c478bd9Sstevel@tonic-gate 	int apcnt;
1837c478bd9Sstevel@tonic-gate 	const char *f;
1847c478bd9Sstevel@tonic-gate 	apd_t *a;
1857c478bd9Sstevel@tonic-gate 	size_t szl, szp;
1867c478bd9Sstevel@tonic-gate 	cfga_list_data_t *aplist, *ap;
1877c478bd9Sstevel@tonic-gate 	cfga_err_t rc;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	rc = CFGA_LIB_ERROR;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	aplist = NULL;
1927c478bd9Sstevel@tonic-gate 	f = ap_cmd_name(CMD_STATUS);
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	DBG("cfga_list_ext(%s %x)\n", ap_id, flags);
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	if ((a = apd_alloc(ap_id, flags, errstring, NULL, NULL)) == NULL)
1977c478bd9Sstevel@tonic-gate 		return (rc);
1987c478bd9Sstevel@tonic-gate 	else if ((rc = ap_cmd_parse(a, f, options, NULL)) != CFGA_OK)
1997c478bd9Sstevel@tonic-gate 		goto done;
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	apcnt = ap_cnt(a);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	DBG("apcnt=%d\n", apcnt);
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	if ((aplist = calloc(apcnt, sizeof (*aplist))) == NULL) {
2067c478bd9Sstevel@tonic-gate 		rc = CFGA_LIB_ERROR;
2077c478bd9Sstevel@tonic-gate 		ap_err(a, ERR_CMD_FAIL, CMD_STATUS);
2087c478bd9Sstevel@tonic-gate 		goto done;
2097c478bd9Sstevel@tonic-gate 	}
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate 	ap = aplist;
2127c478bd9Sstevel@tonic-gate 	szl = sizeof (ap->ap_log_id);
2137c478bd9Sstevel@tonic-gate 	szp = sizeof (ap->ap_phys_id);
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 	/*
2167c478bd9Sstevel@tonic-gate 	 * Initialize the AP specified directly by the caller.
2177c478bd9Sstevel@tonic-gate 	 * The target ID for the 0th element already includes
2187c478bd9Sstevel@tonic-gate 	 * the (potential) dynamic portion. The dynamic portion
2197c478bd9Sstevel@tonic-gate 	 * does need to be appended to the path to form the
2207c478bd9Sstevel@tonic-gate 	 * physical apid for components.
2217c478bd9Sstevel@tonic-gate 	 */
2227c478bd9Sstevel@tonic-gate 	(void) strncpy(ap->ap_log_id, a->target, szl - 1);
2237c478bd9Sstevel@tonic-gate 	(void) snprintf(ap->ap_phys_id, szp, "%s%s%s", a->path,
2247c478bd9Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? "::" : "",
2257c478bd9Sstevel@tonic-gate 	    a->tgt != AP_BOARD ? a->cid : "");
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	DBG("ap_phys_id=%s ap_log_id=%s\n", ap->ap_phys_id, ap->ap_log_id);
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	if (a->tgt == AP_BOARD) {
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 		ap_init(a, ap++);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 		/*
2357c478bd9Sstevel@tonic-gate 		 * Initialize the components, if any.
2367c478bd9Sstevel@tonic-gate 		 */
2377c478bd9Sstevel@tonic-gate 		for (i = 0; i < apcnt - 1; i++, ap++) {
2387c478bd9Sstevel@tonic-gate 			char dyn[MAXPATHLEN];
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 			ap_cm_id(a, i, dyn, sizeof (dyn));
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 			(void) snprintf(ap->ap_log_id, szl, "%s::%s",
243*a3114836SGerry Liu 			    a->target, dyn);
2447c478bd9Sstevel@tonic-gate 			(void) snprintf(ap->ap_phys_id, szp, "%s::%s",
245*a3114836SGerry Liu 			    a->path, dyn);
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 			ap_cm_init(a, ap, i);
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 			DBG("ap_phys_id=%s ap_log_id=%s\n",
250*a3114836SGerry Liu 			    ap->ap_phys_id, ap->ap_log_id);
2517c478bd9Sstevel@tonic-gate 		}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	} else
2547c478bd9Sstevel@tonic-gate 		ap_cm_init(a, ap, 0);
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	apd_free(a);
2577c478bd9Sstevel@tonic-gate 	*ap_id_list = aplist;
2587c478bd9Sstevel@tonic-gate 	*nlist = apcnt;
2597c478bd9Sstevel@tonic-gate 	return (CFGA_OK);
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate done:
2627c478bd9Sstevel@tonic-gate 	s_free(aplist);
2637c478bd9Sstevel@tonic-gate 	apd_free(a);
2647c478bd9Sstevel@tonic-gate 	return (rc);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2687c478bd9Sstevel@tonic-gate cfga_err_t
cfga_help(struct cfga_msg * msgp,const char * options,cfga_flags_t flags)2697c478bd9Sstevel@tonic-gate cfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
2707c478bd9Sstevel@tonic-gate {
2717c478bd9Sstevel@tonic-gate 	return (ap_help(msgp, options, flags));
2727c478bd9Sstevel@tonic-gate }
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate /*
2767c478bd9Sstevel@tonic-gate  * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
2777c478bd9Sstevel@tonic-gate  */
278