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