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