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 /* 22*a3114836SGerry Liu * Copyright 2010 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 <assert.h> 277c478bd9Sstevel@tonic-gate #include <ctype.h> 287c478bd9Sstevel@tonic-gate #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <unistd.h> 327c478bd9Sstevel@tonic-gate #include <macros.h> 337c478bd9Sstevel@tonic-gate #include <dirent.h> 347c478bd9Sstevel@tonic-gate #include <libgen.h> 357c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 367c478bd9Sstevel@tonic-gate #define CFGA_PLUGIN_LIB 377c478bd9Sstevel@tonic-gate #include <config_admin.h> 387c478bd9Sstevel@tonic-gate #include "ap.h" 397c478bd9Sstevel@tonic-gate 40*a3114836SGerry Liu /*ARGSUSED0*/ 417c478bd9Sstevel@tonic-gate int 427c478bd9Sstevel@tonic-gate ap_symid(apd_t *a, char *apid, char *symid, size_t bufsize) 437c478bd9Sstevel@tonic-gate { 447c478bd9Sstevel@tonic-gate int n; 457c478bd9Sstevel@tonic-gate int rc; 467c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 477c478bd9Sstevel@tonic-gate char *p; 487c478bd9Sstevel@tonic-gate DIR *dirp; 497c478bd9Sstevel@tonic-gate struct dirent *dp; 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate *symid = '\0'; 527c478bd9Sstevel@tonic-gate n = sprintf(path, "/dev/cfg/"); 537c478bd9Sstevel@tonic-gate rc = -1; 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate if ((dirp = opendir(path)) == NULL) 567c478bd9Sstevel@tonic-gate return (rc); 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate p = path + n; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) { 617c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 627c478bd9Sstevel@tonic-gate char *cp; 637c478bd9Sstevel@tonic-gate size_t len; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate *p = '\0'; 667c478bd9Sstevel@tonic-gate (void) strcat(path, dp->d_name); 677c478bd9Sstevel@tonic-gate if ((len = readlink(path, buf, sizeof (buf))) == (size_t)-1) 687c478bd9Sstevel@tonic-gate continue; 697c478bd9Sstevel@tonic-gate buf[len] = '\0'; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate len = strlen("../"); 727c478bd9Sstevel@tonic-gate cp = buf; 737c478bd9Sstevel@tonic-gate while (strncmp(cp, "../", len) == 0) 747c478bd9Sstevel@tonic-gate cp += len; 757c478bd9Sstevel@tonic-gate if (cp != buf) 767c478bd9Sstevel@tonic-gate cp--; /* Get the '/' */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate if (strcmp(cp, apid) == 0) { 79*a3114836SGerry Liu (void) snprintf(symid, bufsize, "%s", dp->d_name); 807c478bd9Sstevel@tonic-gate rc = 0; 817c478bd9Sstevel@tonic-gate break; 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 85*a3114836SGerry Liu (void) closedir(dirp); 867c478bd9Sstevel@tonic-gate return (rc); 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate char * 907c478bd9Sstevel@tonic-gate ap_logid(apd_t *a, char *apid) 917c478bd9Sstevel@tonic-gate { 927c478bd9Sstevel@tonic-gate int n; 937c478bd9Sstevel@tonic-gate char *buf; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate if ((buf = calloc(1, MAXPATHLEN)) == NULL) 967c478bd9Sstevel@tonic-gate return (NULL); 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Look for a symlink. On any error, fallback to 1007c478bd9Sstevel@tonic-gate * driver and instance based logical ap_ids. 1017c478bd9Sstevel@tonic-gate */ 1027c478bd9Sstevel@tonic-gate if (ap_symid(a, apid, buf, MAXPATHLEN) == 0) 1037c478bd9Sstevel@tonic-gate n = strlen(buf); 1047c478bd9Sstevel@tonic-gate else 1057c478bd9Sstevel@tonic-gate n = snprintf(buf, MAXPATHLEN, "%s%d:%s", 1067c478bd9Sstevel@tonic-gate a->drv, a->inst, a->minor); 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * Append the dynamic portion, if any. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate if (a->cid != NULL) 1117c478bd9Sstevel@tonic-gate (void) snprintf(&buf[n], MAXPATHLEN - n, "::%s", a->cid); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate return (buf); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate int 1177c478bd9Sstevel@tonic-gate ap_parse(apd_t *a, const char *ap_id) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate int i; 1207c478bd9Sstevel@tonic-gate int rc; 1217c478bd9Sstevel@tonic-gate int phys; 1227c478bd9Sstevel@tonic-gate char c; 1237c478bd9Sstevel@tonic-gate char *s; 1247c478bd9Sstevel@tonic-gate char *p; 1257c478bd9Sstevel@tonic-gate char *q; 1267c478bd9Sstevel@tonic-gate char *base; 1277c478bd9Sstevel@tonic-gate int len; 1287c478bd9Sstevel@tonic-gate char *t; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate if (a == NULL) 1317c478bd9Sstevel@tonic-gate return (-1); 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate a->cnum = -1; 1347c478bd9Sstevel@tonic-gate a->bnum = -1; 1357c478bd9Sstevel@tonic-gate a->inst = -1; 1367c478bd9Sstevel@tonic-gate a->apid = ap_id; 1377c478bd9Sstevel@tonic-gate rc = ERR_NONE; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if (!str_valid(ap_id)) { 1407c478bd9Sstevel@tonic-gate rc = ERR_AP_INVAL; 1417c478bd9Sstevel@tonic-gate goto done; 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate if ((a->path = strdup(ap_id)) == NULL) { 1457c478bd9Sstevel@tonic-gate rc = ERR_NOMEM; 1467c478bd9Sstevel@tonic-gate goto done; 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * For a physical ap_id, look only at the base part. 1517c478bd9Sstevel@tonic-gate * For a logical/symbolic one, use the entire ap_id. 1527c478bd9Sstevel@tonic-gate */ 1537c478bd9Sstevel@tonic-gate if (strncmp(a->path, DEVDIR, strlen(DEVDIR)) == 0) { 1547c478bd9Sstevel@tonic-gate phys = 1; 1557c478bd9Sstevel@tonic-gate base = strrchr((const char *)a->path, '/') + 1; 1567c478bd9Sstevel@tonic-gate } else { 1577c478bd9Sstevel@tonic-gate phys = 0; 1587c478bd9Sstevel@tonic-gate base = a->path; 1597c478bd9Sstevel@tonic-gate if ((a->target = strdup(a->path)) == NULL) { 1607c478bd9Sstevel@tonic-gate rc = ERR_NOMEM; 1617c478bd9Sstevel@tonic-gate goto done; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate if ((s = strchr(base, ':')) == NULL || s[1] == ':') { 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * No ':' found, or got a '::'. If this is a physical 1687c478bd9Sstevel@tonic-gate * ap_id, it must have a minor separtor ':' which must 1697c478bd9Sstevel@tonic-gate * appear before the dynamic part (starting with '::'). 1707c478bd9Sstevel@tonic-gate * For a symbolic ap_id, skip looking for driver/minor 1717c478bd9Sstevel@tonic-gate * names. 1727c478bd9Sstevel@tonic-gate */ 1737c478bd9Sstevel@tonic-gate if (phys) { 1747c478bd9Sstevel@tonic-gate rc = ERR_AP_INVAL; 1757c478bd9Sstevel@tonic-gate goto done; 1767c478bd9Sstevel@tonic-gate } else 1777c478bd9Sstevel@tonic-gate s = base; 1787c478bd9Sstevel@tonic-gate } else { 1797c478bd9Sstevel@tonic-gate /* 1807c478bd9Sstevel@tonic-gate * Look for driver name/instance only up to the first ':', 1817c478bd9Sstevel@tonic-gate * i.e. up to the minor node name. 1827c478bd9Sstevel@tonic-gate */ 1837c478bd9Sstevel@tonic-gate *s = '\0'; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if ((p = strchr(base, '@')) != NULL) { 1867c478bd9Sstevel@tonic-gate /* 1877c478bd9Sstevel@tonic-gate * Get the driver name/instance. 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate *p = '\0'; 1907c478bd9Sstevel@tonic-gate if ((a->drv = strdup(base)) == NULL) { 1917c478bd9Sstevel@tonic-gate rc = ERR_NOMEM; 1927c478bd9Sstevel@tonic-gate goto done; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate *p++ = '@'; 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate i = strtol(p, &q, 10); 1977c478bd9Sstevel@tonic-gate if (q > p) 1987c478bd9Sstevel@tonic-gate a->inst = i; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate *s++ = ':'; 2027c478bd9Sstevel@tonic-gate a->minor = s; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate /* 2067c478bd9Sstevel@tonic-gate * Need to go to the end of the string before the :: if any 2077c478bd9Sstevel@tonic-gate * If the string is null then we are done 2087c478bd9Sstevel@tonic-gate */ 2097c478bd9Sstevel@tonic-gate t = strstr(s, "::"); 2107c478bd9Sstevel@tonic-gate if (t != NULL) 2117c478bd9Sstevel@tonic-gate len = strlen(t); 2127c478bd9Sstevel@tonic-gate else 2137c478bd9Sstevel@tonic-gate len = 0; 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate s += (strlen(s) - len); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate p = s; 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate if (*p == '\0') 2207c478bd9Sstevel@tonic-gate a->tgt = AP_BOARD; 2217c478bd9Sstevel@tonic-gate else if (strncmp(p, "::", 2) != 0) { 2227c478bd9Sstevel@tonic-gate rc = ERR_AP_INVAL; 2237c478bd9Sstevel@tonic-gate goto done; 2247c478bd9Sstevel@tonic-gate } else { 2257c478bd9Sstevel@tonic-gate /* 2267c478bd9Sstevel@tonic-gate * Save the component id. 2277c478bd9Sstevel@tonic-gate */ 2287c478bd9Sstevel@tonic-gate *p++ = '\0'; 2297c478bd9Sstevel@tonic-gate *p++ = '\0'; 2307c478bd9Sstevel@tonic-gate a->cid = p; 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * Get the operation target, e.g. slot0, slot0::cpu0. 2357c478bd9Sstevel@tonic-gate * At this point, a->path points to the /devices path 2367c478bd9Sstevel@tonic-gate * minus the dynamic part, for a physical ap_id. In 2377c478bd9Sstevel@tonic-gate * the case of a logical ap_id, the target is already 2387c478bd9Sstevel@tonic-gate * initialized above. 2397c478bd9Sstevel@tonic-gate */ 2407c478bd9Sstevel@tonic-gate if (phys != 0 && (a->target = ap_logid(a, a->path)) == NULL) { 2417c478bd9Sstevel@tonic-gate rc = ERR_NOMEM; 2427c478bd9Sstevel@tonic-gate goto done; 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate if (a->tgt == AP_BOARD) 2467c478bd9Sstevel@tonic-gate goto done; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate while ((*p != '\0') && !isdigit(*p)) 2497c478bd9Sstevel@tonic-gate p++; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* 2527c478bd9Sstevel@tonic-gate * Get the component unit number, if present. 2537c478bd9Sstevel@tonic-gate */ 2547c478bd9Sstevel@tonic-gate i = strtol(p, &s, 10); 2557c478bd9Sstevel@tonic-gate /* 2567c478bd9Sstevel@tonic-gate * There must be no characters after the unit number. 2577c478bd9Sstevel@tonic-gate */ 2587c478bd9Sstevel@tonic-gate if (*s != '\0') { 2597c478bd9Sstevel@tonic-gate rc = ERR_CM_INVAL; 2607c478bd9Sstevel@tonic-gate goto done; 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate if (s > p) { 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * Disallow leading zeroes, e.g. cpu00, cpu01, cpu001. 2657c478bd9Sstevel@tonic-gate * If there are 2 or more digits and the first is a zero, 2667c478bd9Sstevel@tonic-gate * we fail. 2677c478bd9Sstevel@tonic-gate */ 2687c478bd9Sstevel@tonic-gate if ((s-p) >= 2 && *p == '0') { 2697c478bd9Sstevel@tonic-gate rc = ERR_CM_INVAL; 2707c478bd9Sstevel@tonic-gate goto done; 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate a->cnum = i; 2737c478bd9Sstevel@tonic-gate } 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate c = *p; 2767c478bd9Sstevel@tonic-gate *p = '\0'; 2777c478bd9Sstevel@tonic-gate if ((a->cname = strdup(a->cid)) == NULL) 2787c478bd9Sstevel@tonic-gate rc = ERR_NOMEM; 2797c478bd9Sstevel@tonic-gate *p = c; 2807c478bd9Sstevel@tonic-gate done: 2817c478bd9Sstevel@tonic-gate switch (rc) { 2827c478bd9Sstevel@tonic-gate case ERR_NONE: 2837c478bd9Sstevel@tonic-gate break; 2847c478bd9Sstevel@tonic-gate case ERR_CM_INVAL: 2857c478bd9Sstevel@tonic-gate ap_err(a, ERR_CM_INVAL, a->cid); 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate default: 2887c478bd9Sstevel@tonic-gate ap_err(a, rc); 2897c478bd9Sstevel@tonic-gate break; 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate DBG("path=<%s> ", a->path ? a->path : ""); 2937c478bd9Sstevel@tonic-gate DBG("drv=<%s> inst=%d minor=<%s> ", 2947c478bd9Sstevel@tonic-gate a->drv ? a->drv : "", a->inst, a->minor ? a->minor : ""); 2957c478bd9Sstevel@tonic-gate DBG("target=<%s>\n", a->target ? a->target : ""); 2967c478bd9Sstevel@tonic-gate DBG("cid=<%s> ", a->cid ? a->cid : ""); 2977c478bd9Sstevel@tonic-gate DBG("cname=<%s> ", a->cname ? a->cname : ""); 2987c478bd9Sstevel@tonic-gate DBG("cnum=%d\n", a->cnum); 2997c478bd9Sstevel@tonic-gate DBG("tgt=%d opts=%x\n", a->tgt, a->opts.flags); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate return (rc == ERR_NONE? 0 : -1); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * Command table. 3067c478bd9Sstevel@tonic-gate * 3077c478bd9Sstevel@tonic-gate * The first set of commands in the table are in sequencing order, 3087c478bd9Sstevel@tonic-gate * for example, the first group starts with assign and ends with 3097c478bd9Sstevel@tonic-gate * configure. command sequencer relies on this ordering. 3107c478bd9Sstevel@tonic-gate */ 3117c478bd9Sstevel@tonic-gate static char * 3127c478bd9Sstevel@tonic-gate ap_cmd_names[] = { 3137c478bd9Sstevel@tonic-gate "assign", 3147c478bd9Sstevel@tonic-gate "poweron", 3157c478bd9Sstevel@tonic-gate "test", 3167c478bd9Sstevel@tonic-gate "connect", 3177c478bd9Sstevel@tonic-gate "configure", 3187c478bd9Sstevel@tonic-gate "notify online", 3197c478bd9Sstevel@tonic-gate "notify add capacity", 3207c478bd9Sstevel@tonic-gate "suspend check", 3217c478bd9Sstevel@tonic-gate "request suspend", 3227c478bd9Sstevel@tonic-gate "request delete capacity", 3237c478bd9Sstevel@tonic-gate "request offline", 3247c478bd9Sstevel@tonic-gate "unconfigure", 3257c478bd9Sstevel@tonic-gate "notify remove", 3267c478bd9Sstevel@tonic-gate "notify capacity change", 3277c478bd9Sstevel@tonic-gate "disconnect", 3287c478bd9Sstevel@tonic-gate "poweroff", 3297c478bd9Sstevel@tonic-gate "unassign", 3307c478bd9Sstevel@tonic-gate "notify resume", 3317c478bd9Sstevel@tonic-gate "status", 3327c478bd9Sstevel@tonic-gate "getncm", 3337c478bd9Sstevel@tonic-gate "passthru", 3347c478bd9Sstevel@tonic-gate "help", 3357c478bd9Sstevel@tonic-gate "errtest", 3367c478bd9Sstevel@tonic-gate NULL 3377c478bd9Sstevel@tonic-gate }; 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate char * 3407c478bd9Sstevel@tonic-gate ap_cmd_name(int i) 3417c478bd9Sstevel@tonic-gate { 3427c478bd9Sstevel@tonic-gate return (ap_cmd_names[min(i, CMD_NONE)]); 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate static char * 3467c478bd9Sstevel@tonic-gate ap_opt_names[] = { 3477c478bd9Sstevel@tonic-gate "unassign", 3487c478bd9Sstevel@tonic-gate "skip", 3497c478bd9Sstevel@tonic-gate "parsable", 3507c478bd9Sstevel@tonic-gate "nopoweroff", 3517c478bd9Sstevel@tonic-gate "code", 3527c478bd9Sstevel@tonic-gate "mid", 3537c478bd9Sstevel@tonic-gate "err", 3547c478bd9Sstevel@tonic-gate "platform", 3557c478bd9Sstevel@tonic-gate "sim", 3567c478bd9Sstevel@tonic-gate NULL 3577c478bd9Sstevel@tonic-gate }; 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate char * 3607c478bd9Sstevel@tonic-gate ap_opt_name(int i) 3617c478bd9Sstevel@tonic-gate { 3627c478bd9Sstevel@tonic-gate return (ap_opt_names[i]); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Command descriptor. 3677c478bd9Sstevel@tonic-gate * 3687c478bd9Sstevel@tonic-gate * Each command has a (command) mask specifying the AP target classes 3697c478bd9Sstevel@tonic-gate * it operates on, e.g. the assign command applies only to boards. 3707c478bd9Sstevel@tonic-gate * In addition each AP target class has a separate option mask specifying 3717c478bd9Sstevel@tonic-gate * which command options are valid for that target class. 3727c478bd9Sstevel@tonic-gate * A global value mask specifies which options require values. 3737c478bd9Sstevel@tonic-gate */ 3747c478bd9Sstevel@tonic-gate typedef struct { 3757c478bd9Sstevel@tonic-gate int cmd; 3767c478bd9Sstevel@tonic-gate uint_t cmask; 3777c478bd9Sstevel@tonic-gate uint_t omask[AP_NCLASS]; 3787c478bd9Sstevel@tonic-gate } ap_cmd_t; 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate /* 3817c478bd9Sstevel@tonic-gate * Command option definitions. 3827c478bd9Sstevel@tonic-gate */ 3837c478bd9Sstevel@tonic-gate #define SHFT(i) ((uint_t)1 << (i)) 3847c478bd9Sstevel@tonic-gate #define NULOPT 0 3857c478bd9Sstevel@tonic-gate #define ALLOPT 0xffffffff 3867c478bd9Sstevel@tonic-gate #define CMNOPT (SHFT(OPT_VERBOSE)|SHFT(OPT_PLATFORM)|SHFT(OPT_SIM)) 3877c478bd9Sstevel@tonic-gate #define CMFOPT (CMNOPT|SHFT(OPT_FORCE)) 3887c478bd9Sstevel@tonic-gate #define STSOPT (CMNOPT|SHFT(OPT_PARSABLE)) 3897c478bd9Sstevel@tonic-gate #define BRDDCN (CMNOPT|SHFT(OPT_UNASSIGN)|SHFT(OPT_NOPOWEROFF)) 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate #define BRD SHFT(AP_BOARD) 3927c478bd9Sstevel@tonic-gate #define BIO SHFT(AP_BOARD)|SHFT(AP_IO) 3937c478bd9Sstevel@tonic-gate #define ALL (BRD|SHFT(AP_CPU)|SHFT(AP_MEM)|SHFT(AP_IO)|SHFT(AP_CMP)) 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate static ap_cmd_t 3967c478bd9Sstevel@tonic-gate ap_cmds[] = { 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * cmd cmd board cpu mem io cmp 3997c478bd9Sstevel@tonic-gate * cmask omask omask omask omask omask 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate {CMD_ASSIGN, BRD, 0, CMNOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4027c478bd9Sstevel@tonic-gate {CMD_UNASSIGN, BRD, 0, CMNOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4037c478bd9Sstevel@tonic-gate {CMD_POWERON, BRD, 0, CMNOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4047c478bd9Sstevel@tonic-gate {CMD_POWEROFF, BRD, 0, CMNOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4057c478bd9Sstevel@tonic-gate {CMD_CONNECT, BRD, 0, CMFOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4067c478bd9Sstevel@tonic-gate {CMD_DISCONNECT, BRD, 0, BRDDCN, NULOPT, NULOPT, NULOPT, NULOPT}, 4077c478bd9Sstevel@tonic-gate {CMD_CONFIGURE, ALL, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4087c478bd9Sstevel@tonic-gate {CMD_UNCONFIGURE, ALL, 0, CMFOPT, CMFOPT, CMFOPT, CMFOPT, CMNOPT}, 4097c478bd9Sstevel@tonic-gate {CMD_RCM_OFFLINE, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4107c478bd9Sstevel@tonic-gate {CMD_RCM_ONLINE, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4117c478bd9Sstevel@tonic-gate {CMD_RCM_SUSPEND, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4127c478bd9Sstevel@tonic-gate {CMD_RCM_RESUME, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4137c478bd9Sstevel@tonic-gate {CMD_RCM_CAP_ADD, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4147c478bd9Sstevel@tonic-gate {CMD_RCM_CAP_DEL, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4157c478bd9Sstevel@tonic-gate {CMD_RCM_CAP_NOTIFY, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4167c478bd9Sstevel@tonic-gate {CMD_RCM_REMOVE, BIO, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4177c478bd9Sstevel@tonic-gate {CMD_TEST, BRD, 0, CMFOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4187c478bd9Sstevel@tonic-gate {CMD_STATUS, ALL, 0, STSOPT, STSOPT, STSOPT, STSOPT, STSOPT}, 4197c478bd9Sstevel@tonic-gate {CMD_GETNCM, BRD, 0, CMNOPT, NULOPT, NULOPT, NULOPT, NULOPT}, 4207c478bd9Sstevel@tonic-gate {CMD_PASSTHRU, ALL, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4217c478bd9Sstevel@tonic-gate {CMD_HELP, ALL, 0, CMNOPT, CMNOPT, CMNOPT, CMNOPT, CMNOPT}, 4227c478bd9Sstevel@tonic-gate {CMD_ERRTEST, ALL, 0, ALLOPT, ALLOPT, ALLOPT, ALLOPT, ALLOPT}, 4237c478bd9Sstevel@tonic-gate {CMD_NONE, 0, 0, 0, 0, 0, 0, 0 } 4247c478bd9Sstevel@tonic-gate }; 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate /* 4277c478bd9Sstevel@tonic-gate * Global mask for options that require values. 4287c478bd9Sstevel@tonic-gate */ 4297c478bd9Sstevel@tonic-gate #define AP_VMASK (\ 4307c478bd9Sstevel@tonic-gate SHFT(OPT_CODE)|SHFT(OPT_MID)|SHFT(OPT_ERR)| \ 4317c478bd9Sstevel@tonic-gate SHFT(OPT_PLATFORM)|SHFT(OPT_SKIP)) 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate #if SBD_DEBUG 4347c478bd9Sstevel@tonic-gate void 4357c478bd9Sstevel@tonic-gate ap_cmds_dump() 4367c478bd9Sstevel@tonic-gate { 4377c478bd9Sstevel@tonic-gate int i; 4387c478bd9Sstevel@tonic-gate ap_cmd_t *acp; 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate dbg("vmask=0x%x\n", AP_VMASK); 4417c478bd9Sstevel@tonic-gate dbg("%23s%5s%5s%9s%9s%9s%9s%9s\n", 4427c478bd9Sstevel@tonic-gate "cmd", "msk", "none", "brd", "cpu", "mem", "io", "cmp"); 4437c478bd9Sstevel@tonic-gate 4447c478bd9Sstevel@tonic-gate for (acp = ap_cmds; acp->cmd != CMD_NONE; acp++) { 4457c478bd9Sstevel@tonic-gate dbg("%23s%5x%5x", ap_cmd_name(acp->cmd), acp->cmask, 4467c478bd9Sstevel@tonic-gate acp->omask[AP_NONE]); 4477c478bd9Sstevel@tonic-gate for (i = AP_BOARD; i < AP_NCLASS; i++) { 4487c478bd9Sstevel@tonic-gate dbg("%9x", acp->omask[i]); 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate dbg("\n"); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate #endif 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate int 4567c478bd9Sstevel@tonic-gate ap_state_cmd(cfga_cmd_t i, int *cmd) 4577c478bd9Sstevel@tonic-gate { 4587c478bd9Sstevel@tonic-gate int c; 4597c478bd9Sstevel@tonic-gate int rc; 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate rc = CFGA_OK; 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate switch (i) { 4647c478bd9Sstevel@tonic-gate case CFGA_CMD_CONNECT: 4657c478bd9Sstevel@tonic-gate c = CMD_CONNECT; 4667c478bd9Sstevel@tonic-gate break; 4677c478bd9Sstevel@tonic-gate case CFGA_CMD_DISCONNECT: 4687c478bd9Sstevel@tonic-gate c = CMD_DISCONNECT; 4697c478bd9Sstevel@tonic-gate break; 4707c478bd9Sstevel@tonic-gate case CFGA_CMD_CONFIGURE: 4717c478bd9Sstevel@tonic-gate c = CMD_CONFIGURE; 4727c478bd9Sstevel@tonic-gate break; 4737c478bd9Sstevel@tonic-gate case CFGA_CMD_UNCONFIGURE: 4747c478bd9Sstevel@tonic-gate c = CMD_UNCONFIGURE; 4757c478bd9Sstevel@tonic-gate break; 4767c478bd9Sstevel@tonic-gate case CFGA_CMD_LOAD: 4777c478bd9Sstevel@tonic-gate case CFGA_CMD_UNLOAD: 4787c478bd9Sstevel@tonic-gate rc = CFGA_OPNOTSUPP; 4797c478bd9Sstevel@tonic-gate c = CMD_NONE; 4807c478bd9Sstevel@tonic-gate break; 4817c478bd9Sstevel@tonic-gate default: 4827c478bd9Sstevel@tonic-gate rc = CFGA_INVAL; 4837c478bd9Sstevel@tonic-gate c = CMD_NONE; 4847c478bd9Sstevel@tonic-gate break; 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate *cmd = c; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate return (rc); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate static int 4937c478bd9Sstevel@tonic-gate ap_cmd(char *name) 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate int i; 4967c478bd9Sstevel@tonic-gate char **p; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (name == NULL) 4997c478bd9Sstevel@tonic-gate return (CMD_NONE); 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate for (i = 0, p = ap_cmd_names; *p != NULL; p++, i++) 5027c478bd9Sstevel@tonic-gate if (strcmp(*p, name) == 0) 5037c478bd9Sstevel@tonic-gate break; 5047c478bd9Sstevel@tonic-gate if (*p == NULL) 5057c478bd9Sstevel@tonic-gate i = CMD_NONE; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate return (i); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate static int 5117c478bd9Sstevel@tonic-gate ap_opt_parse(apd_t *a, ap_cmd_t *acp, const char *options) 5127c478bd9Sstevel@tonic-gate { 5137c478bd9Sstevel@tonic-gate char *optstr; 5147c478bd9Sstevel@tonic-gate ap_opts_t *opts; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate /* 5177c478bd9Sstevel@tonic-gate * Set default values. 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate opts = &a->opts; 5207c478bd9Sstevel@tonic-gate opts->mid = (char *)a->class; 5217c478bd9Sstevel@tonic-gate opts->err = ERR_CMD_FAIL; 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate if (options == NULL) 5247c478bd9Sstevel@tonic-gate return (0); 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate if ((optstr = strdup(options)) == NULL) { 5277c478bd9Sstevel@tonic-gate ap_err(a, ERR_NOMEM); 5287c478bd9Sstevel@tonic-gate return (-1); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate a->options = optstr; 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate if (acp->cmd == CMD_PASSTHRU) 5347c478bd9Sstevel@tonic-gate return (0); 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate while (*optstr != '\0') { 5377c478bd9Sstevel@tonic-gate int i; 5387c478bd9Sstevel@tonic-gate int opt; 5397c478bd9Sstevel@tonic-gate int omask; 5407c478bd9Sstevel@tonic-gate char *p; 5417c478bd9Sstevel@tonic-gate char *value; 5427c478bd9Sstevel@tonic-gate char *optname; 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate value = NULL; 5457c478bd9Sstevel@tonic-gate opt = getsubopt(&optstr, ap_opt_names, &value); 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate DBG("opt=%d\n", opt); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate if (opt == -1) { 5507c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_INVAL, value); 5517c478bd9Sstevel@tonic-gate return (-1); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate optname = ap_opt_names[opt]; 5557c478bd9Sstevel@tonic-gate omask = acp->omask[a->tgt]; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate i = mask(opt) & omask; 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate DBG("tgt=%d opt=%x omask=%x\n", a->tgt, mask(opt), omask); 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (i == 0) { 5627c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_INVAL, optname); 5637c478bd9Sstevel@tonic-gate return (-1); 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate /* 5677c478bd9Sstevel@tonic-gate * Check whether the option requires a value. 5687c478bd9Sstevel@tonic-gate */ 5697c478bd9Sstevel@tonic-gate i = mask(opt) & AP_VMASK; 5707c478bd9Sstevel@tonic-gate if (i != 0 && value == NULL) { 5717c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_NOVAL, optname); 5727c478bd9Sstevel@tonic-gate return (-1); 5737c478bd9Sstevel@tonic-gate } else if (i == 0 && value != NULL) { 5747c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_VAL, optname); 5757c478bd9Sstevel@tonic-gate return (-1); 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate if (value == NULL) 5797c478bd9Sstevel@tonic-gate assert(opt != OPT_CODE); /* XXX prefix */ 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate /* 5827c478bd9Sstevel@tonic-gate * Set the options's value. 5837c478bd9Sstevel@tonic-gate */ 5847c478bd9Sstevel@tonic-gate switch (opt) { 5857c478bd9Sstevel@tonic-gate case OPT_SIM: 5867c478bd9Sstevel@tonic-gate case OPT_PARSABLE: 5877c478bd9Sstevel@tonic-gate case OPT_UNASSIGN: 5887c478bd9Sstevel@tonic-gate break; 5897c478bd9Sstevel@tonic-gate case OPT_CODE: 5907c478bd9Sstevel@tonic-gate i = strtol(value, &p, 10); 5917c478bd9Sstevel@tonic-gate if (p > value) 5927c478bd9Sstevel@tonic-gate opts->code = i; 5937c478bd9Sstevel@tonic-gate break; 5947c478bd9Sstevel@tonic-gate case OPT_MID: 5957c478bd9Sstevel@tonic-gate opts->mid = value; 5967c478bd9Sstevel@tonic-gate break; 5977c478bd9Sstevel@tonic-gate case OPT_ERR: 5987c478bd9Sstevel@tonic-gate i = strtol(value, &p, 10); 5997c478bd9Sstevel@tonic-gate if (p > value) 6007c478bd9Sstevel@tonic-gate opts->err = i; 6017c478bd9Sstevel@tonic-gate break; 6027c478bd9Sstevel@tonic-gate case OPT_NOPOWEROFF: 6037c478bd9Sstevel@tonic-gate i = ap_cmd("poweroff"); 6047c478bd9Sstevel@tonic-gate opts->skip |= mask(i); 6057c478bd9Sstevel@tonic-gate break; 6067c478bd9Sstevel@tonic-gate case OPT_SKIP: /* for debugging */ 6077c478bd9Sstevel@tonic-gate /* 6087c478bd9Sstevel@tonic-gate * The skip value may be a ':' separated 6097c478bd9Sstevel@tonic-gate * list of steps (commands) to be skipped 6107c478bd9Sstevel@tonic-gate * during sequencing. 6117c478bd9Sstevel@tonic-gate */ 6127c478bd9Sstevel@tonic-gate for (p = strtok(value, ":"); p != NULL; 6137c478bd9Sstevel@tonic-gate p = strtok(NULL, ":")) { 6147c478bd9Sstevel@tonic-gate if ((i = ap_cmd(p)) == CMD_NONE) { 6157c478bd9Sstevel@tonic-gate ap_err(a, ERR_CMD_INVAL, p); 6167c478bd9Sstevel@tonic-gate return (-1); 6177c478bd9Sstevel@tonic-gate } 6187c478bd9Sstevel@tonic-gate opts->skip |= mask(i); 6197c478bd9Sstevel@tonic-gate } 6207c478bd9Sstevel@tonic-gate break; 6217c478bd9Sstevel@tonic-gate case OPT_PLATFORM: 6227c478bd9Sstevel@tonic-gate opts->platform = value; 6237c478bd9Sstevel@tonic-gate break; 6247c478bd9Sstevel@tonic-gate default: 6257c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_INVAL, optname); 6267c478bd9Sstevel@tonic-gate return (-1); 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate 6297c478bd9Sstevel@tonic-gate ap_setopt(a, opt); 6307c478bd9Sstevel@tonic-gate } 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate return (0); 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate static ap_cmd_t * 6367c478bd9Sstevel@tonic-gate ap_cmdp(int cmd) 6377c478bd9Sstevel@tonic-gate { 6387c478bd9Sstevel@tonic-gate ap_cmd_t *acp; 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate for (acp = ap_cmds; acp->cmd != CMD_NONE; acp++) 6417c478bd9Sstevel@tonic-gate if (acp->cmd == cmd) 6427c478bd9Sstevel@tonic-gate break; 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate if (acp->cmd == CMD_NONE) 6457c478bd9Sstevel@tonic-gate return (NULL); 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate return (acp); 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate cfga_err_t 6517c478bd9Sstevel@tonic-gate ap_cmd_parse(apd_t *a, const char *f, const char *options, int *cmd) 6527c478bd9Sstevel@tonic-gate { 6537c478bd9Sstevel@tonic-gate int c; 6547c478bd9Sstevel@tonic-gate int all; 6557c478bd9Sstevel@tonic-gate int tgt; 6567c478bd9Sstevel@tonic-gate int target; 6577c478bd9Sstevel@tonic-gate ap_cmd_t *acp; 6587c478bd9Sstevel@tonic-gate cfga_err_t rc; 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate #ifdef _SBD_DEBUG 6617c478bd9Sstevel@tonic-gate ap_cmds_dump(); 6627c478bd9Sstevel@tonic-gate #endif 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate rc = CFGA_INVAL; 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate if ((c = ap_cmd((char *)f)) == CMD_NONE || 6677c478bd9Sstevel@tonic-gate (acp = ap_cmdp(c)) == NULL) { 6687c478bd9Sstevel@tonic-gate ap_err(a, ERR_CMD_INVAL, f); 6697c478bd9Sstevel@tonic-gate return (rc); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * Change a->statonly to 1, if the case is CMD_STATUS. We are only 6747c478bd9Sstevel@tonic-gate * wanting to read the devices and no more 6757c478bd9Sstevel@tonic-gate */ 6767c478bd9Sstevel@tonic-gate /* 6777c478bd9Sstevel@tonic-gate * Get the status for all components if either the list all 6787c478bd9Sstevel@tonic-gate * option being specified or if we are configuring/unconfiguring 6797c478bd9Sstevel@tonic-gate * the board. The latter is needed for the RCM interface. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate switch (c) { 6827c478bd9Sstevel@tonic-gate case CMD_STATUS: 6837c478bd9Sstevel@tonic-gate all = ap_getopt(a, OPT_LIST_ALL); 6847c478bd9Sstevel@tonic-gate a->statonly = 1; 6857c478bd9Sstevel@tonic-gate break; 6867c478bd9Sstevel@tonic-gate case CMD_CONFIGURE: 6877c478bd9Sstevel@tonic-gate case CMD_UNCONFIGURE: 6887c478bd9Sstevel@tonic-gate case CMD_CONNECT: 6897c478bd9Sstevel@tonic-gate case CMD_DISCONNECT: 6907c478bd9Sstevel@tonic-gate all = (a->tgt == AP_BOARD); 6917c478bd9Sstevel@tonic-gate a->statonly = 0; 6927c478bd9Sstevel@tonic-gate break; 6937c478bd9Sstevel@tonic-gate default: 6947c478bd9Sstevel@tonic-gate all = 0; 6957c478bd9Sstevel@tonic-gate a->statonly = 0; 6967c478bd9Sstevel@tonic-gate break; 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate if ((rc = apd_init(a, all)) != CFGA_OK) 7007c478bd9Sstevel@tonic-gate return (rc); 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate rc = CFGA_INVAL; 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate /* 7057c478bd9Sstevel@tonic-gate * Get the target here in case it is a component in which 7067c478bd9Sstevel@tonic-gate * case its type is known after the initialization. 7077c478bd9Sstevel@tonic-gate */ 7087c478bd9Sstevel@tonic-gate tgt = a->tgt; 7097c478bd9Sstevel@tonic-gate target = mask(tgt); 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate DBG("cmd=%s(%d) tmask=0x%x cmask=0x%x omask=0x%x\n", 712*a3114836SGerry Liu ap_cmd_name(c), c, target, acp->cmask, acp->omask[tgt]); 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate if ((acp->cmask & target) == 0) 7157c478bd9Sstevel@tonic-gate ap_err(a, ERR_CMD_NOTSUPP, c); 7167c478bd9Sstevel@tonic-gate else if (options != NULL && acp->omask[tgt] == 0) 7177c478bd9Sstevel@tonic-gate ap_err(a, ERR_OPT_INVAL, options); 7187c478bd9Sstevel@tonic-gate else if (ap_opt_parse(a, acp, options) != -1) { 7197c478bd9Sstevel@tonic-gate if (c == CMD_STATUS) 7207c478bd9Sstevel@tonic-gate rc = ap_platopts_check(a, c, c); 7217c478bd9Sstevel@tonic-gate else 7227c478bd9Sstevel@tonic-gate rc = CFGA_OK; 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate if (cmd) 7267c478bd9Sstevel@tonic-gate *cmd = c; 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate return (rc); 7297c478bd9Sstevel@tonic-gate } 7307c478bd9Sstevel@tonic-gate 7317c478bd9Sstevel@tonic-gate int 7327c478bd9Sstevel@tonic-gate ap_cnt(apd_t *a) 7337c478bd9Sstevel@tonic-gate { 7347c478bd9Sstevel@tonic-gate int cnt; 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate if ((a->tgt == AP_BOARD) && ap_getopt(a, OPT_LIST_ALL)) 7377c478bd9Sstevel@tonic-gate cnt = a->ncm + 1; 7387c478bd9Sstevel@tonic-gate else 7397c478bd9Sstevel@tonic-gate cnt = 1; 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate return (cnt); 7427c478bd9Sstevel@tonic-gate } 743