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
ap_symid(apd_t * a,char * apid,char * symid,size_t bufsize)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 *
ap_logid(apd_t * a,char * apid)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
ap_parse(apd_t * a,const char * ap_id)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 *
ap_cmd_name(int i)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 *
ap_opt_name(int i)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
ap_cmds_dump()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
ap_state_cmd(cfga_cmd_t i,int * cmd)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
ap_cmd(char * name)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
ap_opt_parse(apd_t * a,ap_cmd_t * acp,const char * options)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 *
ap_cmdp(int cmd)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
ap_cmd_parse(apd_t * a,const char * f,const char * options,int * cmd)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
ap_cnt(apd_t * a)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