269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER START
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The contents of this file are subject to the terms of the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Common Development and Distribution License (the "License").
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You may not use this file except in compliance with the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
269473047d747f7815af570197e4ef7322d3632cEvan Yan * or http://www.opensolaris.org/os/licensing.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * See the License for the specific language governing permissions
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and limitations under the License.
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * When distributing Covered Code, include this CDDL HEADER in each
269473047d747f7815af570197e4ef7322d3632cEvan Yan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * If applicable, add the following below this CDDL HEADER, with the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * fields enclosed by brackets "[]" replaced with your own identifying
269473047d747f7815af570197e4ef7322d3632cEvan Yan * information: Portions Copyright [yyyy] [name of copyright owner]
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * CDDL HEADER END
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Use is subject to license terms.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <stdio.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <stdlib.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <string.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <locale.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <libintl.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <alloca.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <getopt.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <libhotplug.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <sys/types.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <sys/sunddi.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan#include <sys/ddi_hp.h>
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#endif
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Function prototypes.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_list(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_online(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_offline(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_enable(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_disable(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_poweron(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_poweroff(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_getpriv(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_setpriv(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int cmd_changestate(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void parse_common(int, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void parse_flags(int, char **, int *, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void parse_target(int, char **, char **, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void parse_options(int, char **, char **, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void bad_option(int, int, const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void usage(const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int list_cb(hp_node_t, void *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int list_long_cb(hp_node_t, void *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int error_cb(hp_node_t, void *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void print_options(const char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void print_error(int);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int state_atoi(char *);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *state_itoa(int);
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic short valid_target(int);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Define a conversion table for hotplug states.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yantypedef struct {
269473047d747f7815af570197e4ef7322d3632cEvan Yan int state;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *state_str;
269473047d747f7815af570197e4ef7322d3632cEvan Yan short valid_target;
269473047d747f7815af570197e4ef7322d3632cEvan Yan} hpstate_t;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic hpstate_t hpstates[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_EMPTY, "EMPTY", 0 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_PRESENT, "PRESENT", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_POWERED, "POWERED", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_ENABLED, "ENABLED", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_PORT_EMPTY, "PORT-EMPTY", 0 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_PORT_PRESENT, "PORT-PRESENT", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_OFFLINE, "OFFLINE", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_ATTACHED, "ATTACHED", 0 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_MAINTENANCE, "MAINTENANCE", 0 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { DDI_HP_CN_STATE_ONLINE, "ONLINE", 1 },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Define tables of supported subcommands.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yantypedef struct {
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *usage_str;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *cmd_str;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int (*func)(int argc, char *argv[], const char *usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan} subcmd_t;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic subcmd_t subcmds[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "list [-l] [-v] [<path> [<connection>]]", "list", cmd_list },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "online <path> <port>", "online", cmd_online },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "offline [-f] [-q] <path> <port>", "offline", cmd_offline },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "enable <path> <connector>", "enable", cmd_enable },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "disable [-f] [-q] <path> <connector>", "disable", cmd_disable },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "poweron <path> <connector>", "poweron", cmd_poweron },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "poweroff [-f] [-q] <path> <connector>", "poweroff", cmd_poweroff },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "get -o <options> <path> <connector>", "get", cmd_getpriv },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "set -o <options> <path> <connector>", "set", cmd_setpriv }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic subcmd_t hidden_subcmds[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "changestate [-f] [-q] -s <state> <path> <connection>",
269473047d747f7815af570197e4ef7322d3632cEvan Yan "changestate", cmd_changestate }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Define tables of command line options.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic const struct option common_opts[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "help", no_argument, 0, '?' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "version", no_argument, 0, 'V' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic const struct option list_opts[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "list-path", no_argument, 0, 'l' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "verbose", no_argument, 0, 'v' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic const struct option flag_opts[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "force", no_argument, 0, 'f' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "query", no_argument, 0, 'q' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic const struct option private_opts[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "options", required_argument, 0, 'o' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic const struct option changestate_opts[] = {
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "force", no_argument, 0, 'f' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "query", no_argument, 0, 'q' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { "state", required_argument, 0, 's' },
269473047d747f7815af570197e4ef7322d3632cEvan Yan { 0, 0, 0, 0 }
269473047d747f7815af570197e4ef7322d3632cEvan Yan};
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Define exit codes.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define EXIT_OK 0
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define EXIT_EINVAL 1 /* invalid arguments */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define EXIT_ENOENT 2 /* path or connection doesn't exist */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define EXIT_FAILED 3 /* operation failed */
269473047d747f7815af570197e4ef7322d3632cEvan Yan#define EXIT_UNAVAIL 4 /* service not available */
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Global variables.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *prog;
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char version[] = "1.0";
269473047d747f7815af570197e4ef7322d3632cEvan Yanextern int errno;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * main()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * The main routine determines which subcommand is used,
269473047d747f7815af570197e4ef7322d3632cEvan Yan * and dispatches control to the corresponding function.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanint
269473047d747f7815af570197e4ef7322d3632cEvan Yanmain(int argc, char *argv[])
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int i, rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) setlocale(LC_ALL, "");
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) textdomain(TEXT_DOMAIN);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((prog = strrchr(argv[0], '/')) == NULL)
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog = argv[0];
269473047d747f7815af570197e4ef7322d3632cEvan Yan else
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog++;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (argc < 2) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(NULL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, NULL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Check the list of defined subcommands. */
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < (sizeof (subcmds) / sizeof (subcmd_t)); i++) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcmp(argv[1], subcmds[i].cmd_str) == 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = subcmds[i].func(argc - 1, &argv[1],
269473047d747f7815af570197e4ef7322d3632cEvan Yan subcmds[i].usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan goto finished;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Check the list of hidden subcommands. */
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < (sizeof (hidden_subcmds) / sizeof (subcmd_t)); i++) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcmp(argv[1], hidden_subcmds[i].cmd_str) == 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hidden_subcmds[i].func(argc - 1, &argv[1],
269473047d747f7815af570197e4ef7322d3632cEvan Yan hidden_subcmds[i].usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan goto finished;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* No matching subcommand found. */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: %s: unknown subcommand '%s'\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog, argv[1]);
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(NULL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(EXIT_EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yanfinished:
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Determine exit code */
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (rv) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 0:
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EINVAL:
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENXIO:
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENOENT:
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_ENOENT);
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EBADF:
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_UNAVAIL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_FAILED);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EXIT_OK);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_list()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to list hotplug information.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_list(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan boolean_t long_flag = B_FALSE;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int opt;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "lv", list_opts, NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'l':
269473047d747f7815af570197e4ef7322d3632cEvan Yan long_flag = B_TRUE;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'v':
269473047d747f7815af570197e4ef7322d3632cEvan Yan flags |= HPINFOUSAGE;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan bad_option(opt, optopt, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Default path is "/" */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (path == NULL)
269473047d747f7815af570197e4ef7322d3632cEvan Yan path = "/";
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, flags)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display hotplug information */
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(root, NULL, long_flag ? list_long_cb : list_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_online()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to online a hotplug port.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_online(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a port */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_PORT) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a port).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, 0, DDI_HP_CN_STATE_ONLINE, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (rv == EIO) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: failed to attach device "
269473047d747f7815af570197e4ef7322d3632cEvan Yan "drivers or other internal errors.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan } else if (rv != 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_offline()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to offline a hotplug port.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_offline(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_flags(argc, argv, &flags, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a port */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_PORT) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a port).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, flags, DDI_HP_CN_STATE_OFFLINE, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_enable()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to enable a hotplug connector.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_enable(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, 0, DDI_HP_CN_STATE_ENABLED, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_disable()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to disable a hotplug connector.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_disable(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_flags(argc, argv, &flags, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Do nothing unless the connector is in the ENABLED state.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Otherwise this subcommand becomes an alias for 'poweron.'
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_state(root) != DDI_HP_CN_STATE_ENABLED) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, flags, DDI_HP_CN_STATE_POWERED, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_poweron()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to power on a hotplug connector.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_poweron(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Do nothing if the connector is already powered.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Otherwise this subcommand becomes an alias for 'disable.'
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_state(root) >= DDI_HP_CN_STATE_POWERED) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, 0, DDI_HP_CN_STATE_POWERED, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_poweroff()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to power off a hotplug connector.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_poweroff(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_flags(argc, argv, &flags, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Path and connection are required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do state change */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, flags, DDI_HP_CN_STATE_PRESENT, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_getpriv()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to get and display bus private options.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_getpriv(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *options = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_options(argc, argv, &options, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Options, path, and connection are all required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((options == NULL) || (path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do the operation */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_get_private(root, options, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (rv == ENOTSUP) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: unsupported property name or value.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("(Properties may depend upon connector state.)\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan } else if (rv != 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_options(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan free(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_setpriv()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to set bus private options.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_setpriv(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *options = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_options(argc, argv, &options, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Options, path, and connection are all required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((options == NULL) || (path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Verify target is a connector */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(root) != HP_NODE_CONNECTOR) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target (must be a connector).\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do the operation */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_private(root, options, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (rv == ENOTSUP) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: unsupported property name or value.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("(Properties may depend upon connector state.)\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan } else if (rv != 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_options(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan free(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * cmd_changestate()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Subcommand to initiate a state change operation. This is
269473047d747f7815af570197e4ef7322d3632cEvan Yan * a hidden subcommand to directly set a connector or port to
269473047d747f7815af570197e4ef7322d3632cEvan Yan * a specific target state.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yancmd_changestate(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t root;
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t results = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *path = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *connection = NULL;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int state = -1;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int opt, rv;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Parse command line options */
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_common(argc, argv, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "fqs:", changestate_opts,
269473047d747f7815af570197e4ef7322d3632cEvan Yan NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'f':
269473047d747f7815af570197e4ef7322d3632cEvan Yan flags |= HPFORCE;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'q':
269473047d747f7815af570197e4ef7322d3632cEvan Yan flags |= HPQUERY;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 's':
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((state = state_atoi(optarg)) == -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("ERROR: invalid target state\n");
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan bad_option(opt, optopt, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan parse_target(argc, argv, &path, &connection, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* State, path, and connection are all required */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((state == -1) || (path == NULL) || (connection == NULL)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Check that target state is valid */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (valid_target(state) == 0) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid target state\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Get hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((root = hp_init(path, connection, 0)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (errno);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Initiate state change operation on root of snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan rv = hp_set_state(root, flags, state, &results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Display results */
269473047d747f7815af570197e4ef7322d3632cEvan Yan print_error(rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (results) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) hp_traverse(results, NULL, error_cb);
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(results);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Discard hotplug information snapshot */
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_fini(root);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (rv);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * parse_common()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Parse command line options that are common to the
269473047d747f7815af570197e4ef7322d3632cEvan Yan * entire program, and to each of its subcommands.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanparse_common(int argc, char *argv[], const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int opt;
269473047d747f7815af570197e4ef7322d3632cEvan Yan extern int opterr;
269473047d747f7815af570197e4ef7322d3632cEvan Yan extern int optind;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Turn off error reporting */
269473047d747f7815af570197e4ef7322d3632cEvan Yan opterr = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "?V", common_opts, NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case '?':
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (optopt == '?') {
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'V':
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(gettext("%s: Version %s\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog, version);
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Reset option index */
269473047d747f7815af570197e4ef7322d3632cEvan Yan optind = 1;
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * parse_flags()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Parse command line flags common to all downward state
269473047d747f7815af570197e4ef7322d3632cEvan Yan * change operations (offline, disable, poweoff).
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanparse_flags(int argc, char *argv[], int *flagsp, const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int opt;
269473047d747f7815af570197e4ef7322d3632cEvan Yan int flags = 0;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "fq", flag_opts, NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'f':
269473047d747f7815af570197e4ef7322d3632cEvan Yan flags |= HPFORCE;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'q':
269473047d747f7815af570197e4ef7322d3632cEvan Yan flags |= HPQUERY;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan bad_option(opt, optopt, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan *flagsp = flags;
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * parse_options()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Parse command line options common to the bus private set and
269473047d747f7815af570197e4ef7322d3632cEvan Yan * get subcommands.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanparse_options(int argc, char *argv[], char **optionsp, const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int opt;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan while ((opt = getopt_clip(argc, argv, "o:", private_opts,
269473047d747f7815af570197e4ef7322d3632cEvan Yan NULL)) != -1) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 'o':
269473047d747f7815af570197e4ef7322d3632cEvan Yan *optionsp = optarg;
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan bad_option(opt, optopt, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * parse_target()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Parse the target path and connection name from the command line.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanparse_target(int argc, char *argv[], char **pathp, char **connectionp,
269473047d747f7815af570197e4ef7322d3632cEvan Yan const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan extern int optind;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (optind < argc)
269473047d747f7815af570197e4ef7322d3632cEvan Yan *pathp = argv[optind++];
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (optind < argc)
269473047d747f7815af570197e4ef7322d3632cEvan Yan *connectionp = argv[optind++];
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (optind < argc) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: too many arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * bad_option()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Routine to handle bad command line options.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanbad_option(int opt, int optopt, const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (opt) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ':':
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: option '%c' requires an argument.\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan optopt);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (optopt == '?') {
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(EXIT_OK);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: unrecognized option '%c'.\n"), optopt);
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan usage(usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan exit(EXIT_EINVAL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * usage()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Display general usage of the command. Including
269473047d747f7815af570197e4ef7322d3632cEvan Yan * the usage synopsis of each defined subcommand.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanusage(const char *usage_str)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int i;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (usage_str != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("Usage: %s %s\n\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog, usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("Usage: %s <subcommand> [<args>]\n\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan prog);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("Subcommands:\n\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; i < (sizeof (subcmds) / sizeof (subcmd_t)); i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, " %s\n\n", subcmds[i].usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * list_cb()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Callback function for hp_traverse(), to display nodes
269473047d747f7815af570197e4ef7322d3632cEvan Yan * of a hotplug information snapshot. (Short version.)
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yanlist_cb(hp_node_t node, void *arg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t parent;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Indent */
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (parent = hp_parent(node); parent; parent = hp_parent(parent))
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(parent) == HP_NODE_DEVICE)
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" ");
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (hp_type(node)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_DEVICE:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("%s\n", hp_name(node));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_CONNECTOR:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("[%s]", hp_name(node));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" (%s)", state_itoa(hp_state(node)));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("\n");
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_PORT:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("<%s>", hp_name(node));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" (%s)", state_itoa(hp_state(node)));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("\n");
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_USAGE:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("{ %s }\n", hp_usage(node));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (HP_WALK_CONTINUE);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * list_long_cb()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Callback function for hp_traverse(), to display nodes
269473047d747f7815af570197e4ef7322d3632cEvan Yan * of a hotplug information snapshot. (Long version.)
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yanlist_long_cb(hp_node_t node, void *arg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan char path[MAXPATHLEN];
269473047d747f7815af570197e4ef7322d3632cEvan Yan char connection[MAXPATHLEN];
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_type(node) != HP_NODE_USAGE) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_path(node, path, connection) != 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (HP_WALK_CONTINUE);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("%s", path);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (hp_type(node)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_CONNECTOR:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" [%s]", connection);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" (%s)", state_itoa(hp_state(node)));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_PORT:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" <%s>", connection);
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" (%s)", state_itoa(hp_state(node)));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan case HP_NODE_USAGE:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" { %s }", hp_usage(node));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("\n");
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (HP_WALK_CONTINUE);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * error_cb()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Callback function for hp_traverse(), to display
269473047d747f7815af570197e4ef7322d3632cEvan Yan * error results from a state change operation.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*ARGSUSED*/
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yanerror_cb(hp_node_t node, void *arg)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan hp_node_t child;
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *usage_str;
269473047d747f7815af570197e4ef7322d3632cEvan Yan static char path[MAXPATHLEN];
269473047d747f7815af570197e4ef7322d3632cEvan Yan static char connection[MAXPATHLEN];
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (((child = hp_child(node)) != NULL) &&
269473047d747f7815af570197e4ef7322d3632cEvan Yan (hp_type(child) == HP_NODE_USAGE)) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (hp_path(node, path, connection) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("%s:\n", path);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (HP_WALK_CONTINUE);
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((hp_type(node) == HP_NODE_USAGE) &&
269473047d747f7815af570197e4ef7322d3632cEvan Yan ((usage_str = hp_usage(node)) != NULL))
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf(" { %s }\n", usage_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (HP_WALK_CONTINUE);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * print_options()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Parse and display bus private options. The options are
269473047d747f7815af570197e4ef7322d3632cEvan Yan * formatted as a string which conforms to the getsubopt(3C)
269473047d747f7815af570197e4ef7322d3632cEvan Yan * format. This routine only splits the string elements as
269473047d747f7815af570197e4ef7322d3632cEvan Yan * separated by commas, and displays each portion on its own
269473047d747f7815af570197e4ef7322d3632cEvan Yan * separate line of output.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanprint_options(const char *options)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan char *buf, *curr, *next;
269473047d747f7815af570197e4ef7322d3632cEvan Yan size_t len;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Do nothing if options string is empty */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((len = strlen(options)) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan return;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* To avoid modifying the input string, make a copy on the stack */
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((buf = (char *)alloca(len + 1)) == NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("%s\n", options);
269473047d747f7815af570197e4ef7322d3632cEvan Yan return;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) strlcpy(buf, options, len + 1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* Iterate through each comma-separated name/value pair */
269473047d747f7815af570197e4ef7322d3632cEvan Yan curr = buf;
269473047d747f7815af570197e4ef7322d3632cEvan Yan do {
269473047d747f7815af570197e4ef7322d3632cEvan Yan if ((next = strchr(curr, ',')) != NULL) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan *next = '\0';
269473047d747f7815af570197e4ef7322d3632cEvan Yan next++;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) printf("%s\n", curr);
269473047d747f7815af570197e4ef7322d3632cEvan Yan } while ((curr = next) != NULL);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * print_error()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Common routine to print error numbers in an appropriate way.
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Prints nothing if error code is 0.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic void
269473047d747f7815af570197e4ef7322d3632cEvan Yanprint_error(int error)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan switch (error) {
269473047d747f7815af570197e4ef7322d3632cEvan Yan case 0:
269473047d747f7815af570197e4ef7322d3632cEvan Yan /* No error */
269473047d747f7815af570197e4ef7322d3632cEvan Yan return;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EACCES:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: operation not authorized.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EBADF:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: hotplug service is not available.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EBUSY:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: devices or resources are busy.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EEXIST:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: resource already exists.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EFAULT:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: internal failure in hotplug service.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EINVAL:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: invalid arguments.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENOENT:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: there are no connections to display.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("(See hotplug(1m) for more information.)\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENXIO:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: no such path or connection.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENOMEM:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: not enough memory.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case ENOTSUP:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: operation not supported.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan case EIO:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr,
269473047d747f7815af570197e4ef7322d3632cEvan Yan gettext("ERROR: hardware or driver specific failure.\n"));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan default:
269473047d747f7815af570197e4ef7322d3632cEvan Yan (void) fprintf(stderr, gettext("ERROR: operation failed: %s\n"),
269473047d747f7815af570197e4ef7322d3632cEvan Yan strerror(error));
269473047d747f7815af570197e4ef7322d3632cEvan Yan break;
269473047d747f7815af570197e4ef7322d3632cEvan Yan }
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * state_atoi()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Convert a hotplug state from a string to an integer.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic int
269473047d747f7815af570197e4ef7322d3632cEvan Yanstate_atoi(char *state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int i;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; hpstates[i].state_str != NULL; i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (strcasecmp(state, hpstates[i].state_str) == 0)
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (hpstates[i].state);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (-1);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * state_itoa()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Convert a hotplug state from an integer to a string.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic char *
269473047d747f7815af570197e4ef7322d3632cEvan Yanstate_itoa(int state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan static char unknown[] = "UNKNOWN";
269473047d747f7815af570197e4ef7322d3632cEvan Yan int i;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; hpstates[i].state_str != NULL; i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (state == hpstates[i].state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (hpstates[i].state_str);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (unknown);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan/*
269473047d747f7815af570197e4ef7322d3632cEvan Yan * valid_target()
269473047d747f7815af570197e4ef7322d3632cEvan Yan *
269473047d747f7815af570197e4ef7322d3632cEvan Yan * Check if a state is a valid target for a changestate command.
269473047d747f7815af570197e4ef7322d3632cEvan Yan */
269473047d747f7815af570197e4ef7322d3632cEvan Yanstatic short
269473047d747f7815af570197e4ef7322d3632cEvan Yanvalid_target(int state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan{
269473047d747f7815af570197e4ef7322d3632cEvan Yan int i;
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan for (i = 0; hpstates[i].state_str != NULL; i++)
269473047d747f7815af570197e4ef7322d3632cEvan Yan if (state == hpstates[i].state)
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (hpstates[i].valid_target);
269473047d747f7815af570197e4ef7322d3632cEvan Yan
269473047d747f7815af570197e4ef7322d3632cEvan Yan return (0);
269473047d747f7815af570197e4ef7322d3632cEvan Yan}