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