1*10923SEvan.Yan@Sun.COM /*
2*10923SEvan.Yan@Sun.COM * CDDL HEADER START
3*10923SEvan.Yan@Sun.COM *
4*10923SEvan.Yan@Sun.COM * The contents of this file are subject to the terms of the
5*10923SEvan.Yan@Sun.COM * Common Development and Distribution License (the "License").
6*10923SEvan.Yan@Sun.COM * You may not use this file except in compliance with the License.
7*10923SEvan.Yan@Sun.COM *
8*10923SEvan.Yan@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10923SEvan.Yan@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10923SEvan.Yan@Sun.COM * See the License for the specific language governing permissions
11*10923SEvan.Yan@Sun.COM * and limitations under the License.
12*10923SEvan.Yan@Sun.COM *
13*10923SEvan.Yan@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10923SEvan.Yan@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10923SEvan.Yan@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10923SEvan.Yan@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10923SEvan.Yan@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10923SEvan.Yan@Sun.COM *
19*10923SEvan.Yan@Sun.COM * CDDL HEADER END
20*10923SEvan.Yan@Sun.COM */
21*10923SEvan.Yan@Sun.COM /*
22*10923SEvan.Yan@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23*10923SEvan.Yan@Sun.COM * Use is subject to license terms.
24*10923SEvan.Yan@Sun.COM */
25*10923SEvan.Yan@Sun.COM
26*10923SEvan.Yan@Sun.COM #include <stdio.h>
27*10923SEvan.Yan@Sun.COM #include <stdlib.h>
28*10923SEvan.Yan@Sun.COM #include <string.h>
29*10923SEvan.Yan@Sun.COM #include <locale.h>
30*10923SEvan.Yan@Sun.COM #include <libintl.h>
31*10923SEvan.Yan@Sun.COM #include <alloca.h>
32*10923SEvan.Yan@Sun.COM #include <getopt.h>
33*10923SEvan.Yan@Sun.COM #include <libhotplug.h>
34*10923SEvan.Yan@Sun.COM #include <sys/types.h>
35*10923SEvan.Yan@Sun.COM #include <sys/sunddi.h>
36*10923SEvan.Yan@Sun.COM #include <sys/ddi_hp.h>
37*10923SEvan.Yan@Sun.COM
38*10923SEvan.Yan@Sun.COM #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
39*10923SEvan.Yan@Sun.COM #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
40*10923SEvan.Yan@Sun.COM #endif
41*10923SEvan.Yan@Sun.COM
42*10923SEvan.Yan@Sun.COM /*
43*10923SEvan.Yan@Sun.COM * Function prototypes.
44*10923SEvan.Yan@Sun.COM */
45*10923SEvan.Yan@Sun.COM static int cmd_list(int, char **, const char *);
46*10923SEvan.Yan@Sun.COM static int cmd_online(int, char **, const char *);
47*10923SEvan.Yan@Sun.COM static int cmd_offline(int, char **, const char *);
48*10923SEvan.Yan@Sun.COM static int cmd_enable(int, char **, const char *);
49*10923SEvan.Yan@Sun.COM static int cmd_disable(int, char **, const char *);
50*10923SEvan.Yan@Sun.COM static int cmd_poweron(int, char **, const char *);
51*10923SEvan.Yan@Sun.COM static int cmd_poweroff(int, char **, const char *);
52*10923SEvan.Yan@Sun.COM static int cmd_getpriv(int, char **, const char *);
53*10923SEvan.Yan@Sun.COM static int cmd_setpriv(int, char **, const char *);
54*10923SEvan.Yan@Sun.COM static int cmd_changestate(int, char **, const char *);
55*10923SEvan.Yan@Sun.COM static void parse_common(int, char **, const char *);
56*10923SEvan.Yan@Sun.COM static void parse_flags(int, char **, int *, const char *);
57*10923SEvan.Yan@Sun.COM static void parse_target(int, char **, char **, char **, const char *);
58*10923SEvan.Yan@Sun.COM static void parse_options(int, char **, char **, const char *);
59*10923SEvan.Yan@Sun.COM static void bad_option(int, int, const char *);
60*10923SEvan.Yan@Sun.COM static void usage(const char *);
61*10923SEvan.Yan@Sun.COM static int list_cb(hp_node_t, void *);
62*10923SEvan.Yan@Sun.COM static int list_long_cb(hp_node_t, void *);
63*10923SEvan.Yan@Sun.COM static int error_cb(hp_node_t, void *);
64*10923SEvan.Yan@Sun.COM static void print_options(const char *);
65*10923SEvan.Yan@Sun.COM static void print_error(int);
66*10923SEvan.Yan@Sun.COM static int state_atoi(char *);
67*10923SEvan.Yan@Sun.COM static char *state_itoa(int);
68*10923SEvan.Yan@Sun.COM static short valid_target(int);
69*10923SEvan.Yan@Sun.COM
70*10923SEvan.Yan@Sun.COM /*
71*10923SEvan.Yan@Sun.COM * Define a conversion table for hotplug states.
72*10923SEvan.Yan@Sun.COM */
73*10923SEvan.Yan@Sun.COM typedef struct {
74*10923SEvan.Yan@Sun.COM int state;
75*10923SEvan.Yan@Sun.COM char *state_str;
76*10923SEvan.Yan@Sun.COM short valid_target;
77*10923SEvan.Yan@Sun.COM } hpstate_t;
78*10923SEvan.Yan@Sun.COM
79*10923SEvan.Yan@Sun.COM static hpstate_t hpstates[] = {
80*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_EMPTY, "EMPTY", 0 },
81*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_PRESENT, "PRESENT", 1 },
82*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_POWERED, "POWERED", 1 },
83*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_ENABLED, "ENABLED", 1 },
84*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_PORT_EMPTY, "PORT-EMPTY", 0 },
85*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_PORT_PRESENT, "PORT-PRESENT", 1 },
86*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_OFFLINE, "OFFLINE", 1 },
87*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_ATTACHED, "ATTACHED", 0 },
88*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_MAINTENANCE, "MAINTENANCE", 0 },
89*10923SEvan.Yan@Sun.COM { DDI_HP_CN_STATE_ONLINE, "ONLINE", 1 },
90*10923SEvan.Yan@Sun.COM { 0, 0, 0 }
91*10923SEvan.Yan@Sun.COM };
92*10923SEvan.Yan@Sun.COM
93*10923SEvan.Yan@Sun.COM /*
94*10923SEvan.Yan@Sun.COM * Define tables of supported subcommands.
95*10923SEvan.Yan@Sun.COM */
96*10923SEvan.Yan@Sun.COM typedef struct {
97*10923SEvan.Yan@Sun.COM char *usage_str;
98*10923SEvan.Yan@Sun.COM char *cmd_str;
99*10923SEvan.Yan@Sun.COM int (*func)(int argc, char *argv[], const char *usage_str);
100*10923SEvan.Yan@Sun.COM } subcmd_t;
101*10923SEvan.Yan@Sun.COM
102*10923SEvan.Yan@Sun.COM static subcmd_t subcmds[] = {
103*10923SEvan.Yan@Sun.COM { "list [-l] [-v] [<path> [<connection>]]", "list", cmd_list },
104*10923SEvan.Yan@Sun.COM { "online <path> <port>", "online", cmd_online },
105*10923SEvan.Yan@Sun.COM { "offline [-f] [-q] <path> <port>", "offline", cmd_offline },
106*10923SEvan.Yan@Sun.COM { "enable <path> <connector>", "enable", cmd_enable },
107*10923SEvan.Yan@Sun.COM { "disable [-f] [-q] <path> <connector>", "disable", cmd_disable },
108*10923SEvan.Yan@Sun.COM { "poweron <path> <connector>", "poweron", cmd_poweron },
109*10923SEvan.Yan@Sun.COM { "poweroff [-f] [-q] <path> <connector>", "poweroff", cmd_poweroff },
110*10923SEvan.Yan@Sun.COM { "get -o <options> <path> <connector>", "get", cmd_getpriv },
111*10923SEvan.Yan@Sun.COM { "set -o <options> <path> <connector>", "set", cmd_setpriv }
112*10923SEvan.Yan@Sun.COM };
113*10923SEvan.Yan@Sun.COM
114*10923SEvan.Yan@Sun.COM static subcmd_t hidden_subcmds[] = {
115*10923SEvan.Yan@Sun.COM { "changestate [-f] [-q] -s <state> <path> <connection>",
116*10923SEvan.Yan@Sun.COM "changestate", cmd_changestate }
117*10923SEvan.Yan@Sun.COM };
118*10923SEvan.Yan@Sun.COM
119*10923SEvan.Yan@Sun.COM /*
120*10923SEvan.Yan@Sun.COM * Define tables of command line options.
121*10923SEvan.Yan@Sun.COM */
122*10923SEvan.Yan@Sun.COM static const struct option common_opts[] = {
123*10923SEvan.Yan@Sun.COM { "help", no_argument, 0, '?' },
124*10923SEvan.Yan@Sun.COM { "version", no_argument, 0, 'V' },
125*10923SEvan.Yan@Sun.COM { 0, 0, 0, 0 }
126*10923SEvan.Yan@Sun.COM };
127*10923SEvan.Yan@Sun.COM
128*10923SEvan.Yan@Sun.COM static const struct option list_opts[] = {
129*10923SEvan.Yan@Sun.COM { "list-path", no_argument, 0, 'l' },
130*10923SEvan.Yan@Sun.COM { "verbose", no_argument, 0, 'v' },
131*10923SEvan.Yan@Sun.COM { 0, 0, 0, 0 }
132*10923SEvan.Yan@Sun.COM };
133*10923SEvan.Yan@Sun.COM
134*10923SEvan.Yan@Sun.COM static const struct option flag_opts[] = {
135*10923SEvan.Yan@Sun.COM { "force", no_argument, 0, 'f' },
136*10923SEvan.Yan@Sun.COM { "query", no_argument, 0, 'q' },
137*10923SEvan.Yan@Sun.COM { 0, 0, 0, 0 }
138*10923SEvan.Yan@Sun.COM };
139*10923SEvan.Yan@Sun.COM
140*10923SEvan.Yan@Sun.COM static const struct option private_opts[] = {
141*10923SEvan.Yan@Sun.COM { "options", required_argument, 0, 'o' },
142*10923SEvan.Yan@Sun.COM { 0, 0, 0, 0 }
143*10923SEvan.Yan@Sun.COM };
144*10923SEvan.Yan@Sun.COM
145*10923SEvan.Yan@Sun.COM static const struct option changestate_opts[] = {
146*10923SEvan.Yan@Sun.COM { "force", no_argument, 0, 'f' },
147*10923SEvan.Yan@Sun.COM { "query", no_argument, 0, 'q' },
148*10923SEvan.Yan@Sun.COM { "state", required_argument, 0, 's' },
149*10923SEvan.Yan@Sun.COM { 0, 0, 0, 0 }
150*10923SEvan.Yan@Sun.COM };
151*10923SEvan.Yan@Sun.COM
152*10923SEvan.Yan@Sun.COM /*
153*10923SEvan.Yan@Sun.COM * Define exit codes.
154*10923SEvan.Yan@Sun.COM */
155*10923SEvan.Yan@Sun.COM #define EXIT_OK 0
156*10923SEvan.Yan@Sun.COM #define EXIT_EINVAL 1 /* invalid arguments */
157*10923SEvan.Yan@Sun.COM #define EXIT_ENOENT 2 /* path or connection doesn't exist */
158*10923SEvan.Yan@Sun.COM #define EXIT_FAILED 3 /* operation failed */
159*10923SEvan.Yan@Sun.COM #define EXIT_UNAVAIL 4 /* service not available */
160*10923SEvan.Yan@Sun.COM
161*10923SEvan.Yan@Sun.COM /*
162*10923SEvan.Yan@Sun.COM * Global variables.
163*10923SEvan.Yan@Sun.COM */
164*10923SEvan.Yan@Sun.COM static char *prog;
165*10923SEvan.Yan@Sun.COM static char version[] = "1.0";
166*10923SEvan.Yan@Sun.COM extern int errno;
167*10923SEvan.Yan@Sun.COM
168*10923SEvan.Yan@Sun.COM /*
169*10923SEvan.Yan@Sun.COM * main()
170*10923SEvan.Yan@Sun.COM *
171*10923SEvan.Yan@Sun.COM * The main routine determines which subcommand is used,
172*10923SEvan.Yan@Sun.COM * and dispatches control to the corresponding function.
173*10923SEvan.Yan@Sun.COM */
174*10923SEvan.Yan@Sun.COM int
main(int argc,char * argv[])175*10923SEvan.Yan@Sun.COM main(int argc, char *argv[])
176*10923SEvan.Yan@Sun.COM {
177*10923SEvan.Yan@Sun.COM int i, rv;
178*10923SEvan.Yan@Sun.COM
179*10923SEvan.Yan@Sun.COM (void) setlocale(LC_ALL, "");
180*10923SEvan.Yan@Sun.COM (void) textdomain(TEXT_DOMAIN);
181*10923SEvan.Yan@Sun.COM
182*10923SEvan.Yan@Sun.COM if ((prog = strrchr(argv[0], '/')) == NULL)
183*10923SEvan.Yan@Sun.COM prog = argv[0];
184*10923SEvan.Yan@Sun.COM else
185*10923SEvan.Yan@Sun.COM prog++;
186*10923SEvan.Yan@Sun.COM
187*10923SEvan.Yan@Sun.COM if (argc < 2) {
188*10923SEvan.Yan@Sun.COM usage(NULL);
189*10923SEvan.Yan@Sun.COM return (EXIT_EINVAL);
190*10923SEvan.Yan@Sun.COM }
191*10923SEvan.Yan@Sun.COM
192*10923SEvan.Yan@Sun.COM parse_common(argc, argv, NULL);
193*10923SEvan.Yan@Sun.COM
194*10923SEvan.Yan@Sun.COM /* Check the list of defined subcommands. */
195*10923SEvan.Yan@Sun.COM for (i = 0; i < (sizeof (subcmds) / sizeof (subcmd_t)); i++) {
196*10923SEvan.Yan@Sun.COM if (strcmp(argv[1], subcmds[i].cmd_str) == 0) {
197*10923SEvan.Yan@Sun.COM rv = subcmds[i].func(argc - 1, &argv[1],
198*10923SEvan.Yan@Sun.COM subcmds[i].usage_str);
199*10923SEvan.Yan@Sun.COM goto finished;
200*10923SEvan.Yan@Sun.COM }
201*10923SEvan.Yan@Sun.COM }
202*10923SEvan.Yan@Sun.COM
203*10923SEvan.Yan@Sun.COM /* Check the list of hidden subcommands. */
204*10923SEvan.Yan@Sun.COM for (i = 0; i < (sizeof (hidden_subcmds) / sizeof (subcmd_t)); i++) {
205*10923SEvan.Yan@Sun.COM if (strcmp(argv[1], hidden_subcmds[i].cmd_str) == 0) {
206*10923SEvan.Yan@Sun.COM rv = hidden_subcmds[i].func(argc - 1, &argv[1],
207*10923SEvan.Yan@Sun.COM hidden_subcmds[i].usage_str);
208*10923SEvan.Yan@Sun.COM goto finished;
209*10923SEvan.Yan@Sun.COM }
210*10923SEvan.Yan@Sun.COM }
211*10923SEvan.Yan@Sun.COM
212*10923SEvan.Yan@Sun.COM /* No matching subcommand found. */
213*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: %s: unknown subcommand '%s'\n"),
214*10923SEvan.Yan@Sun.COM prog, argv[1]);
215*10923SEvan.Yan@Sun.COM usage(NULL);
216*10923SEvan.Yan@Sun.COM exit(EXIT_EINVAL);
217*10923SEvan.Yan@Sun.COM
218*10923SEvan.Yan@Sun.COM finished:
219*10923SEvan.Yan@Sun.COM /* Determine exit code */
220*10923SEvan.Yan@Sun.COM switch (rv) {
221*10923SEvan.Yan@Sun.COM case 0:
222*10923SEvan.Yan@Sun.COM break;
223*10923SEvan.Yan@Sun.COM case EINVAL:
224*10923SEvan.Yan@Sun.COM return (EXIT_EINVAL);
225*10923SEvan.Yan@Sun.COM case ENXIO:
226*10923SEvan.Yan@Sun.COM case ENOENT:
227*10923SEvan.Yan@Sun.COM return (EXIT_ENOENT);
228*10923SEvan.Yan@Sun.COM case EBADF:
229*10923SEvan.Yan@Sun.COM return (EXIT_UNAVAIL);
230*10923SEvan.Yan@Sun.COM default:
231*10923SEvan.Yan@Sun.COM return (EXIT_FAILED);
232*10923SEvan.Yan@Sun.COM }
233*10923SEvan.Yan@Sun.COM
234*10923SEvan.Yan@Sun.COM return (EXIT_OK);
235*10923SEvan.Yan@Sun.COM }
236*10923SEvan.Yan@Sun.COM
237*10923SEvan.Yan@Sun.COM /*
238*10923SEvan.Yan@Sun.COM * cmd_list()
239*10923SEvan.Yan@Sun.COM *
240*10923SEvan.Yan@Sun.COM * Subcommand to list hotplug information.
241*10923SEvan.Yan@Sun.COM */
242*10923SEvan.Yan@Sun.COM static int
cmd_list(int argc,char * argv[],const char * usage_str)243*10923SEvan.Yan@Sun.COM cmd_list(int argc, char *argv[], const char *usage_str)
244*10923SEvan.Yan@Sun.COM {
245*10923SEvan.Yan@Sun.COM hp_node_t root;
246*10923SEvan.Yan@Sun.COM char *path = NULL;
247*10923SEvan.Yan@Sun.COM char *connection = NULL;
248*10923SEvan.Yan@Sun.COM boolean_t long_flag = B_FALSE;
249*10923SEvan.Yan@Sun.COM int flags = 0;
250*10923SEvan.Yan@Sun.COM int opt;
251*10923SEvan.Yan@Sun.COM
252*10923SEvan.Yan@Sun.COM /* Parse command line options */
253*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
254*10923SEvan.Yan@Sun.COM while ((opt = getopt_clip(argc, argv, "lv", list_opts, NULL)) != -1) {
255*10923SEvan.Yan@Sun.COM switch (opt) {
256*10923SEvan.Yan@Sun.COM case 'l':
257*10923SEvan.Yan@Sun.COM long_flag = B_TRUE;
258*10923SEvan.Yan@Sun.COM break;
259*10923SEvan.Yan@Sun.COM case 'v':
260*10923SEvan.Yan@Sun.COM flags |= HPINFOUSAGE;
261*10923SEvan.Yan@Sun.COM break;
262*10923SEvan.Yan@Sun.COM default:
263*10923SEvan.Yan@Sun.COM bad_option(opt, optopt, usage_str);
264*10923SEvan.Yan@Sun.COM break;
265*10923SEvan.Yan@Sun.COM }
266*10923SEvan.Yan@Sun.COM }
267*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
268*10923SEvan.Yan@Sun.COM
269*10923SEvan.Yan@Sun.COM /* Default path is "/" */
270*10923SEvan.Yan@Sun.COM if (path == NULL)
271*10923SEvan.Yan@Sun.COM path = "/";
272*10923SEvan.Yan@Sun.COM
273*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
274*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, flags)) == NULL) {
275*10923SEvan.Yan@Sun.COM print_error(errno);
276*10923SEvan.Yan@Sun.COM return (errno);
277*10923SEvan.Yan@Sun.COM }
278*10923SEvan.Yan@Sun.COM
279*10923SEvan.Yan@Sun.COM /* Display hotplug information */
280*10923SEvan.Yan@Sun.COM (void) hp_traverse(root, NULL, long_flag ? list_long_cb : list_cb);
281*10923SEvan.Yan@Sun.COM
282*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
283*10923SEvan.Yan@Sun.COM hp_fini(root);
284*10923SEvan.Yan@Sun.COM
285*10923SEvan.Yan@Sun.COM return (0);
286*10923SEvan.Yan@Sun.COM }
287*10923SEvan.Yan@Sun.COM
288*10923SEvan.Yan@Sun.COM /*
289*10923SEvan.Yan@Sun.COM * cmd_online()
290*10923SEvan.Yan@Sun.COM *
291*10923SEvan.Yan@Sun.COM * Subcommand to online a hotplug port.
292*10923SEvan.Yan@Sun.COM */
293*10923SEvan.Yan@Sun.COM static int
cmd_online(int argc,char * argv[],const char * usage_str)294*10923SEvan.Yan@Sun.COM cmd_online(int argc, char *argv[], const char *usage_str)
295*10923SEvan.Yan@Sun.COM {
296*10923SEvan.Yan@Sun.COM hp_node_t root;
297*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
298*10923SEvan.Yan@Sun.COM char *path = NULL;
299*10923SEvan.Yan@Sun.COM char *connection = NULL;
300*10923SEvan.Yan@Sun.COM int rv;
301*10923SEvan.Yan@Sun.COM
302*10923SEvan.Yan@Sun.COM /* Parse command line options */
303*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
304*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
305*10923SEvan.Yan@Sun.COM
306*10923SEvan.Yan@Sun.COM /* Path and connection are required */
307*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
308*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
309*10923SEvan.Yan@Sun.COM usage(usage_str);
310*10923SEvan.Yan@Sun.COM return (EINVAL);
311*10923SEvan.Yan@Sun.COM }
312*10923SEvan.Yan@Sun.COM
313*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
314*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
315*10923SEvan.Yan@Sun.COM print_error(errno);
316*10923SEvan.Yan@Sun.COM return (errno);
317*10923SEvan.Yan@Sun.COM }
318*10923SEvan.Yan@Sun.COM
319*10923SEvan.Yan@Sun.COM /* Verify target is a port */
320*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_PORT) {
321*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
322*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a port).\n"));
323*10923SEvan.Yan@Sun.COM hp_fini(root);
324*10923SEvan.Yan@Sun.COM return (EINVAL);
325*10923SEvan.Yan@Sun.COM }
326*10923SEvan.Yan@Sun.COM
327*10923SEvan.Yan@Sun.COM /* Do state change */
328*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, 0, DDI_HP_CN_STATE_ONLINE, &results);
329*10923SEvan.Yan@Sun.COM
330*10923SEvan.Yan@Sun.COM /* Display results */
331*10923SEvan.Yan@Sun.COM if (rv == EIO) {
332*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: failed to attach device "
333*10923SEvan.Yan@Sun.COM "drivers or other internal errors.\n"));
334*10923SEvan.Yan@Sun.COM } else if (rv != 0) {
335*10923SEvan.Yan@Sun.COM print_error(rv);
336*10923SEvan.Yan@Sun.COM }
337*10923SEvan.Yan@Sun.COM if (results != NULL) {
338*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
339*10923SEvan.Yan@Sun.COM hp_fini(results);
340*10923SEvan.Yan@Sun.COM }
341*10923SEvan.Yan@Sun.COM
342*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
343*10923SEvan.Yan@Sun.COM hp_fini(root);
344*10923SEvan.Yan@Sun.COM
345*10923SEvan.Yan@Sun.COM return (rv);
346*10923SEvan.Yan@Sun.COM }
347*10923SEvan.Yan@Sun.COM
348*10923SEvan.Yan@Sun.COM /*
349*10923SEvan.Yan@Sun.COM * cmd_offline()
350*10923SEvan.Yan@Sun.COM *
351*10923SEvan.Yan@Sun.COM * Subcommand to offline a hotplug port.
352*10923SEvan.Yan@Sun.COM */
353*10923SEvan.Yan@Sun.COM static int
cmd_offline(int argc,char * argv[],const char * usage_str)354*10923SEvan.Yan@Sun.COM cmd_offline(int argc, char *argv[], const char *usage_str)
355*10923SEvan.Yan@Sun.COM {
356*10923SEvan.Yan@Sun.COM hp_node_t root;
357*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
358*10923SEvan.Yan@Sun.COM char *path = NULL;
359*10923SEvan.Yan@Sun.COM char *connection = NULL;
360*10923SEvan.Yan@Sun.COM int flags = 0;
361*10923SEvan.Yan@Sun.COM int rv;
362*10923SEvan.Yan@Sun.COM
363*10923SEvan.Yan@Sun.COM /* Parse command line options */
364*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
365*10923SEvan.Yan@Sun.COM parse_flags(argc, argv, &flags, usage_str);
366*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
367*10923SEvan.Yan@Sun.COM
368*10923SEvan.Yan@Sun.COM /* Path and connection are required */
369*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
370*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
371*10923SEvan.Yan@Sun.COM usage(usage_str);
372*10923SEvan.Yan@Sun.COM return (EINVAL);
373*10923SEvan.Yan@Sun.COM }
374*10923SEvan.Yan@Sun.COM
375*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
376*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
377*10923SEvan.Yan@Sun.COM print_error(errno);
378*10923SEvan.Yan@Sun.COM return (errno);
379*10923SEvan.Yan@Sun.COM }
380*10923SEvan.Yan@Sun.COM
381*10923SEvan.Yan@Sun.COM /* Verify target is a port */
382*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_PORT) {
383*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
384*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a port).\n"));
385*10923SEvan.Yan@Sun.COM hp_fini(root);
386*10923SEvan.Yan@Sun.COM return (EINVAL);
387*10923SEvan.Yan@Sun.COM }
388*10923SEvan.Yan@Sun.COM
389*10923SEvan.Yan@Sun.COM /* Do state change */
390*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, flags, DDI_HP_CN_STATE_OFFLINE, &results);
391*10923SEvan.Yan@Sun.COM
392*10923SEvan.Yan@Sun.COM /* Display results */
393*10923SEvan.Yan@Sun.COM print_error(rv);
394*10923SEvan.Yan@Sun.COM if (results != NULL) {
395*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
396*10923SEvan.Yan@Sun.COM hp_fini(results);
397*10923SEvan.Yan@Sun.COM }
398*10923SEvan.Yan@Sun.COM
399*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
400*10923SEvan.Yan@Sun.COM hp_fini(root);
401*10923SEvan.Yan@Sun.COM
402*10923SEvan.Yan@Sun.COM return (rv);
403*10923SEvan.Yan@Sun.COM }
404*10923SEvan.Yan@Sun.COM
405*10923SEvan.Yan@Sun.COM /*
406*10923SEvan.Yan@Sun.COM * cmd_enable()
407*10923SEvan.Yan@Sun.COM *
408*10923SEvan.Yan@Sun.COM * Subcommand to enable a hotplug connector.
409*10923SEvan.Yan@Sun.COM */
410*10923SEvan.Yan@Sun.COM static int
cmd_enable(int argc,char * argv[],const char * usage_str)411*10923SEvan.Yan@Sun.COM cmd_enable(int argc, char *argv[], const char *usage_str)
412*10923SEvan.Yan@Sun.COM {
413*10923SEvan.Yan@Sun.COM hp_node_t root;
414*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
415*10923SEvan.Yan@Sun.COM char *path = NULL;
416*10923SEvan.Yan@Sun.COM char *connection = NULL;
417*10923SEvan.Yan@Sun.COM int rv;
418*10923SEvan.Yan@Sun.COM
419*10923SEvan.Yan@Sun.COM /* Parse command line options */
420*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
421*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
422*10923SEvan.Yan@Sun.COM
423*10923SEvan.Yan@Sun.COM /* Path and connection are required */
424*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
425*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
426*10923SEvan.Yan@Sun.COM usage(usage_str);
427*10923SEvan.Yan@Sun.COM return (EINVAL);
428*10923SEvan.Yan@Sun.COM }
429*10923SEvan.Yan@Sun.COM
430*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
431*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
432*10923SEvan.Yan@Sun.COM print_error(errno);
433*10923SEvan.Yan@Sun.COM return (errno);
434*10923SEvan.Yan@Sun.COM }
435*10923SEvan.Yan@Sun.COM
436*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
437*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
438*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
439*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
440*10923SEvan.Yan@Sun.COM hp_fini(root);
441*10923SEvan.Yan@Sun.COM return (EINVAL);
442*10923SEvan.Yan@Sun.COM }
443*10923SEvan.Yan@Sun.COM
444*10923SEvan.Yan@Sun.COM /* Do state change */
445*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, 0, DDI_HP_CN_STATE_ENABLED, &results);
446*10923SEvan.Yan@Sun.COM
447*10923SEvan.Yan@Sun.COM /* Display results */
448*10923SEvan.Yan@Sun.COM print_error(rv);
449*10923SEvan.Yan@Sun.COM if (results != NULL) {
450*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
451*10923SEvan.Yan@Sun.COM hp_fini(results);
452*10923SEvan.Yan@Sun.COM }
453*10923SEvan.Yan@Sun.COM
454*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
455*10923SEvan.Yan@Sun.COM hp_fini(root);
456*10923SEvan.Yan@Sun.COM
457*10923SEvan.Yan@Sun.COM return (rv);
458*10923SEvan.Yan@Sun.COM }
459*10923SEvan.Yan@Sun.COM
460*10923SEvan.Yan@Sun.COM /*
461*10923SEvan.Yan@Sun.COM * cmd_disable()
462*10923SEvan.Yan@Sun.COM *
463*10923SEvan.Yan@Sun.COM * Subcommand to disable a hotplug connector.
464*10923SEvan.Yan@Sun.COM */
465*10923SEvan.Yan@Sun.COM static int
cmd_disable(int argc,char * argv[],const char * usage_str)466*10923SEvan.Yan@Sun.COM cmd_disable(int argc, char *argv[], const char *usage_str)
467*10923SEvan.Yan@Sun.COM {
468*10923SEvan.Yan@Sun.COM hp_node_t root;
469*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
470*10923SEvan.Yan@Sun.COM char *path = NULL;
471*10923SEvan.Yan@Sun.COM char *connection = NULL;
472*10923SEvan.Yan@Sun.COM int flags = 0;
473*10923SEvan.Yan@Sun.COM int rv;
474*10923SEvan.Yan@Sun.COM
475*10923SEvan.Yan@Sun.COM /* Parse command line options */
476*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
477*10923SEvan.Yan@Sun.COM parse_flags(argc, argv, &flags, usage_str);
478*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
479*10923SEvan.Yan@Sun.COM
480*10923SEvan.Yan@Sun.COM /* Path and connection are required */
481*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
482*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
483*10923SEvan.Yan@Sun.COM usage(usage_str);
484*10923SEvan.Yan@Sun.COM return (EINVAL);
485*10923SEvan.Yan@Sun.COM }
486*10923SEvan.Yan@Sun.COM
487*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
488*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
489*10923SEvan.Yan@Sun.COM print_error(errno);
490*10923SEvan.Yan@Sun.COM return (errno);
491*10923SEvan.Yan@Sun.COM }
492*10923SEvan.Yan@Sun.COM
493*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
494*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
495*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
496*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
497*10923SEvan.Yan@Sun.COM hp_fini(root);
498*10923SEvan.Yan@Sun.COM return (EINVAL);
499*10923SEvan.Yan@Sun.COM }
500*10923SEvan.Yan@Sun.COM
501*10923SEvan.Yan@Sun.COM /*
502*10923SEvan.Yan@Sun.COM * Do nothing unless the connector is in the ENABLED state.
503*10923SEvan.Yan@Sun.COM * Otherwise this subcommand becomes an alias for 'poweron.'
504*10923SEvan.Yan@Sun.COM */
505*10923SEvan.Yan@Sun.COM if (hp_state(root) != DDI_HP_CN_STATE_ENABLED) {
506*10923SEvan.Yan@Sun.COM hp_fini(root);
507*10923SEvan.Yan@Sun.COM return (0);
508*10923SEvan.Yan@Sun.COM }
509*10923SEvan.Yan@Sun.COM
510*10923SEvan.Yan@Sun.COM /* Do state change */
511*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, flags, DDI_HP_CN_STATE_POWERED, &results);
512*10923SEvan.Yan@Sun.COM
513*10923SEvan.Yan@Sun.COM /* Display results */
514*10923SEvan.Yan@Sun.COM print_error(rv);
515*10923SEvan.Yan@Sun.COM if (results != NULL) {
516*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
517*10923SEvan.Yan@Sun.COM hp_fini(results);
518*10923SEvan.Yan@Sun.COM }
519*10923SEvan.Yan@Sun.COM
520*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
521*10923SEvan.Yan@Sun.COM hp_fini(root);
522*10923SEvan.Yan@Sun.COM
523*10923SEvan.Yan@Sun.COM return (rv);
524*10923SEvan.Yan@Sun.COM }
525*10923SEvan.Yan@Sun.COM
526*10923SEvan.Yan@Sun.COM /*
527*10923SEvan.Yan@Sun.COM * cmd_poweron()
528*10923SEvan.Yan@Sun.COM *
529*10923SEvan.Yan@Sun.COM * Subcommand to power on a hotplug connector.
530*10923SEvan.Yan@Sun.COM */
531*10923SEvan.Yan@Sun.COM static int
cmd_poweron(int argc,char * argv[],const char * usage_str)532*10923SEvan.Yan@Sun.COM cmd_poweron(int argc, char *argv[], const char *usage_str)
533*10923SEvan.Yan@Sun.COM {
534*10923SEvan.Yan@Sun.COM hp_node_t root;
535*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
536*10923SEvan.Yan@Sun.COM char *path = NULL;
537*10923SEvan.Yan@Sun.COM char *connection = NULL;
538*10923SEvan.Yan@Sun.COM int rv;
539*10923SEvan.Yan@Sun.COM
540*10923SEvan.Yan@Sun.COM /* Parse command line options */
541*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
542*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
543*10923SEvan.Yan@Sun.COM
544*10923SEvan.Yan@Sun.COM /* Path and connection are required */
545*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
546*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
547*10923SEvan.Yan@Sun.COM usage(usage_str);
548*10923SEvan.Yan@Sun.COM return (EINVAL);
549*10923SEvan.Yan@Sun.COM }
550*10923SEvan.Yan@Sun.COM
551*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
552*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
553*10923SEvan.Yan@Sun.COM print_error(errno);
554*10923SEvan.Yan@Sun.COM return (errno);
555*10923SEvan.Yan@Sun.COM }
556*10923SEvan.Yan@Sun.COM
557*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
558*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
559*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
560*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
561*10923SEvan.Yan@Sun.COM hp_fini(root);
562*10923SEvan.Yan@Sun.COM return (EINVAL);
563*10923SEvan.Yan@Sun.COM }
564*10923SEvan.Yan@Sun.COM
565*10923SEvan.Yan@Sun.COM /*
566*10923SEvan.Yan@Sun.COM * Do nothing if the connector is already powered.
567*10923SEvan.Yan@Sun.COM * Otherwise this subcommand becomes an alias for 'disable.'
568*10923SEvan.Yan@Sun.COM */
569*10923SEvan.Yan@Sun.COM if (hp_state(root) >= DDI_HP_CN_STATE_POWERED) {
570*10923SEvan.Yan@Sun.COM hp_fini(root);
571*10923SEvan.Yan@Sun.COM return (0);
572*10923SEvan.Yan@Sun.COM }
573*10923SEvan.Yan@Sun.COM
574*10923SEvan.Yan@Sun.COM /* Do state change */
575*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, 0, DDI_HP_CN_STATE_POWERED, &results);
576*10923SEvan.Yan@Sun.COM
577*10923SEvan.Yan@Sun.COM /* Display results */
578*10923SEvan.Yan@Sun.COM print_error(rv);
579*10923SEvan.Yan@Sun.COM if (results != NULL) {
580*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
581*10923SEvan.Yan@Sun.COM hp_fini(results);
582*10923SEvan.Yan@Sun.COM }
583*10923SEvan.Yan@Sun.COM
584*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
585*10923SEvan.Yan@Sun.COM hp_fini(root);
586*10923SEvan.Yan@Sun.COM
587*10923SEvan.Yan@Sun.COM return (rv);
588*10923SEvan.Yan@Sun.COM }
589*10923SEvan.Yan@Sun.COM
590*10923SEvan.Yan@Sun.COM /*
591*10923SEvan.Yan@Sun.COM * cmd_poweroff()
592*10923SEvan.Yan@Sun.COM *
593*10923SEvan.Yan@Sun.COM * Subcommand to power off a hotplug connector.
594*10923SEvan.Yan@Sun.COM */
595*10923SEvan.Yan@Sun.COM static int
cmd_poweroff(int argc,char * argv[],const char * usage_str)596*10923SEvan.Yan@Sun.COM cmd_poweroff(int argc, char *argv[], const char *usage_str)
597*10923SEvan.Yan@Sun.COM {
598*10923SEvan.Yan@Sun.COM hp_node_t root;
599*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
600*10923SEvan.Yan@Sun.COM char *path = NULL;
601*10923SEvan.Yan@Sun.COM char *connection = NULL;
602*10923SEvan.Yan@Sun.COM int flags = 0;
603*10923SEvan.Yan@Sun.COM int rv;
604*10923SEvan.Yan@Sun.COM
605*10923SEvan.Yan@Sun.COM /* Parse command line options */
606*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
607*10923SEvan.Yan@Sun.COM parse_flags(argc, argv, &flags, usage_str);
608*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
609*10923SEvan.Yan@Sun.COM
610*10923SEvan.Yan@Sun.COM /* Path and connection are required */
611*10923SEvan.Yan@Sun.COM if ((path == NULL) || (connection == NULL)) {
612*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
613*10923SEvan.Yan@Sun.COM usage(usage_str);
614*10923SEvan.Yan@Sun.COM return (EINVAL);
615*10923SEvan.Yan@Sun.COM }
616*10923SEvan.Yan@Sun.COM
617*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
618*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
619*10923SEvan.Yan@Sun.COM print_error(errno);
620*10923SEvan.Yan@Sun.COM return (errno);
621*10923SEvan.Yan@Sun.COM }
622*10923SEvan.Yan@Sun.COM
623*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
624*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
625*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
626*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
627*10923SEvan.Yan@Sun.COM hp_fini(root);
628*10923SEvan.Yan@Sun.COM return (EINVAL);
629*10923SEvan.Yan@Sun.COM }
630*10923SEvan.Yan@Sun.COM
631*10923SEvan.Yan@Sun.COM /* Do state change */
632*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, flags, DDI_HP_CN_STATE_PRESENT, &results);
633*10923SEvan.Yan@Sun.COM
634*10923SEvan.Yan@Sun.COM /* Display results */
635*10923SEvan.Yan@Sun.COM print_error(rv);
636*10923SEvan.Yan@Sun.COM if (results != NULL) {
637*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
638*10923SEvan.Yan@Sun.COM hp_fini(results);
639*10923SEvan.Yan@Sun.COM }
640*10923SEvan.Yan@Sun.COM
641*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
642*10923SEvan.Yan@Sun.COM hp_fini(root);
643*10923SEvan.Yan@Sun.COM
644*10923SEvan.Yan@Sun.COM return (rv);
645*10923SEvan.Yan@Sun.COM }
646*10923SEvan.Yan@Sun.COM
647*10923SEvan.Yan@Sun.COM /*
648*10923SEvan.Yan@Sun.COM * cmd_getpriv()
649*10923SEvan.Yan@Sun.COM *
650*10923SEvan.Yan@Sun.COM * Subcommand to get and display bus private options.
651*10923SEvan.Yan@Sun.COM */
652*10923SEvan.Yan@Sun.COM static int
cmd_getpriv(int argc,char * argv[],const char * usage_str)653*10923SEvan.Yan@Sun.COM cmd_getpriv(int argc, char *argv[], const char *usage_str)
654*10923SEvan.Yan@Sun.COM {
655*10923SEvan.Yan@Sun.COM hp_node_t root;
656*10923SEvan.Yan@Sun.COM char *path = NULL;
657*10923SEvan.Yan@Sun.COM char *connection = NULL;
658*10923SEvan.Yan@Sun.COM char *options = NULL;
659*10923SEvan.Yan@Sun.COM char *results = NULL;
660*10923SEvan.Yan@Sun.COM int rv;
661*10923SEvan.Yan@Sun.COM
662*10923SEvan.Yan@Sun.COM /* Parse command line options */
663*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
664*10923SEvan.Yan@Sun.COM parse_options(argc, argv, &options, usage_str);
665*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
666*10923SEvan.Yan@Sun.COM
667*10923SEvan.Yan@Sun.COM /* Options, path, and connection are all required */
668*10923SEvan.Yan@Sun.COM if ((options == NULL) || (path == NULL) || (connection == NULL)) {
669*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
670*10923SEvan.Yan@Sun.COM usage(usage_str);
671*10923SEvan.Yan@Sun.COM return (EINVAL);
672*10923SEvan.Yan@Sun.COM }
673*10923SEvan.Yan@Sun.COM
674*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
675*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
676*10923SEvan.Yan@Sun.COM print_error(errno);
677*10923SEvan.Yan@Sun.COM return (errno);
678*10923SEvan.Yan@Sun.COM }
679*10923SEvan.Yan@Sun.COM
680*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
681*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
682*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
683*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
684*10923SEvan.Yan@Sun.COM hp_fini(root);
685*10923SEvan.Yan@Sun.COM return (EINVAL);
686*10923SEvan.Yan@Sun.COM }
687*10923SEvan.Yan@Sun.COM
688*10923SEvan.Yan@Sun.COM /* Do the operation */
689*10923SEvan.Yan@Sun.COM rv = hp_get_private(root, options, &results);
690*10923SEvan.Yan@Sun.COM
691*10923SEvan.Yan@Sun.COM /* Display results */
692*10923SEvan.Yan@Sun.COM if (rv == ENOTSUP) {
693*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
694*10923SEvan.Yan@Sun.COM gettext("ERROR: unsupported property name or value.\n"));
695*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
696*10923SEvan.Yan@Sun.COM gettext("(Properties may depend upon connector state.)\n"));
697*10923SEvan.Yan@Sun.COM } else if (rv != 0) {
698*10923SEvan.Yan@Sun.COM print_error(rv);
699*10923SEvan.Yan@Sun.COM }
700*10923SEvan.Yan@Sun.COM if (results != NULL) {
701*10923SEvan.Yan@Sun.COM print_options(results);
702*10923SEvan.Yan@Sun.COM free(results);
703*10923SEvan.Yan@Sun.COM }
704*10923SEvan.Yan@Sun.COM
705*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
706*10923SEvan.Yan@Sun.COM hp_fini(root);
707*10923SEvan.Yan@Sun.COM
708*10923SEvan.Yan@Sun.COM return (rv);
709*10923SEvan.Yan@Sun.COM }
710*10923SEvan.Yan@Sun.COM
711*10923SEvan.Yan@Sun.COM /*
712*10923SEvan.Yan@Sun.COM * cmd_setpriv()
713*10923SEvan.Yan@Sun.COM *
714*10923SEvan.Yan@Sun.COM * Subcommand to set bus private options.
715*10923SEvan.Yan@Sun.COM */
716*10923SEvan.Yan@Sun.COM static int
cmd_setpriv(int argc,char * argv[],const char * usage_str)717*10923SEvan.Yan@Sun.COM cmd_setpriv(int argc, char *argv[], const char *usage_str)
718*10923SEvan.Yan@Sun.COM {
719*10923SEvan.Yan@Sun.COM hp_node_t root;
720*10923SEvan.Yan@Sun.COM char *path = NULL;
721*10923SEvan.Yan@Sun.COM char *connection = NULL;
722*10923SEvan.Yan@Sun.COM char *options = NULL;
723*10923SEvan.Yan@Sun.COM char *results = NULL;
724*10923SEvan.Yan@Sun.COM int rv;
725*10923SEvan.Yan@Sun.COM
726*10923SEvan.Yan@Sun.COM /* Parse command line options */
727*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
728*10923SEvan.Yan@Sun.COM parse_options(argc, argv, &options, usage_str);
729*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
730*10923SEvan.Yan@Sun.COM
731*10923SEvan.Yan@Sun.COM /* Options, path, and connection are all required */
732*10923SEvan.Yan@Sun.COM if ((options == NULL) || (path == NULL) || (connection == NULL)) {
733*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
734*10923SEvan.Yan@Sun.COM usage(usage_str);
735*10923SEvan.Yan@Sun.COM return (EINVAL);
736*10923SEvan.Yan@Sun.COM }
737*10923SEvan.Yan@Sun.COM
738*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
739*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
740*10923SEvan.Yan@Sun.COM print_error(errno);
741*10923SEvan.Yan@Sun.COM return (errno);
742*10923SEvan.Yan@Sun.COM }
743*10923SEvan.Yan@Sun.COM
744*10923SEvan.Yan@Sun.COM /* Verify target is a connector */
745*10923SEvan.Yan@Sun.COM if (hp_type(root) != HP_NODE_CONNECTOR) {
746*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
747*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target (must be a connector).\n"));
748*10923SEvan.Yan@Sun.COM hp_fini(root);
749*10923SEvan.Yan@Sun.COM return (EINVAL);
750*10923SEvan.Yan@Sun.COM }
751*10923SEvan.Yan@Sun.COM
752*10923SEvan.Yan@Sun.COM /* Do the operation */
753*10923SEvan.Yan@Sun.COM rv = hp_set_private(root, options, &results);
754*10923SEvan.Yan@Sun.COM
755*10923SEvan.Yan@Sun.COM /* Display results */
756*10923SEvan.Yan@Sun.COM if (rv == ENOTSUP) {
757*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
758*10923SEvan.Yan@Sun.COM gettext("ERROR: unsupported property name or value.\n"));
759*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
760*10923SEvan.Yan@Sun.COM gettext("(Properties may depend upon connector state.)\n"));
761*10923SEvan.Yan@Sun.COM } else if (rv != 0) {
762*10923SEvan.Yan@Sun.COM print_error(rv);
763*10923SEvan.Yan@Sun.COM }
764*10923SEvan.Yan@Sun.COM if (results != NULL) {
765*10923SEvan.Yan@Sun.COM print_options(results);
766*10923SEvan.Yan@Sun.COM free(results);
767*10923SEvan.Yan@Sun.COM }
768*10923SEvan.Yan@Sun.COM
769*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
770*10923SEvan.Yan@Sun.COM hp_fini(root);
771*10923SEvan.Yan@Sun.COM
772*10923SEvan.Yan@Sun.COM return (rv);
773*10923SEvan.Yan@Sun.COM }
774*10923SEvan.Yan@Sun.COM
775*10923SEvan.Yan@Sun.COM /*
776*10923SEvan.Yan@Sun.COM * cmd_changestate()
777*10923SEvan.Yan@Sun.COM *
778*10923SEvan.Yan@Sun.COM * Subcommand to initiate a state change operation. This is
779*10923SEvan.Yan@Sun.COM * a hidden subcommand to directly set a connector or port to
780*10923SEvan.Yan@Sun.COM * a specific target state.
781*10923SEvan.Yan@Sun.COM */
782*10923SEvan.Yan@Sun.COM static int
cmd_changestate(int argc,char * argv[],const char * usage_str)783*10923SEvan.Yan@Sun.COM cmd_changestate(int argc, char *argv[], const char *usage_str)
784*10923SEvan.Yan@Sun.COM {
785*10923SEvan.Yan@Sun.COM hp_node_t root;
786*10923SEvan.Yan@Sun.COM hp_node_t results = NULL;
787*10923SEvan.Yan@Sun.COM char *path = NULL;
788*10923SEvan.Yan@Sun.COM char *connection = NULL;
789*10923SEvan.Yan@Sun.COM int state = -1;
790*10923SEvan.Yan@Sun.COM int flags = 0;
791*10923SEvan.Yan@Sun.COM int opt, rv;
792*10923SEvan.Yan@Sun.COM
793*10923SEvan.Yan@Sun.COM /* Parse command line options */
794*10923SEvan.Yan@Sun.COM parse_common(argc, argv, usage_str);
795*10923SEvan.Yan@Sun.COM while ((opt = getopt_clip(argc, argv, "fqs:", changestate_opts,
796*10923SEvan.Yan@Sun.COM NULL)) != -1) {
797*10923SEvan.Yan@Sun.COM switch (opt) {
798*10923SEvan.Yan@Sun.COM case 'f':
799*10923SEvan.Yan@Sun.COM flags |= HPFORCE;
800*10923SEvan.Yan@Sun.COM break;
801*10923SEvan.Yan@Sun.COM case 'q':
802*10923SEvan.Yan@Sun.COM flags |= HPQUERY;
803*10923SEvan.Yan@Sun.COM break;
804*10923SEvan.Yan@Sun.COM case 's':
805*10923SEvan.Yan@Sun.COM if ((state = state_atoi(optarg)) == -1) {
806*10923SEvan.Yan@Sun.COM (void) printf("ERROR: invalid target state\n");
807*10923SEvan.Yan@Sun.COM return (EINVAL);
808*10923SEvan.Yan@Sun.COM }
809*10923SEvan.Yan@Sun.COM break;
810*10923SEvan.Yan@Sun.COM default:
811*10923SEvan.Yan@Sun.COM bad_option(opt, optopt, usage_str);
812*10923SEvan.Yan@Sun.COM break;
813*10923SEvan.Yan@Sun.COM }
814*10923SEvan.Yan@Sun.COM }
815*10923SEvan.Yan@Sun.COM parse_target(argc, argv, &path, &connection, usage_str);
816*10923SEvan.Yan@Sun.COM
817*10923SEvan.Yan@Sun.COM /* State, path, and connection are all required */
818*10923SEvan.Yan@Sun.COM if ((state == -1) || (path == NULL) || (connection == NULL)) {
819*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too few arguments.\n"));
820*10923SEvan.Yan@Sun.COM usage(usage_str);
821*10923SEvan.Yan@Sun.COM return (EINVAL);
822*10923SEvan.Yan@Sun.COM }
823*10923SEvan.Yan@Sun.COM
824*10923SEvan.Yan@Sun.COM /* Check that target state is valid */
825*10923SEvan.Yan@Sun.COM if (valid_target(state) == 0) {
826*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
827*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid target state\n"));
828*10923SEvan.Yan@Sun.COM return (EINVAL);
829*10923SEvan.Yan@Sun.COM }
830*10923SEvan.Yan@Sun.COM
831*10923SEvan.Yan@Sun.COM /* Get hotplug information snapshot */
832*10923SEvan.Yan@Sun.COM if ((root = hp_init(path, connection, 0)) == NULL) {
833*10923SEvan.Yan@Sun.COM print_error(errno);
834*10923SEvan.Yan@Sun.COM return (errno);
835*10923SEvan.Yan@Sun.COM }
836*10923SEvan.Yan@Sun.COM
837*10923SEvan.Yan@Sun.COM /* Initiate state change operation on root of snapshot */
838*10923SEvan.Yan@Sun.COM rv = hp_set_state(root, flags, state, &results);
839*10923SEvan.Yan@Sun.COM
840*10923SEvan.Yan@Sun.COM /* Display results */
841*10923SEvan.Yan@Sun.COM print_error(rv);
842*10923SEvan.Yan@Sun.COM if (results) {
843*10923SEvan.Yan@Sun.COM (void) hp_traverse(results, NULL, error_cb);
844*10923SEvan.Yan@Sun.COM hp_fini(results);
845*10923SEvan.Yan@Sun.COM }
846*10923SEvan.Yan@Sun.COM
847*10923SEvan.Yan@Sun.COM /* Discard hotplug information snapshot */
848*10923SEvan.Yan@Sun.COM hp_fini(root);
849*10923SEvan.Yan@Sun.COM
850*10923SEvan.Yan@Sun.COM return (rv);
851*10923SEvan.Yan@Sun.COM }
852*10923SEvan.Yan@Sun.COM
853*10923SEvan.Yan@Sun.COM /*
854*10923SEvan.Yan@Sun.COM * parse_common()
855*10923SEvan.Yan@Sun.COM *
856*10923SEvan.Yan@Sun.COM * Parse command line options that are common to the
857*10923SEvan.Yan@Sun.COM * entire program, and to each of its subcommands.
858*10923SEvan.Yan@Sun.COM */
859*10923SEvan.Yan@Sun.COM static void
parse_common(int argc,char * argv[],const char * usage_str)860*10923SEvan.Yan@Sun.COM parse_common(int argc, char *argv[], const char *usage_str)
861*10923SEvan.Yan@Sun.COM {
862*10923SEvan.Yan@Sun.COM int opt;
863*10923SEvan.Yan@Sun.COM extern int opterr;
864*10923SEvan.Yan@Sun.COM extern int optind;
865*10923SEvan.Yan@Sun.COM
866*10923SEvan.Yan@Sun.COM /* Turn off error reporting */
867*10923SEvan.Yan@Sun.COM opterr = 0;
868*10923SEvan.Yan@Sun.COM
869*10923SEvan.Yan@Sun.COM while ((opt = getopt_clip(argc, argv, "?V", common_opts, NULL)) != -1) {
870*10923SEvan.Yan@Sun.COM switch (opt) {
871*10923SEvan.Yan@Sun.COM case '?':
872*10923SEvan.Yan@Sun.COM if (optopt == '?') {
873*10923SEvan.Yan@Sun.COM usage(usage_str);
874*10923SEvan.Yan@Sun.COM exit(0);
875*10923SEvan.Yan@Sun.COM }
876*10923SEvan.Yan@Sun.COM break;
877*10923SEvan.Yan@Sun.COM case 'V':
878*10923SEvan.Yan@Sun.COM (void) printf(gettext("%s: Version %s\n"),
879*10923SEvan.Yan@Sun.COM prog, version);
880*10923SEvan.Yan@Sun.COM exit(0);
881*10923SEvan.Yan@Sun.COM default:
882*10923SEvan.Yan@Sun.COM break;
883*10923SEvan.Yan@Sun.COM }
884*10923SEvan.Yan@Sun.COM }
885*10923SEvan.Yan@Sun.COM
886*10923SEvan.Yan@Sun.COM /* Reset option index */
887*10923SEvan.Yan@Sun.COM optind = 1;
888*10923SEvan.Yan@Sun.COM }
889*10923SEvan.Yan@Sun.COM
890*10923SEvan.Yan@Sun.COM /*
891*10923SEvan.Yan@Sun.COM * parse_flags()
892*10923SEvan.Yan@Sun.COM *
893*10923SEvan.Yan@Sun.COM * Parse command line flags common to all downward state
894*10923SEvan.Yan@Sun.COM * change operations (offline, disable, poweoff).
895*10923SEvan.Yan@Sun.COM */
896*10923SEvan.Yan@Sun.COM static void
parse_flags(int argc,char * argv[],int * flagsp,const char * usage_str)897*10923SEvan.Yan@Sun.COM parse_flags(int argc, char *argv[], int *flagsp, const char *usage_str)
898*10923SEvan.Yan@Sun.COM {
899*10923SEvan.Yan@Sun.COM int opt;
900*10923SEvan.Yan@Sun.COM int flags = 0;
901*10923SEvan.Yan@Sun.COM
902*10923SEvan.Yan@Sun.COM while ((opt = getopt_clip(argc, argv, "fq", flag_opts, NULL)) != -1) {
903*10923SEvan.Yan@Sun.COM switch (opt) {
904*10923SEvan.Yan@Sun.COM case 'f':
905*10923SEvan.Yan@Sun.COM flags |= HPFORCE;
906*10923SEvan.Yan@Sun.COM break;
907*10923SEvan.Yan@Sun.COM case 'q':
908*10923SEvan.Yan@Sun.COM flags |= HPQUERY;
909*10923SEvan.Yan@Sun.COM break;
910*10923SEvan.Yan@Sun.COM default:
911*10923SEvan.Yan@Sun.COM bad_option(opt, optopt, usage_str);
912*10923SEvan.Yan@Sun.COM break;
913*10923SEvan.Yan@Sun.COM }
914*10923SEvan.Yan@Sun.COM }
915*10923SEvan.Yan@Sun.COM
916*10923SEvan.Yan@Sun.COM *flagsp = flags;
917*10923SEvan.Yan@Sun.COM }
918*10923SEvan.Yan@Sun.COM
919*10923SEvan.Yan@Sun.COM /*
920*10923SEvan.Yan@Sun.COM * parse_options()
921*10923SEvan.Yan@Sun.COM *
922*10923SEvan.Yan@Sun.COM * Parse command line options common to the bus private set and
923*10923SEvan.Yan@Sun.COM * get subcommands.
924*10923SEvan.Yan@Sun.COM */
925*10923SEvan.Yan@Sun.COM static void
parse_options(int argc,char * argv[],char ** optionsp,const char * usage_str)926*10923SEvan.Yan@Sun.COM parse_options(int argc, char *argv[], char **optionsp, const char *usage_str)
927*10923SEvan.Yan@Sun.COM {
928*10923SEvan.Yan@Sun.COM int opt;
929*10923SEvan.Yan@Sun.COM
930*10923SEvan.Yan@Sun.COM while ((opt = getopt_clip(argc, argv, "o:", private_opts,
931*10923SEvan.Yan@Sun.COM NULL)) != -1) {
932*10923SEvan.Yan@Sun.COM switch (opt) {
933*10923SEvan.Yan@Sun.COM case 'o':
934*10923SEvan.Yan@Sun.COM *optionsp = optarg;
935*10923SEvan.Yan@Sun.COM break;
936*10923SEvan.Yan@Sun.COM default:
937*10923SEvan.Yan@Sun.COM bad_option(opt, optopt, usage_str);
938*10923SEvan.Yan@Sun.COM break;
939*10923SEvan.Yan@Sun.COM }
940*10923SEvan.Yan@Sun.COM }
941*10923SEvan.Yan@Sun.COM }
942*10923SEvan.Yan@Sun.COM
943*10923SEvan.Yan@Sun.COM /*
944*10923SEvan.Yan@Sun.COM * parse_target()
945*10923SEvan.Yan@Sun.COM *
946*10923SEvan.Yan@Sun.COM * Parse the target path and connection name from the command line.
947*10923SEvan.Yan@Sun.COM */
948*10923SEvan.Yan@Sun.COM static void
parse_target(int argc,char * argv[],char ** pathp,char ** connectionp,const char * usage_str)949*10923SEvan.Yan@Sun.COM parse_target(int argc, char *argv[], char **pathp, char **connectionp,
950*10923SEvan.Yan@Sun.COM const char *usage_str)
951*10923SEvan.Yan@Sun.COM {
952*10923SEvan.Yan@Sun.COM extern int optind;
953*10923SEvan.Yan@Sun.COM
954*10923SEvan.Yan@Sun.COM if (optind < argc)
955*10923SEvan.Yan@Sun.COM *pathp = argv[optind++];
956*10923SEvan.Yan@Sun.COM
957*10923SEvan.Yan@Sun.COM if (optind < argc)
958*10923SEvan.Yan@Sun.COM *connectionp = argv[optind++];
959*10923SEvan.Yan@Sun.COM
960*10923SEvan.Yan@Sun.COM if (optind < argc) {
961*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: too many arguments.\n"));
962*10923SEvan.Yan@Sun.COM usage(usage_str);
963*10923SEvan.Yan@Sun.COM exit(EINVAL);
964*10923SEvan.Yan@Sun.COM }
965*10923SEvan.Yan@Sun.COM }
966*10923SEvan.Yan@Sun.COM
967*10923SEvan.Yan@Sun.COM /*
968*10923SEvan.Yan@Sun.COM * bad_option()
969*10923SEvan.Yan@Sun.COM *
970*10923SEvan.Yan@Sun.COM * Routine to handle bad command line options.
971*10923SEvan.Yan@Sun.COM */
972*10923SEvan.Yan@Sun.COM static void
bad_option(int opt,int optopt,const char * usage_str)973*10923SEvan.Yan@Sun.COM bad_option(int opt, int optopt, const char *usage_str)
974*10923SEvan.Yan@Sun.COM {
975*10923SEvan.Yan@Sun.COM switch (opt) {
976*10923SEvan.Yan@Sun.COM case ':':
977*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
978*10923SEvan.Yan@Sun.COM gettext("ERROR: option '%c' requires an argument.\n"),
979*10923SEvan.Yan@Sun.COM optopt);
980*10923SEvan.Yan@Sun.COM break;
981*10923SEvan.Yan@Sun.COM default:
982*10923SEvan.Yan@Sun.COM if (optopt == '?') {
983*10923SEvan.Yan@Sun.COM usage(usage_str);
984*10923SEvan.Yan@Sun.COM exit(EXIT_OK);
985*10923SEvan.Yan@Sun.COM }
986*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
987*10923SEvan.Yan@Sun.COM gettext("ERROR: unrecognized option '%c'.\n"), optopt);
988*10923SEvan.Yan@Sun.COM break;
989*10923SEvan.Yan@Sun.COM }
990*10923SEvan.Yan@Sun.COM
991*10923SEvan.Yan@Sun.COM usage(usage_str);
992*10923SEvan.Yan@Sun.COM
993*10923SEvan.Yan@Sun.COM exit(EXIT_EINVAL);
994*10923SEvan.Yan@Sun.COM }
995*10923SEvan.Yan@Sun.COM
996*10923SEvan.Yan@Sun.COM /*
997*10923SEvan.Yan@Sun.COM * usage()
998*10923SEvan.Yan@Sun.COM *
999*10923SEvan.Yan@Sun.COM * Display general usage of the command. Including
1000*10923SEvan.Yan@Sun.COM * the usage synopsis of each defined subcommand.
1001*10923SEvan.Yan@Sun.COM */
1002*10923SEvan.Yan@Sun.COM static void
usage(const char * usage_str)1003*10923SEvan.Yan@Sun.COM usage(const char *usage_str)
1004*10923SEvan.Yan@Sun.COM {
1005*10923SEvan.Yan@Sun.COM int i;
1006*10923SEvan.Yan@Sun.COM
1007*10923SEvan.Yan@Sun.COM if (usage_str != NULL) {
1008*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("Usage: %s %s\n\n"),
1009*10923SEvan.Yan@Sun.COM prog, usage_str);
1010*10923SEvan.Yan@Sun.COM return;
1011*10923SEvan.Yan@Sun.COM }
1012*10923SEvan.Yan@Sun.COM
1013*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("Usage: %s <subcommand> [<args>]\n\n"),
1014*10923SEvan.Yan@Sun.COM prog);
1015*10923SEvan.Yan@Sun.COM
1016*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("Subcommands:\n\n"));
1017*10923SEvan.Yan@Sun.COM
1018*10923SEvan.Yan@Sun.COM for (i = 0; i < (sizeof (subcmds) / sizeof (subcmd_t)); i++)
1019*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, " %s\n\n", subcmds[i].usage_str);
1020*10923SEvan.Yan@Sun.COM }
1021*10923SEvan.Yan@Sun.COM
1022*10923SEvan.Yan@Sun.COM /*
1023*10923SEvan.Yan@Sun.COM * list_cb()
1024*10923SEvan.Yan@Sun.COM *
1025*10923SEvan.Yan@Sun.COM * Callback function for hp_traverse(), to display nodes
1026*10923SEvan.Yan@Sun.COM * of a hotplug information snapshot. (Short version.)
1027*10923SEvan.Yan@Sun.COM */
1028*10923SEvan.Yan@Sun.COM /*ARGSUSED*/
1029*10923SEvan.Yan@Sun.COM static int
list_cb(hp_node_t node,void * arg)1030*10923SEvan.Yan@Sun.COM list_cb(hp_node_t node, void *arg)
1031*10923SEvan.Yan@Sun.COM {
1032*10923SEvan.Yan@Sun.COM hp_node_t parent;
1033*10923SEvan.Yan@Sun.COM
1034*10923SEvan.Yan@Sun.COM /* Indent */
1035*10923SEvan.Yan@Sun.COM for (parent = hp_parent(node); parent; parent = hp_parent(parent))
1036*10923SEvan.Yan@Sun.COM if (hp_type(parent) == HP_NODE_DEVICE)
1037*10923SEvan.Yan@Sun.COM (void) printf(" ");
1038*10923SEvan.Yan@Sun.COM
1039*10923SEvan.Yan@Sun.COM switch (hp_type(node)) {
1040*10923SEvan.Yan@Sun.COM case HP_NODE_DEVICE:
1041*10923SEvan.Yan@Sun.COM (void) printf("%s\n", hp_name(node));
1042*10923SEvan.Yan@Sun.COM break;
1043*10923SEvan.Yan@Sun.COM
1044*10923SEvan.Yan@Sun.COM case HP_NODE_CONNECTOR:
1045*10923SEvan.Yan@Sun.COM (void) printf("[%s]", hp_name(node));
1046*10923SEvan.Yan@Sun.COM (void) printf(" (%s)", state_itoa(hp_state(node)));
1047*10923SEvan.Yan@Sun.COM (void) printf("\n");
1048*10923SEvan.Yan@Sun.COM break;
1049*10923SEvan.Yan@Sun.COM
1050*10923SEvan.Yan@Sun.COM case HP_NODE_PORT:
1051*10923SEvan.Yan@Sun.COM (void) printf("<%s>", hp_name(node));
1052*10923SEvan.Yan@Sun.COM (void) printf(" (%s)", state_itoa(hp_state(node)));
1053*10923SEvan.Yan@Sun.COM (void) printf("\n");
1054*10923SEvan.Yan@Sun.COM break;
1055*10923SEvan.Yan@Sun.COM
1056*10923SEvan.Yan@Sun.COM case HP_NODE_USAGE:
1057*10923SEvan.Yan@Sun.COM (void) printf("{ %s }\n", hp_usage(node));
1058*10923SEvan.Yan@Sun.COM break;
1059*10923SEvan.Yan@Sun.COM }
1060*10923SEvan.Yan@Sun.COM
1061*10923SEvan.Yan@Sun.COM return (HP_WALK_CONTINUE);
1062*10923SEvan.Yan@Sun.COM }
1063*10923SEvan.Yan@Sun.COM
1064*10923SEvan.Yan@Sun.COM /*
1065*10923SEvan.Yan@Sun.COM * list_long_cb()
1066*10923SEvan.Yan@Sun.COM *
1067*10923SEvan.Yan@Sun.COM * Callback function for hp_traverse(), to display nodes
1068*10923SEvan.Yan@Sun.COM * of a hotplug information snapshot. (Long version.)
1069*10923SEvan.Yan@Sun.COM */
1070*10923SEvan.Yan@Sun.COM /*ARGSUSED*/
1071*10923SEvan.Yan@Sun.COM static int
list_long_cb(hp_node_t node,void * arg)1072*10923SEvan.Yan@Sun.COM list_long_cb(hp_node_t node, void *arg)
1073*10923SEvan.Yan@Sun.COM {
1074*10923SEvan.Yan@Sun.COM char path[MAXPATHLEN];
1075*10923SEvan.Yan@Sun.COM char connection[MAXPATHLEN];
1076*10923SEvan.Yan@Sun.COM
1077*10923SEvan.Yan@Sun.COM if (hp_type(node) != HP_NODE_USAGE) {
1078*10923SEvan.Yan@Sun.COM if (hp_path(node, path, connection) != 0)
1079*10923SEvan.Yan@Sun.COM return (HP_WALK_CONTINUE);
1080*10923SEvan.Yan@Sun.COM (void) printf("%s", path);
1081*10923SEvan.Yan@Sun.COM }
1082*10923SEvan.Yan@Sun.COM
1083*10923SEvan.Yan@Sun.COM switch (hp_type(node)) {
1084*10923SEvan.Yan@Sun.COM case HP_NODE_CONNECTOR:
1085*10923SEvan.Yan@Sun.COM (void) printf(" [%s]", connection);
1086*10923SEvan.Yan@Sun.COM (void) printf(" (%s)", state_itoa(hp_state(node)));
1087*10923SEvan.Yan@Sun.COM break;
1088*10923SEvan.Yan@Sun.COM
1089*10923SEvan.Yan@Sun.COM case HP_NODE_PORT:
1090*10923SEvan.Yan@Sun.COM (void) printf(" <%s>", connection);
1091*10923SEvan.Yan@Sun.COM (void) printf(" (%s)", state_itoa(hp_state(node)));
1092*10923SEvan.Yan@Sun.COM break;
1093*10923SEvan.Yan@Sun.COM
1094*10923SEvan.Yan@Sun.COM case HP_NODE_USAGE:
1095*10923SEvan.Yan@Sun.COM (void) printf(" { %s }", hp_usage(node));
1096*10923SEvan.Yan@Sun.COM break;
1097*10923SEvan.Yan@Sun.COM }
1098*10923SEvan.Yan@Sun.COM
1099*10923SEvan.Yan@Sun.COM (void) printf("\n");
1100*10923SEvan.Yan@Sun.COM
1101*10923SEvan.Yan@Sun.COM return (HP_WALK_CONTINUE);
1102*10923SEvan.Yan@Sun.COM }
1103*10923SEvan.Yan@Sun.COM
1104*10923SEvan.Yan@Sun.COM /*
1105*10923SEvan.Yan@Sun.COM * error_cb()
1106*10923SEvan.Yan@Sun.COM *
1107*10923SEvan.Yan@Sun.COM * Callback function for hp_traverse(), to display
1108*10923SEvan.Yan@Sun.COM * error results from a state change operation.
1109*10923SEvan.Yan@Sun.COM */
1110*10923SEvan.Yan@Sun.COM /*ARGSUSED*/
1111*10923SEvan.Yan@Sun.COM static int
error_cb(hp_node_t node,void * arg)1112*10923SEvan.Yan@Sun.COM error_cb(hp_node_t node, void *arg)
1113*10923SEvan.Yan@Sun.COM {
1114*10923SEvan.Yan@Sun.COM hp_node_t child;
1115*10923SEvan.Yan@Sun.COM char *usage_str;
1116*10923SEvan.Yan@Sun.COM static char path[MAXPATHLEN];
1117*10923SEvan.Yan@Sun.COM static char connection[MAXPATHLEN];
1118*10923SEvan.Yan@Sun.COM
1119*10923SEvan.Yan@Sun.COM if (((child = hp_child(node)) != NULL) &&
1120*10923SEvan.Yan@Sun.COM (hp_type(child) == HP_NODE_USAGE)) {
1121*10923SEvan.Yan@Sun.COM if (hp_path(node, path, connection) == 0)
1122*10923SEvan.Yan@Sun.COM (void) printf("%s:\n", path);
1123*10923SEvan.Yan@Sun.COM return (HP_WALK_CONTINUE);
1124*10923SEvan.Yan@Sun.COM }
1125*10923SEvan.Yan@Sun.COM
1126*10923SEvan.Yan@Sun.COM if ((hp_type(node) == HP_NODE_USAGE) &&
1127*10923SEvan.Yan@Sun.COM ((usage_str = hp_usage(node)) != NULL))
1128*10923SEvan.Yan@Sun.COM (void) printf(" { %s }\n", usage_str);
1129*10923SEvan.Yan@Sun.COM
1130*10923SEvan.Yan@Sun.COM return (HP_WALK_CONTINUE);
1131*10923SEvan.Yan@Sun.COM }
1132*10923SEvan.Yan@Sun.COM
1133*10923SEvan.Yan@Sun.COM /*
1134*10923SEvan.Yan@Sun.COM * print_options()
1135*10923SEvan.Yan@Sun.COM *
1136*10923SEvan.Yan@Sun.COM * Parse and display bus private options. The options are
1137*10923SEvan.Yan@Sun.COM * formatted as a string which conforms to the getsubopt(3C)
1138*10923SEvan.Yan@Sun.COM * format. This routine only splits the string elements as
1139*10923SEvan.Yan@Sun.COM * separated by commas, and displays each portion on its own
1140*10923SEvan.Yan@Sun.COM * separate line of output.
1141*10923SEvan.Yan@Sun.COM */
1142*10923SEvan.Yan@Sun.COM static void
print_options(const char * options)1143*10923SEvan.Yan@Sun.COM print_options(const char *options)
1144*10923SEvan.Yan@Sun.COM {
1145*10923SEvan.Yan@Sun.COM char *buf, *curr, *next;
1146*10923SEvan.Yan@Sun.COM size_t len;
1147*10923SEvan.Yan@Sun.COM
1148*10923SEvan.Yan@Sun.COM /* Do nothing if options string is empty */
1149*10923SEvan.Yan@Sun.COM if ((len = strlen(options)) == 0)
1150*10923SEvan.Yan@Sun.COM return;
1151*10923SEvan.Yan@Sun.COM
1152*10923SEvan.Yan@Sun.COM /* To avoid modifying the input string, make a copy on the stack */
1153*10923SEvan.Yan@Sun.COM if ((buf = (char *)alloca(len + 1)) == NULL) {
1154*10923SEvan.Yan@Sun.COM (void) printf("%s\n", options);
1155*10923SEvan.Yan@Sun.COM return;
1156*10923SEvan.Yan@Sun.COM }
1157*10923SEvan.Yan@Sun.COM (void) strlcpy(buf, options, len + 1);
1158*10923SEvan.Yan@Sun.COM
1159*10923SEvan.Yan@Sun.COM /* Iterate through each comma-separated name/value pair */
1160*10923SEvan.Yan@Sun.COM curr = buf;
1161*10923SEvan.Yan@Sun.COM do {
1162*10923SEvan.Yan@Sun.COM if ((next = strchr(curr, ',')) != NULL) {
1163*10923SEvan.Yan@Sun.COM *next = '\0';
1164*10923SEvan.Yan@Sun.COM next++;
1165*10923SEvan.Yan@Sun.COM }
1166*10923SEvan.Yan@Sun.COM (void) printf("%s\n", curr);
1167*10923SEvan.Yan@Sun.COM } while ((curr = next) != NULL);
1168*10923SEvan.Yan@Sun.COM }
1169*10923SEvan.Yan@Sun.COM
1170*10923SEvan.Yan@Sun.COM /*
1171*10923SEvan.Yan@Sun.COM * print_error()
1172*10923SEvan.Yan@Sun.COM *
1173*10923SEvan.Yan@Sun.COM * Common routine to print error numbers in an appropriate way.
1174*10923SEvan.Yan@Sun.COM * Prints nothing if error code is 0.
1175*10923SEvan.Yan@Sun.COM */
1176*10923SEvan.Yan@Sun.COM static void
print_error(int error)1177*10923SEvan.Yan@Sun.COM print_error(int error)
1178*10923SEvan.Yan@Sun.COM {
1179*10923SEvan.Yan@Sun.COM switch (error) {
1180*10923SEvan.Yan@Sun.COM case 0:
1181*10923SEvan.Yan@Sun.COM /* No error */
1182*10923SEvan.Yan@Sun.COM return;
1183*10923SEvan.Yan@Sun.COM case EACCES:
1184*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1185*10923SEvan.Yan@Sun.COM gettext("ERROR: operation not authorized.\n"));
1186*10923SEvan.Yan@Sun.COM break;
1187*10923SEvan.Yan@Sun.COM case EBADF:
1188*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1189*10923SEvan.Yan@Sun.COM gettext("ERROR: hotplug service is not available.\n"));
1190*10923SEvan.Yan@Sun.COM break;
1191*10923SEvan.Yan@Sun.COM case EBUSY:
1192*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1193*10923SEvan.Yan@Sun.COM gettext("ERROR: devices or resources are busy.\n"));
1194*10923SEvan.Yan@Sun.COM break;
1195*10923SEvan.Yan@Sun.COM case EEXIST:
1196*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1197*10923SEvan.Yan@Sun.COM gettext("ERROR: resource already exists.\n"));
1198*10923SEvan.Yan@Sun.COM break;
1199*10923SEvan.Yan@Sun.COM case EFAULT:
1200*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1201*10923SEvan.Yan@Sun.COM gettext("ERROR: internal failure in hotplug service.\n"));
1202*10923SEvan.Yan@Sun.COM break;
1203*10923SEvan.Yan@Sun.COM case EINVAL:
1204*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1205*10923SEvan.Yan@Sun.COM gettext("ERROR: invalid arguments.\n"));
1206*10923SEvan.Yan@Sun.COM break;
1207*10923SEvan.Yan@Sun.COM case ENOENT:
1208*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1209*10923SEvan.Yan@Sun.COM gettext("ERROR: there are no connections to display.\n"));
1210*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1211*10923SEvan.Yan@Sun.COM gettext("(See hotplug(1m) for more information.)\n"));
1212*10923SEvan.Yan@Sun.COM break;
1213*10923SEvan.Yan@Sun.COM case ENXIO:
1214*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1215*10923SEvan.Yan@Sun.COM gettext("ERROR: no such path or connection.\n"));
1216*10923SEvan.Yan@Sun.COM break;
1217*10923SEvan.Yan@Sun.COM case ENOMEM:
1218*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1219*10923SEvan.Yan@Sun.COM gettext("ERROR: not enough memory.\n"));
1220*10923SEvan.Yan@Sun.COM break;
1221*10923SEvan.Yan@Sun.COM case ENOTSUP:
1222*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1223*10923SEvan.Yan@Sun.COM gettext("ERROR: operation not supported.\n"));
1224*10923SEvan.Yan@Sun.COM break;
1225*10923SEvan.Yan@Sun.COM case EIO:
1226*10923SEvan.Yan@Sun.COM (void) fprintf(stderr,
1227*10923SEvan.Yan@Sun.COM gettext("ERROR: hardware or driver specific failure.\n"));
1228*10923SEvan.Yan@Sun.COM break;
1229*10923SEvan.Yan@Sun.COM default:
1230*10923SEvan.Yan@Sun.COM (void) fprintf(stderr, gettext("ERROR: operation failed: %s\n"),
1231*10923SEvan.Yan@Sun.COM strerror(error));
1232*10923SEvan.Yan@Sun.COM break;
1233*10923SEvan.Yan@Sun.COM }
1234*10923SEvan.Yan@Sun.COM }
1235*10923SEvan.Yan@Sun.COM
1236*10923SEvan.Yan@Sun.COM /*
1237*10923SEvan.Yan@Sun.COM * state_atoi()
1238*10923SEvan.Yan@Sun.COM *
1239*10923SEvan.Yan@Sun.COM * Convert a hotplug state from a string to an integer.
1240*10923SEvan.Yan@Sun.COM */
1241*10923SEvan.Yan@Sun.COM static int
state_atoi(char * state)1242*10923SEvan.Yan@Sun.COM state_atoi(char *state)
1243*10923SEvan.Yan@Sun.COM {
1244*10923SEvan.Yan@Sun.COM int i;
1245*10923SEvan.Yan@Sun.COM
1246*10923SEvan.Yan@Sun.COM for (i = 0; hpstates[i].state_str != NULL; i++)
1247*10923SEvan.Yan@Sun.COM if (strcasecmp(state, hpstates[i].state_str) == 0)
1248*10923SEvan.Yan@Sun.COM return (hpstates[i].state);
1249*10923SEvan.Yan@Sun.COM
1250*10923SEvan.Yan@Sun.COM return (-1);
1251*10923SEvan.Yan@Sun.COM }
1252*10923SEvan.Yan@Sun.COM
1253*10923SEvan.Yan@Sun.COM /*
1254*10923SEvan.Yan@Sun.COM * state_itoa()
1255*10923SEvan.Yan@Sun.COM *
1256*10923SEvan.Yan@Sun.COM * Convert a hotplug state from an integer to a string.
1257*10923SEvan.Yan@Sun.COM */
1258*10923SEvan.Yan@Sun.COM static char *
state_itoa(int state)1259*10923SEvan.Yan@Sun.COM state_itoa(int state)
1260*10923SEvan.Yan@Sun.COM {
1261*10923SEvan.Yan@Sun.COM static char unknown[] = "UNKNOWN";
1262*10923SEvan.Yan@Sun.COM int i;
1263*10923SEvan.Yan@Sun.COM
1264*10923SEvan.Yan@Sun.COM for (i = 0; hpstates[i].state_str != NULL; i++)
1265*10923SEvan.Yan@Sun.COM if (state == hpstates[i].state)
1266*10923SEvan.Yan@Sun.COM return (hpstates[i].state_str);
1267*10923SEvan.Yan@Sun.COM
1268*10923SEvan.Yan@Sun.COM return (unknown);
1269*10923SEvan.Yan@Sun.COM }
1270*10923SEvan.Yan@Sun.COM
1271*10923SEvan.Yan@Sun.COM /*
1272*10923SEvan.Yan@Sun.COM * valid_target()
1273*10923SEvan.Yan@Sun.COM *
1274*10923SEvan.Yan@Sun.COM * Check if a state is a valid target for a changestate command.
1275*10923SEvan.Yan@Sun.COM */
1276*10923SEvan.Yan@Sun.COM static short
valid_target(int state)1277*10923SEvan.Yan@Sun.COM valid_target(int state)
1278*10923SEvan.Yan@Sun.COM {
1279*10923SEvan.Yan@Sun.COM int i;
1280*10923SEvan.Yan@Sun.COM
1281*10923SEvan.Yan@Sun.COM for (i = 0; hpstates[i].state_str != NULL; i++)
1282*10923SEvan.Yan@Sun.COM if (state == hpstates[i].state)
1283*10923SEvan.Yan@Sun.COM return (hpstates[i].valid_target);
1284*10923SEvan.Yan@Sun.COM
1285*10923SEvan.Yan@Sun.COM return (0);
1286*10923SEvan.Yan@Sun.COM }
1287