2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#include <ctype.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <unistd.h>
2N/A#include <macros.h>
2N/A#include <libdevinfo.h>
2N/A#define CFGA_PLUGIN_LIB
2N/A#include <config_admin.h>
2N/A#include "ap.h"
2N/A
2N/Aint cfga_version = CFGA_HSL_V2;
2N/A
2N/A/*ARGSUSED*/
2N/Acfga_err_t
2N/Acfga_change_state(
2N/A cfga_cmd_t cfga_cmd,
2N/A const char *ap_id,
2N/A const char *options,
2N/A struct cfga_confirm *confp,
2N/A struct cfga_msg *msgp,
2N/A char **errstring,
2N/A cfga_flags_t flags)
2N/A{
2N/A int cmd;
2N/A const char *name;
2N/A apd_t *a;
2N/A cfga_err_t rc;
2N/A
2N/A if ((rc = ap_state_cmd(cfga_cmd, &cmd)) != CFGA_OK)
2N/A return (rc);
2N/A
2N/A rc = CFGA_LIB_ERROR;
2N/A
2N/A if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
2N/A return (rc);
2N/A
2N/A name = ap_cmd_name(cmd);
2N/A
2N/A if ((rc = ap_cmd_parse(a, name, options, NULL)) == CFGA_OK)
2N/A rc = ap_cmd_seq(a, cmd);
2N/A
2N/A apd_free(a);
2N/A
2N/A return (rc);
2N/A}
2N/A
2N/A/*
2N/A * Check if this is a valid -x command.
2N/A */
2N/Astatic int
2N/Aprivate_func(const char *function)
2N/A{
2N/A char **f;
2N/A static char *
2N/A private_funcs[] = {
2N/A "assign",
2N/A "unassign",
2N/A "poweron",
2N/A "poweroff",
2N/A "passthru",
2N/A "errtest",
2N/A NULL
2N/A };
2N/A
2N/A for (f = private_funcs; *f != NULL; f++)
2N/A if (strcmp(*f, function) == 0)
2N/A break;
2N/A
2N/A return (*f == NULL ? CFGA_INVAL : CFGA_OK);
2N/A}
2N/A
2N/A/*ARGSUSED*/
2N/Acfga_err_t
2N/Acfga_private_func(
2N/A const char *function,
2N/A const char *ap_id,
2N/A const char *options,
2N/A struct cfga_confirm *confp,
2N/A struct cfga_msg *msgp,
2N/A char **errstring,
2N/A cfga_flags_t flags)
2N/A{
2N/A int cmd;
2N/A apd_t *a;
2N/A cfga_err_t rc;
2N/A
2N/A DBG("cfga_private_func(%s)\n", ap_id);
2N/A
2N/A rc = CFGA_LIB_ERROR;
2N/A
2N/A if ((a = apd_alloc(ap_id, flags, errstring, msgp, confp)) == NULL)
2N/A return (rc);
2N/A else if ((rc = private_func(function)) != CFGA_OK) {
2N/A ap_err(a, ERR_CMD_INVAL, function);
2N/A goto done;
2N/A } else if ((rc = ap_cmd_parse(a, function, options, &cmd)) != CFGA_OK)
2N/A goto done;
2N/A else if (cmd == CMD_ERRTEST)
2N/A rc = ap_test_err(a, options);
2N/A else
2N/A rc = ap_cmd_exec(a, cmd);
2N/Adone:
2N/A apd_free(a);
2N/A return (rc);
2N/A}
2N/A
2N/A
2N/A/*ARGSUSED*/
2N/Acfga_err_t
2N/Acfga_test(
2N/A const char *ap_id,
2N/A const char *options,
2N/A struct cfga_msg *msgp,
2N/A char **errstring,
2N/A cfga_flags_t flags)
2N/A{
2N/A int cmd;
2N/A const char *f;
2N/A apd_t *a;
2N/A cfga_err_t rc;
2N/A
2N/A DBG("cfga_test(%s)\n", ap_id);
2N/A
2N/A f = "test";
2N/A rc = CFGA_LIB_ERROR;
2N/A
2N/A /*
2N/A * A test that is not sequenced by a change
2N/A * state operation should be forced.
2N/A */
2N/A flags |= CFGA_FLAG_FORCE;
2N/A
2N/A if ((a = apd_alloc(ap_id, flags, errstring, msgp, NULL)) == NULL)
2N/A return (rc);
2N/A else if ((rc = ap_cmd_parse(a, f, options, &cmd)) != CFGA_OK)
2N/A goto done;
2N/A else
2N/A rc = ap_cmd_exec(a, cmd);
2N/Adone:
2N/A apd_free(a);
2N/A return (rc);
2N/A}
2N/A
2N/A/*ARGSUSED*/
2N/Acfga_err_t
2N/Acfga_list_ext(
2N/A const char *ap_id,
2N/A cfga_list_data_t **ap_id_list,
2N/A int *nlist,
2N/A const char *options,
2N/A const char *listopts,
2N/A char **errstring,
2N/A cfga_flags_t flags)
2N/A{
2N/A int i;
2N/A int apcnt;
2N/A const char *f;
2N/A apd_t *a;
2N/A size_t szl, szp;
2N/A cfga_list_data_t *aplist, *ap;
2N/A cfga_err_t rc;
2N/A
2N/A rc = CFGA_LIB_ERROR;
2N/A
2N/A aplist = NULL;
2N/A f = ap_cmd_name(CMD_STATUS);
2N/A
2N/A DBG("cfga_list_ext(%s %x)\n", ap_id, flags);
2N/A
2N/A if ((a = apd_alloc(ap_id, flags, errstring, NULL, NULL)) == NULL)
2N/A return (rc);
2N/A else if ((rc = ap_cmd_parse(a, f, options, NULL)) != CFGA_OK)
2N/A goto done;
2N/A
2N/A apcnt = ap_cnt(a);
2N/A
2N/A DBG("apcnt=%d\n", apcnt);
2N/A
2N/A if ((aplist = calloc(apcnt, sizeof (*aplist))) == NULL) {
2N/A rc = CFGA_LIB_ERROR;
2N/A ap_err(a, ERR_CMD_FAIL, CMD_STATUS);
2N/A goto done;
2N/A }
2N/A
2N/A ap = aplist;
2N/A szl = sizeof (ap->ap_log_id);
2N/A szp = sizeof (ap->ap_phys_id);
2N/A
2N/A /*
2N/A * Initialize the AP specified directly by the caller.
2N/A * The target ID for the 0th element already includes
2N/A * the (potential) dynamic portion. The dynamic portion
2N/A * does need to be appended to the path to form the
2N/A * physical apid for components.
2N/A */
2N/A (void) strncpy(ap->ap_log_id, a->target, szl - 1);
2N/A (void) snprintf(ap->ap_phys_id, szp, "%s%s%s", a->path,
2N/A a->tgt != AP_BOARD ? "::" : "",
2N/A a->tgt != AP_BOARD ? a->cid : "");
2N/A
2N/A
2N/A DBG("ap_phys_id=%s ap_log_id=%s\n", ap->ap_phys_id, ap->ap_log_id);
2N/A
2N/A if (a->tgt == AP_BOARD) {
2N/A
2N/A ap_init(a, ap++);
2N/A
2N/A /*
2N/A * Initialize the components, if any.
2N/A */
2N/A for (i = 0; i < apcnt - 1; i++, ap++) {
2N/A char dyn[MAXPATHLEN];
2N/A
2N/A ap_cm_id(a, i, dyn, sizeof (dyn));
2N/A
2N/A (void) snprintf(ap->ap_log_id, szl, "%s::%s",
2N/A a->target, dyn);
2N/A (void) snprintf(ap->ap_phys_id, szp, "%s::%s",
2N/A a->path, dyn);
2N/A
2N/A ap_cm_init(a, ap, i);
2N/A
2N/A DBG("ap_phys_id=%s ap_log_id=%s\n",
2N/A ap->ap_phys_id, ap->ap_log_id);
2N/A }
2N/A
2N/A } else
2N/A ap_cm_init(a, ap, 0);
2N/A
2N/A apd_free(a);
2N/A *ap_id_list = aplist;
2N/A *nlist = apcnt;
2N/A return (CFGA_OK);
2N/A
2N/Adone:
2N/A s_free(aplist);
2N/A apd_free(a);
2N/A return (rc);
2N/A}
2N/A
2N/A/*ARGSUSED*/
2N/Acfga_err_t
2N/Acfga_help(struct cfga_msg *msgp, const char *options, cfga_flags_t flags)
2N/A{
2N/A return (ap_help(msgp, options, flags));
2N/A}
2N/A
2N/A
2N/A/*
2N/A * cfga_ap_id_cmp -- use default_ap_id_cmp() in libcfgadm
2N/A */