1d5ace945SErwin T Tsaur /*
2d5ace945SErwin T Tsaur * CDDL HEADER START
3d5ace945SErwin T Tsaur *
4d5ace945SErwin T Tsaur * The contents of this file are subject to the terms of the
5d5ace945SErwin T Tsaur * Common Development and Distribution License (the "License").
6d5ace945SErwin T Tsaur * You may not use this file except in compliance with the License.
7d5ace945SErwin T Tsaur *
8d5ace945SErwin T Tsaur * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d5ace945SErwin T Tsaur * or http://www.opensolaris.org/os/licensing.
10d5ace945SErwin T Tsaur * See the License for the specific language governing permissions
11d5ace945SErwin T Tsaur * and limitations under the License.
12d5ace945SErwin T Tsaur *
13d5ace945SErwin T Tsaur * When distributing Covered Code, include this CDDL HEADER in each
14d5ace945SErwin T Tsaur * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d5ace945SErwin T Tsaur * If applicable, add the following below this CDDL HEADER, with the
16d5ace945SErwin T Tsaur * fields enclosed by brackets "[]" replaced with your own identifying
17d5ace945SErwin T Tsaur * information: Portions Copyright [yyyy] [name of copyright owner]
18d5ace945SErwin T Tsaur *
19d5ace945SErwin T Tsaur * CDDL HEADER END
20d5ace945SErwin T Tsaur */
21d5ace945SErwin T Tsaur /*
225cd376e8SJimmy Vetayases * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23*33f5ff17SMilan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
24d5ace945SErwin T Tsaur */
25d5ace945SErwin T Tsaur
26d5ace945SErwin T Tsaur /*
27d5ace945SErwin T Tsaur * This is the user interface module for the pcitool. It checks commandline
28d5ace945SErwin T Tsaur * arguments and options and stores them in a pcitool_uiargs_t structure passed
29d5ace945SErwin T Tsaur * back to the rest of the program for processing.
30d5ace945SErwin T Tsaur *
31d5ace945SErwin T Tsaur * Please see pcitool_usage.c for a complete commandline description.
32d5ace945SErwin T Tsaur */
33d5ace945SErwin T Tsaur
34d5ace945SErwin T Tsaur #include <stdio.h>
35d5ace945SErwin T Tsaur #include <stdlib.h>
36d5ace945SErwin T Tsaur #include <unistd.h>
37d5ace945SErwin T Tsaur #include <sys/inttypes.h>
38d5ace945SErwin T Tsaur #include <sys/types.h>
39d5ace945SErwin T Tsaur #include <sys/param.h>
40d5ace945SErwin T Tsaur #include <strings.h>
41d5ace945SErwin T Tsaur #include <errno.h>
42d5ace945SErwin T Tsaur #include <sys/pci.h>
43d5ace945SErwin T Tsaur
44d5ace945SErwin T Tsaur #include <sys/pci_tools.h>
45d5ace945SErwin T Tsaur
46d5ace945SErwin T Tsaur #include "pcitool_ui.h"
47d5ace945SErwin T Tsaur
48d5ace945SErwin T Tsaur /*
49d5ace945SErwin T Tsaur * Uncomment the following for useful debugging / development options for this
50d5ace945SErwin T Tsaur * module only.
51d5ace945SErwin T Tsaur */
52d5ace945SErwin T Tsaur
53d5ace945SErwin T Tsaur /* #define DEBUG 1 */
54d5ace945SErwin T Tsaur /* #define STANDALONE 1 */
55d5ace945SErwin T Tsaur
56500b1e78SAlan Adamson, SD OSSD #define DEVNAME_START_PCI "/pci"
57500b1e78SAlan Adamson, SD OSSD #define DEVNAME_START_NIU "/niu"
58d5ace945SErwin T Tsaur
59d5ace945SErwin T Tsaur /* Default read/write size when -s not specified. */
60d5ace945SErwin T Tsaur #define DEFAULT_SIZE 4
61d5ace945SErwin T Tsaur
62d5ace945SErwin T Tsaur /* For get_value64 */
63d5ace945SErwin T Tsaur #define HEX_ONLY B_TRUE
64d5ace945SErwin T Tsaur #define BASE_BY_PREFIX B_FALSE
65d5ace945SErwin T Tsaur
66d5ace945SErwin T Tsaur #define BITS_PER_BYTE 8
67d5ace945SErwin T Tsaur
68d5ace945SErwin T Tsaur /*
69d5ace945SErwin T Tsaur * This defines which main options can be specified by the user.
70d5ace945SErwin T Tsaur * Options with colons after them require arguments.
71d5ace945SErwin T Tsaur */
7209b1eac2SEvan Yan static char *opt_string = ":n:d:i:m:p:rw:o:s:e:b:vaqlcxgy";
73d5ace945SErwin T Tsaur
74d5ace945SErwin T Tsaur /* This defines options used singly and only by themselves (no nexus). */
75d5ace945SErwin T Tsaur static char *no_dev_opt_string = "ahpqv";
76d5ace945SErwin T Tsaur
77d5ace945SErwin T Tsaur static void print_bad_option(char *argv[], int optopt, char *optarg);
78d5ace945SErwin T Tsaur static boolean_t get_confirmation(void);
79d5ace945SErwin T Tsaur static int get_value64(char *value_str, uint64_t *value, boolean_t hex_only);
80d5ace945SErwin T Tsaur static int parse_nexus_opts(char *input, uint64_t *flags_arg, uint8_t *bank_arg,
81d5ace945SErwin T Tsaur uint64_t *base_addr_arg);
82d5ace945SErwin T Tsaur static int extract_bdf_arg(char *cvalue, char *fld, uint64_t fld_flag,
83d5ace945SErwin T Tsaur uint64_t *all_flags, uint8_t *ivalue);
84d5ace945SErwin T Tsaur static int extract_bdf(char *value, char **bvalue_p, char **dvalue_p,
85d5ace945SErwin T Tsaur char **fvalue_p);
86d5ace945SErwin T Tsaur static int parse_device_opts(char *input, uint64_t *flags_arg,
87d5ace945SErwin T Tsaur uint8_t *bus_arg, uint8_t *device_arg, uint8_t *func_arg,
88d5ace945SErwin T Tsaur uint8_t *bank_arg);
897ff178cdSJimmy Vetayases static int parse_ino_opts(char *input, uint64_t *flags_arg,
907ff178cdSJimmy Vetayases uint32_t *cpu_arg, uint8_t *ino_arg);
9109b1eac2SEvan Yan static int parse_msi_opts(char *input, uint64_t *flags_arg, uint16_t *msi_arg);
92d5ace945SErwin T Tsaur static int parse_intr_set_opts(char *input, uint64_t *flags_arg,
93d5ace945SErwin T Tsaur uint32_t *cpu_arg);
94d5ace945SErwin T Tsaur static int parse_probeone_opts(char *input, uint64_t *flags_arg,
95d5ace945SErwin T Tsaur uint8_t *bus_arg, uint8_t *device_arg, uint8_t *func_arg);
96d5ace945SErwin T Tsaur
97d5ace945SErwin T Tsaur #ifdef DEBUG
98d5ace945SErwin T Tsaur void dump_struct(pcitool_uiargs_t *dump_this);
99d5ace945SErwin T Tsaur #endif
100d5ace945SErwin T Tsaur
101d5ace945SErwin T Tsaur /* Exported functions. */
102d5ace945SErwin T Tsaur
103d5ace945SErwin T Tsaur /*
104d5ace945SErwin T Tsaur * Main commandline argument parsing routine.
105d5ace945SErwin T Tsaur *
106d5ace945SErwin T Tsaur * Takes argc and argv straight from the commandline.
107d5ace945SErwin T Tsaur * Returns a pcitool_uiargs_t with flags of options specified, and values
108d5ace945SErwin T Tsaur * associated with them.
109d5ace945SErwin T Tsaur */
110d5ace945SErwin T Tsaur int
get_commandline_args(int argc,char * argv[],pcitool_uiargs_t * parsed_args)111d5ace945SErwin T Tsaur get_commandline_args(int argc, char *argv[], pcitool_uiargs_t *parsed_args)
112d5ace945SErwin T Tsaur {
113d5ace945SErwin T Tsaur int c; /* Current option being processed. */
114d5ace945SErwin T Tsaur boolean_t error = B_FALSE;
115d5ace945SErwin T Tsaur boolean_t confirm = B_FALSE;
116d5ace945SErwin T Tsaur uint64_t recv64;
117d5ace945SErwin T Tsaur
118d5ace945SErwin T Tsaur /* Needed for getopt(3C) */
119d5ace945SErwin T Tsaur extern char *optarg; /* Current commandline string. */
120d5ace945SErwin T Tsaur extern int optind; /* Index of current commandline string. */
121d5ace945SErwin T Tsaur extern int optopt; /* Option (char) which is missing an operand. */
122d5ace945SErwin T Tsaur extern int opterr; /* Set to 0 to disable getopt err reporting. */
123d5ace945SErwin T Tsaur
124d5ace945SErwin T Tsaur opterr = 0;
125d5ace945SErwin T Tsaur
126d5ace945SErwin T Tsaur bzero(parsed_args, sizeof (pcitool_uiargs_t));
127d5ace945SErwin T Tsaur
128d5ace945SErwin T Tsaur /* No args. probe mode accounting for bus ranges, nonverbose. */
129d5ace945SErwin T Tsaur if (argc == 1) {
130d5ace945SErwin T Tsaur usage(argv[0]);
131d5ace945SErwin T Tsaur parsed_args->flags = 0;
132d5ace945SErwin T Tsaur return (SUCCESS);
133d5ace945SErwin T Tsaur }
134d5ace945SErwin T Tsaur
135d5ace945SErwin T Tsaur /* 1st arg is not a device name. */
136500b1e78SAlan Adamson, SD OSSD if ((strstr(argv[1], DEVNAME_START_PCI) != argv[1]) &&
137500b1e78SAlan Adamson, SD OSSD (strstr(argv[1], DEVNAME_START_NIU) != argv[1])) {
138d5ace945SErwin T Tsaur
139d5ace945SErwin T Tsaur /* Default is to probe all trees accounting for bus ranges. */
140d5ace945SErwin T Tsaur parsed_args->flags = PROBEALL_FLAG | PROBERNG_FLAG;
141d5ace945SErwin T Tsaur
142d5ace945SErwin T Tsaur /* Loop thru the options until complete or an error is found. */
143d5ace945SErwin T Tsaur while (((c = getopt(argc, argv, no_dev_opt_string)) != -1) &&
144d5ace945SErwin T Tsaur (error == B_FALSE)) {
145d5ace945SErwin T Tsaur
146d5ace945SErwin T Tsaur switch (c) {
147d5ace945SErwin T Tsaur
148d5ace945SErwin T Tsaur /* Help requested. */
149d5ace945SErwin T Tsaur case 'h':
150d5ace945SErwin T Tsaur usage(argv[0]);
151d5ace945SErwin T Tsaur parsed_args->flags = 0;
152d5ace945SErwin T Tsaur return (SUCCESS);
153d5ace945SErwin T Tsaur
154d5ace945SErwin T Tsaur case 'p':
155d5ace945SErwin T Tsaur /* Take default probe mode */
156d5ace945SErwin T Tsaur break;
157d5ace945SErwin T Tsaur
158d5ace945SErwin T Tsaur case 'a':
159d5ace945SErwin T Tsaur /*
160d5ace945SErwin T Tsaur * Enable display of ALL bus numbers.
161d5ace945SErwin T Tsaur *
162d5ace945SErwin T Tsaur * This takes precidence over PROBERNG as -a
163d5ace945SErwin T Tsaur * is explicitly specified.
164d5ace945SErwin T Tsaur */
165d5ace945SErwin T Tsaur parsed_args->flags &= ~PROBERNG_FLAG;
166d5ace945SErwin T Tsaur break;
167d5ace945SErwin T Tsaur
168d5ace945SErwin T Tsaur case 'q':
169d5ace945SErwin T Tsaur parsed_args->flags |= QUIET_FLAG;
170d5ace945SErwin T Tsaur break;
171d5ace945SErwin T Tsaur
172d5ace945SErwin T Tsaur /* Verbose mode for full probe. */
173d5ace945SErwin T Tsaur case 'v':
174d5ace945SErwin T Tsaur parsed_args->flags |= VERBOSE_FLAG;
175d5ace945SErwin T Tsaur break;
176d5ace945SErwin T Tsaur
177d5ace945SErwin T Tsaur default:
178d5ace945SErwin T Tsaur error = B_TRUE;
179d5ace945SErwin T Tsaur break;
180d5ace945SErwin T Tsaur }
181d5ace945SErwin T Tsaur }
182d5ace945SErwin T Tsaur
183d5ace945SErwin T Tsaur /* Check for values straggling at the end of the command. */
184d5ace945SErwin T Tsaur if (optind != argc) {
185d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Unrecognized parameter "
186d5ace945SErwin T Tsaur "at the end of the command.\n", argv[0]);
187d5ace945SErwin T Tsaur error = B_TRUE;
188d5ace945SErwin T Tsaur }
189d5ace945SErwin T Tsaur
190d5ace945SErwin T Tsaur if (error) {
191d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg);
192d5ace945SErwin T Tsaur return (FAILURE);
193d5ace945SErwin T Tsaur }
194d5ace945SErwin T Tsaur
195d5ace945SErwin T Tsaur return (SUCCESS);
196d5ace945SErwin T Tsaur }
197d5ace945SErwin T Tsaur
198d5ace945SErwin T Tsaur /* Device node specified on commandline. */
199d5ace945SErwin T Tsaur
200d5ace945SErwin T Tsaur /* Skip argv[1] before continuing below. */
201d5ace945SErwin T Tsaur optind++;
202d5ace945SErwin T Tsaur
203d5ace945SErwin T Tsaur /* Loop through the options until complete or an error is found. */
204d5ace945SErwin T Tsaur while (((c = getopt(argc, argv, opt_string)) != -1) &&
205d5ace945SErwin T Tsaur (error == B_FALSE)) {
206d5ace945SErwin T Tsaur
207d5ace945SErwin T Tsaur switch (c) {
208d5ace945SErwin T Tsaur
209d5ace945SErwin T Tsaur /* Nexus */
210d5ace945SErwin T Tsaur case 'n':
211d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG |
212d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) {
213d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -n set with "
214d5ace945SErwin T Tsaur "-d, -p or -i or is set twice\n", argv[0]);
215d5ace945SErwin T Tsaur error = B_TRUE;
216d5ace945SErwin T Tsaur break;
217d5ace945SErwin T Tsaur }
218d5ace945SErwin T Tsaur parsed_args->flags |= NEXUS_FLAG;
219d5ace945SErwin T Tsaur if (parse_nexus_opts(optarg, &parsed_args->flags,
220d5ace945SErwin T Tsaur &parsed_args->bank, &parsed_args->base_address) !=
221d5ace945SErwin T Tsaur SUCCESS) {
222d5ace945SErwin T Tsaur (void) fprintf(stderr,
223d5ace945SErwin T Tsaur "%s: Error parsing -n options\n", argv[0]);
224d5ace945SErwin T Tsaur error = B_TRUE;
225d5ace945SErwin T Tsaur break;
226d5ace945SErwin T Tsaur }
227d5ace945SErwin T Tsaur break;
228d5ace945SErwin T Tsaur
229d5ace945SErwin T Tsaur /* Device (leaf node) */
230d5ace945SErwin T Tsaur case 'd':
231d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG |
232d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) {
233d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -d set with "
234d5ace945SErwin T Tsaur "-n, -p or -i or is set twice\n", argv[0]);
235d5ace945SErwin T Tsaur error = B_TRUE;
236d5ace945SErwin T Tsaur break;
237d5ace945SErwin T Tsaur }
238d5ace945SErwin T Tsaur parsed_args->flags |= LEAF_FLAG;
239d5ace945SErwin T Tsaur if (parse_device_opts(optarg, &parsed_args->flags,
240d5ace945SErwin T Tsaur &parsed_args->bus, &parsed_args->device,
241d5ace945SErwin T Tsaur &parsed_args->function,
242d5ace945SErwin T Tsaur &parsed_args->bank) != SUCCESS) {
243d5ace945SErwin T Tsaur (void) fprintf(stderr,
244d5ace945SErwin T Tsaur "%s: Error parsing -d options\n", argv[0]);
245d5ace945SErwin T Tsaur error = B_TRUE;
246d5ace945SErwin T Tsaur break;
247d5ace945SErwin T Tsaur }
248d5ace945SErwin T Tsaur break;
249d5ace945SErwin T Tsaur
250d5ace945SErwin T Tsaur /* Interrupt */
251d5ace945SErwin T Tsaur case 'i':
252d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG |
253d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) {
25409b1eac2SEvan Yan (void) fprintf(stderr, "%s: -i set with -m, "
255d5ace945SErwin T Tsaur "-n, -d or -p or is set twice\n", argv[0]);
256d5ace945SErwin T Tsaur error = B_TRUE;
257d5ace945SErwin T Tsaur break;
258d5ace945SErwin T Tsaur }
259d5ace945SErwin T Tsaur parsed_args->flags |= INTR_FLAG;
260d5ace945SErwin T Tsaur
261d5ace945SErwin T Tsaur /* parse input to get ino value. */
26209b1eac2SEvan Yan if (parse_ino_opts(optarg, &parsed_args->flags,
2637ff178cdSJimmy Vetayases &parsed_args->old_cpu,
264d5ace945SErwin T Tsaur &parsed_args->intr_ino) != SUCCESS) {
265d5ace945SErwin T Tsaur (void) fprintf(stderr,
266d5ace945SErwin T Tsaur "%s: Error parsing interrupt options\n",
267d5ace945SErwin T Tsaur argv[0]);
268d5ace945SErwin T Tsaur error = B_TRUE;
269d5ace945SErwin T Tsaur }
270d5ace945SErwin T Tsaur break;
27109b1eac2SEvan Yan /* Interrupt */
27209b1eac2SEvan Yan case 'm':
27309b1eac2SEvan Yan if (parsed_args->flags & (LEAF_FLAG |
27409b1eac2SEvan Yan NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) {
27509b1eac2SEvan Yan (void) fprintf(stderr, "%s: -m set with -i, "
27609b1eac2SEvan Yan "-n, -d or -p or is set twice\n", argv[0]);
27709b1eac2SEvan Yan error = B_TRUE;
27809b1eac2SEvan Yan break;
27909b1eac2SEvan Yan }
28009b1eac2SEvan Yan parsed_args->flags |= INTR_FLAG;
281d5ace945SErwin T Tsaur
28209b1eac2SEvan Yan /* parse input to get msi value. */
28309b1eac2SEvan Yan if (parse_msi_opts(optarg, &parsed_args->flags,
28409b1eac2SEvan Yan &parsed_args->intr_msi) != SUCCESS) {
28509b1eac2SEvan Yan (void) fprintf(stderr,
28609b1eac2SEvan Yan "%s: Error parsing interrupt options\n",
28709b1eac2SEvan Yan argv[0]);
28809b1eac2SEvan Yan error = B_TRUE;
28909b1eac2SEvan Yan }
29009b1eac2SEvan Yan break;
291d5ace945SErwin T Tsaur /* Probe */
292d5ace945SErwin T Tsaur case 'p':
293d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG |
294d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) {
295d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -p set with "
296d5ace945SErwin T Tsaur "-n, -d or -i or is set twice\n", argv[0]);
297d5ace945SErwin T Tsaur error = B_TRUE;
298d5ace945SErwin T Tsaur break;
299d5ace945SErwin T Tsaur }
300d5ace945SErwin T Tsaur
301d5ace945SErwin T Tsaur /* Process -p with no dedicated options to it. */
302d5ace945SErwin T Tsaur if (optarg[0] == '-') {
303d5ace945SErwin T Tsaur optind--;
304d5ace945SErwin T Tsaur
305d5ace945SErwin T Tsaur /* Probe given tree observing ranges */
306d5ace945SErwin T Tsaur parsed_args->flags |=
307d5ace945SErwin T Tsaur (PROBETREE_FLAG | PROBERNG_FLAG);
308d5ace945SErwin T Tsaur continue;
309d5ace945SErwin T Tsaur }
310d5ace945SErwin T Tsaur
311d5ace945SErwin T Tsaur /* parse input to get ino value. */
312d5ace945SErwin T Tsaur if (parse_probeone_opts(optarg, &parsed_args->flags,
313d5ace945SErwin T Tsaur &parsed_args->bus, &parsed_args->device,
314d5ace945SErwin T Tsaur &parsed_args->function) != SUCCESS) {
315d5ace945SErwin T Tsaur (void) fprintf(stderr,
316d5ace945SErwin T Tsaur "%s: Error parsing probe options\n",
317d5ace945SErwin T Tsaur argv[0]);
318d5ace945SErwin T Tsaur error = B_TRUE;
319d5ace945SErwin T Tsaur } else {
320d5ace945SErwin T Tsaur /*
321d5ace945SErwin T Tsaur * parse_probeone_opts found options to
322d5ace945SErwin T Tsaur * set up bdf.
323d5ace945SErwin T Tsaur */
324d5ace945SErwin T Tsaur parsed_args->flags |= PROBEDEV_FLAG;
325d5ace945SErwin T Tsaur }
326d5ace945SErwin T Tsaur break;
327d5ace945SErwin T Tsaur
328d5ace945SErwin T Tsaur /* Probe all busses */
329d5ace945SErwin T Tsaur case 'a':
330d5ace945SErwin T Tsaur /* Must follow -p, and -p must have no bdf. */
331d5ace945SErwin T Tsaur if (!(parsed_args->flags & PROBETREE_FLAG)) {
332d5ace945SErwin T Tsaur error = B_TRUE;
333d5ace945SErwin T Tsaur break;
334d5ace945SErwin T Tsaur }
335d5ace945SErwin T Tsaur
336d5ace945SErwin T Tsaur parsed_args->flags &= ~PROBERNG_FLAG;
337d5ace945SErwin T Tsaur break;
338d5ace945SErwin T Tsaur
339d5ace945SErwin T Tsaur /* Read */
340d5ace945SErwin T Tsaur case 'r':
341d5ace945SErwin T Tsaur if (!(parsed_args->flags &
342d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG))) {
343d5ace945SErwin T Tsaur error = B_TRUE;
344d5ace945SErwin T Tsaur break;
345d5ace945SErwin T Tsaur }
346d5ace945SErwin T Tsaur
347d5ace945SErwin T Tsaur /*
348d5ace945SErwin T Tsaur * Allow read and write to be set together for now,
349d5ace945SErwin T Tsaur * since this means write then read back for device and
350d5ace945SErwin T Tsaur * nexus accesses. Check for this and disallow with
351d5ace945SErwin T Tsaur * interrupt command later.
352d5ace945SErwin T Tsaur */
353d5ace945SErwin T Tsaur parsed_args->flags |= READ_FLAG;
354d5ace945SErwin T Tsaur break;
355d5ace945SErwin T Tsaur
356d5ace945SErwin T Tsaur /* Write */
357d5ace945SErwin T Tsaur case 'w':
358d5ace945SErwin T Tsaur if (!(parsed_args->flags &
359d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG))) {
360d5ace945SErwin T Tsaur error = B_TRUE;
361d5ace945SErwin T Tsaur break;
362d5ace945SErwin T Tsaur }
363d5ace945SErwin T Tsaur if (parsed_args->flags & WRITE_FLAG) {
364d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -w set twice\n",
365d5ace945SErwin T Tsaur argv[0]);
366d5ace945SErwin T Tsaur error = B_TRUE;
367d5ace945SErwin T Tsaur break;
368d5ace945SErwin T Tsaur }
369d5ace945SErwin T Tsaur
370d5ace945SErwin T Tsaur /*
371d5ace945SErwin T Tsaur * For device and nexus, get a single register value
372d5ace945SErwin T Tsaur * to write.
373d5ace945SErwin T Tsaur */
374d5ace945SErwin T Tsaur if (parsed_args->flags & (NEXUS_FLAG | LEAF_FLAG)) {
375d5ace945SErwin T Tsaur parsed_args->flags |= WRITE_FLAG;
376d5ace945SErwin T Tsaur if (get_value64(optarg,
377d5ace945SErwin T Tsaur &parsed_args->write_value, HEX_ONLY) !=
378d5ace945SErwin T Tsaur SUCCESS) {
379d5ace945SErwin T Tsaur (void) fprintf(stderr,
380d5ace945SErwin T Tsaur "%s: Error reading value to "
381d5ace945SErwin T Tsaur "write.\n", argv[0]);
382d5ace945SErwin T Tsaur error = B_TRUE;
383d5ace945SErwin T Tsaur break;
384d5ace945SErwin T Tsaur }
385d5ace945SErwin T Tsaur
386d5ace945SErwin T Tsaur /* For interrupt, parse input to get cpu value. */
387d5ace945SErwin T Tsaur } else if (parsed_args->flags & INTR_FLAG) {
388d5ace945SErwin T Tsaur parsed_args->flags |= WRITE_FLAG;
389d5ace945SErwin T Tsaur if (parse_intr_set_opts(optarg,
390d5ace945SErwin T Tsaur &parsed_args->flags,
391d5ace945SErwin T Tsaur &parsed_args->intr_cpu) != SUCCESS) {
392d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Error "
393d5ace945SErwin T Tsaur "parsing interrupt options.\n",
394d5ace945SErwin T Tsaur argv[0]);
395d5ace945SErwin T Tsaur error = B_TRUE;
396d5ace945SErwin T Tsaur break;
397d5ace945SErwin T Tsaur }
398d5ace945SErwin T Tsaur
399d5ace945SErwin T Tsaur } else {
400d5ace945SErwin T Tsaur error = B_TRUE;
401d5ace945SErwin T Tsaur break;
402d5ace945SErwin T Tsaur }
403d5ace945SErwin T Tsaur break;
404d5ace945SErwin T Tsaur
405d5ace945SErwin T Tsaur /* Offset */
406d5ace945SErwin T Tsaur case 'o':
407d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) {
408d5ace945SErwin T Tsaur error = B_TRUE;
409d5ace945SErwin T Tsaur break;
410d5ace945SErwin T Tsaur }
411d5ace945SErwin T Tsaur if (parsed_args->flags & OFFSET_FLAG) {
412d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -o set twice\n",
413d5ace945SErwin T Tsaur argv[0]);
414d5ace945SErwin T Tsaur error = B_TRUE;
415d5ace945SErwin T Tsaur break;
416d5ace945SErwin T Tsaur }
417d5ace945SErwin T Tsaur parsed_args->flags |= OFFSET_FLAG;
418d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) {
419d5ace945SErwin T Tsaur (void) fprintf(stderr,
420d5ace945SErwin T Tsaur "%s: Error in offset argument\n", argv[0]);
421d5ace945SErwin T Tsaur error = B_TRUE;
422d5ace945SErwin T Tsaur break;
423d5ace945SErwin T Tsaur }
424d5ace945SErwin T Tsaur parsed_args->offset = (uint32_t)recv64;
425d5ace945SErwin T Tsaur if (parsed_args->offset != recv64) {
426d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Offset argument "
427d5ace945SErwin T Tsaur "too large for 32 bits\n", argv[0]);
428d5ace945SErwin T Tsaur error = B_TRUE;
429d5ace945SErwin T Tsaur break;
430d5ace945SErwin T Tsaur }
431d5ace945SErwin T Tsaur break;
432d5ace945SErwin T Tsaur
433d5ace945SErwin T Tsaur /* Size */
434d5ace945SErwin T Tsaur case 's':
435d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) {
436d5ace945SErwin T Tsaur error = B_TRUE;
437d5ace945SErwin T Tsaur break;
438d5ace945SErwin T Tsaur }
439d5ace945SErwin T Tsaur if (parsed_args->flags & SIZE_FLAG) {
440d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -s set twice\n",
441d5ace945SErwin T Tsaur argv[0]);
442d5ace945SErwin T Tsaur error = B_TRUE;
443d5ace945SErwin T Tsaur break;
444d5ace945SErwin T Tsaur }
445d5ace945SErwin T Tsaur parsed_args->flags |= SIZE_FLAG;
446d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) {
447d5ace945SErwin T Tsaur (void) fprintf(stderr,
448d5ace945SErwin T Tsaur "%s: Error in size argument\n", argv[0]);
449d5ace945SErwin T Tsaur error = B_TRUE;
450d5ace945SErwin T Tsaur break;
451d5ace945SErwin T Tsaur }
452d5ace945SErwin T Tsaur switch (recv64) {
453d5ace945SErwin T Tsaur case 1:
454d5ace945SErwin T Tsaur case 2:
455d5ace945SErwin T Tsaur case 4:
456d5ace945SErwin T Tsaur case 8:
457d5ace945SErwin T Tsaur break;
458d5ace945SErwin T Tsaur default:
459d5ace945SErwin T Tsaur error = B_TRUE;
460d5ace945SErwin T Tsaur (void) fprintf(stderr,
461d5ace945SErwin T Tsaur "%s: Error in size argument\n", argv[0]);
462d5ace945SErwin T Tsaur break;
463d5ace945SErwin T Tsaur }
464d5ace945SErwin T Tsaur parsed_args->size |= (uint8_t)recv64;
465d5ace945SErwin T Tsaur break;
466d5ace945SErwin T Tsaur
467d5ace945SErwin T Tsaur /* Endian. */
468d5ace945SErwin T Tsaur case 'e':
469d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) {
470d5ace945SErwin T Tsaur error = B_TRUE;
471d5ace945SErwin T Tsaur break;
472d5ace945SErwin T Tsaur }
473d5ace945SErwin T Tsaur if (parsed_args->flags & ENDIAN_FLAG) {
474d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -e set twice\n",
475d5ace945SErwin T Tsaur argv[0]);
476d5ace945SErwin T Tsaur error = B_TRUE;
477d5ace945SErwin T Tsaur break;
478d5ace945SErwin T Tsaur }
479d5ace945SErwin T Tsaur parsed_args->flags |= ENDIAN_FLAG;
480d5ace945SErwin T Tsaur
481d5ace945SErwin T Tsaur /* Only a single character allowed. */
482d5ace945SErwin T Tsaur if (optarg[1] != '\0') {
483d5ace945SErwin T Tsaur (void) fprintf(stderr,
484d5ace945SErwin T Tsaur "%s: Error in endian argument\n", argv[0]);
485d5ace945SErwin T Tsaur error = B_TRUE;
486d5ace945SErwin T Tsaur break;
487d5ace945SErwin T Tsaur }
488d5ace945SErwin T Tsaur
489d5ace945SErwin T Tsaur switch (optarg[0]) {
490d5ace945SErwin T Tsaur case 'b':
491d5ace945SErwin T Tsaur parsed_args->big_endian = B_TRUE;
492d5ace945SErwin T Tsaur break;
493d5ace945SErwin T Tsaur case 'l':
494d5ace945SErwin T Tsaur break;
495d5ace945SErwin T Tsaur default:
496d5ace945SErwin T Tsaur (void) fprintf(stderr,
497d5ace945SErwin T Tsaur "%s: Error in endian argument\n", argv[0]);
498d5ace945SErwin T Tsaur error = B_TRUE;
499d5ace945SErwin T Tsaur break;
500d5ace945SErwin T Tsaur }
501d5ace945SErwin T Tsaur break;
502d5ace945SErwin T Tsaur
503d5ace945SErwin T Tsaur /* (Byte)dump */
504d5ace945SErwin T Tsaur case 'b':
505d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) {
506d5ace945SErwin T Tsaur error = B_TRUE;
507d5ace945SErwin T Tsaur break;
508d5ace945SErwin T Tsaur }
509d5ace945SErwin T Tsaur if (parsed_args->flags & BYTEDUMP_FLAG) {
510d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -b set twice\n",
511d5ace945SErwin T Tsaur argv[0]);
512d5ace945SErwin T Tsaur error = B_TRUE;
513d5ace945SErwin T Tsaur break;
514d5ace945SErwin T Tsaur }
515d5ace945SErwin T Tsaur parsed_args->flags |= BYTEDUMP_FLAG;
516d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) {
517d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Error in "
518d5ace945SErwin T Tsaur "bytedump argument\n", argv[0]);
519d5ace945SErwin T Tsaur error = B_TRUE;
520d5ace945SErwin T Tsaur break;
521d5ace945SErwin T Tsaur }
522d5ace945SErwin T Tsaur parsed_args->bytedump_amt = (uint32_t)recv64;
523d5ace945SErwin T Tsaur if (parsed_args->bytedump_amt != recv64) {
524d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Bytedump amount "
525d5ace945SErwin T Tsaur "too large for 32 bits\n", argv[0]);
526d5ace945SErwin T Tsaur error = B_TRUE;
527d5ace945SErwin T Tsaur break;
528d5ace945SErwin T Tsaur }
529d5ace945SErwin T Tsaur break;
530d5ace945SErwin T Tsaur
531d5ace945SErwin T Tsaur /* Verbose. */
532d5ace945SErwin T Tsaur case 'v':
533d5ace945SErwin T Tsaur parsed_args->flags |= VERBOSE_FLAG;
534d5ace945SErwin T Tsaur break;
535d5ace945SErwin T Tsaur
536d5ace945SErwin T Tsaur /*
537d5ace945SErwin T Tsaur * Quiet - no errors reported as messages.
538d5ace945SErwin T Tsaur * (Status still returned by program, however.)
539d5ace945SErwin T Tsaur */
540d5ace945SErwin T Tsaur case 'q':
541d5ace945SErwin T Tsaur parsed_args->flags |= QUIET_FLAG;
542d5ace945SErwin T Tsaur break;
543d5ace945SErwin T Tsaur
544d5ace945SErwin T Tsaur /* Loop. */
545d5ace945SErwin T Tsaur case 'l':
546d5ace945SErwin T Tsaur parsed_args->flags |= LOOP_FLAG;
547d5ace945SErwin T Tsaur break;
548d5ace945SErwin T Tsaur
549d5ace945SErwin T Tsaur /*
550d5ace945SErwin T Tsaur * Dump characters with bytedump (-b).
551d5ace945SErwin T Tsaur * Show controller info with -i.
552d5ace945SErwin T Tsaur */
553d5ace945SErwin T Tsaur case 'c':
554d5ace945SErwin T Tsaur if (parsed_args->flags & BYTEDUMP_FLAG) {
555d5ace945SErwin T Tsaur parsed_args->flags |= CHARDUMP_FLAG;
556d5ace945SErwin T Tsaur
557d5ace945SErwin T Tsaur } else if (parsed_args->flags & INTR_FLAG) {
558d5ace945SErwin T Tsaur parsed_args->flags |= SHOWCTLR_FLAG;
559d5ace945SErwin T Tsaur
560d5ace945SErwin T Tsaur } else {
561d5ace945SErwin T Tsaur error = B_TRUE;
562d5ace945SErwin T Tsaur }
563d5ace945SErwin T Tsaur break;
564d5ace945SErwin T Tsaur
565d5ace945SErwin T Tsaur /* Continue on errors with bytedump (-b). */
566d5ace945SErwin T Tsaur case 'x':
567d5ace945SErwin T Tsaur if (!(parsed_args->flags & BYTEDUMP_FLAG)) {
568d5ace945SErwin T Tsaur error = B_TRUE;
569d5ace945SErwin T Tsaur break;
570d5ace945SErwin T Tsaur }
571d5ace945SErwin T Tsaur parsed_args->flags |= ERRCONT_FLAG;
572d5ace945SErwin T Tsaur break;
573d5ace945SErwin T Tsaur
574d5ace945SErwin T Tsaur case 'g':
575d5ace945SErwin T Tsaur if (!(parsed_args->flags & INTR_FLAG)) {
576d5ace945SErwin T Tsaur error = B_TRUE;
577d5ace945SErwin T Tsaur break;
578d5ace945SErwin T Tsaur }
579d5ace945SErwin T Tsaur parsed_args->flags |= SETGRP_FLAG;
580d5ace945SErwin T Tsaur break;
581d5ace945SErwin T Tsaur
582d5ace945SErwin T Tsaur /* Take -y as confirmation and don't ask (where applicable). */
583d5ace945SErwin T Tsaur case 'y':
584d5ace945SErwin T Tsaur confirm = B_TRUE;
585d5ace945SErwin T Tsaur break;
586d5ace945SErwin T Tsaur
587d5ace945SErwin T Tsaur /* Option without operand. */
588d5ace945SErwin T Tsaur case ':':
589d5ace945SErwin T Tsaur switch (optopt) {
590d5ace945SErwin T Tsaur case 'p':
591d5ace945SErwin T Tsaur /* Allow -p without bdf spec. */
592d5ace945SErwin T Tsaur parsed_args->flags |=
593d5ace945SErwin T Tsaur (PROBETREE_FLAG | PROBERNG_FLAG);
594d5ace945SErwin T Tsaur break;
595d5ace945SErwin T Tsaur default:
596d5ace945SErwin T Tsaur error = B_TRUE;
597d5ace945SErwin T Tsaur break;
598d5ace945SErwin T Tsaur }
599d5ace945SErwin T Tsaur break;
600d5ace945SErwin T Tsaur
601d5ace945SErwin T Tsaur /* Unrecognized option. */
602d5ace945SErwin T Tsaur case '?':
603d5ace945SErwin T Tsaur error = B_TRUE;
604d5ace945SErwin T Tsaur break;
605d5ace945SErwin T Tsaur }
606d5ace945SErwin T Tsaur }
607d5ace945SErwin T Tsaur
608d5ace945SErwin T Tsaur /*
609d5ace945SErwin T Tsaur * Commandline has been parsed. Check for errors which can be checked
610d5ace945SErwin T Tsaur * only after commandline parsing is complete.
611d5ace945SErwin T Tsaur */
612d5ace945SErwin T Tsaur
613d5ace945SErwin T Tsaur if (!error) {
614d5ace945SErwin T Tsaur
615d5ace945SErwin T Tsaur /* Check for values straggling at the end of the command. */
616d5ace945SErwin T Tsaur if (optind != argc) {
617d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Unrecognized parameter "
618d5ace945SErwin T Tsaur "at the end of the command.\n", argv[0]);
619d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg);
620d5ace945SErwin T Tsaur return (FAILURE);
621d5ace945SErwin T Tsaur }
622d5ace945SErwin T Tsaur
623d5ace945SErwin T Tsaur /* No args other than nexus. Default to probing that nexus */
624d5ace945SErwin T Tsaur if (!(parsed_args->flags &
625d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS))) {
626d5ace945SErwin T Tsaur usage(argv[0]);
627d5ace945SErwin T Tsaur parsed_args->flags = 0;
628d5ace945SErwin T Tsaur return (SUCCESS);
629d5ace945SErwin T Tsaur }
630d5ace945SErwin T Tsaur
631d5ace945SErwin T Tsaur /*
632d5ace945SErwin T Tsaur * Don't allow any options other than all-bus, verbose or
633d5ace945SErwin T Tsaur * quiet with probe command. Set default probe flags if nexus
634d5ace945SErwin T Tsaur * or leaf options are not specified.
635d5ace945SErwin T Tsaur */
636d5ace945SErwin T Tsaur if (parsed_args->flags & (PROBETREE_FLAG | PROBEALL_FLAG)) {
637d5ace945SErwin T Tsaur if (parsed_args->flags &
638d5ace945SErwin T Tsaur ~(PROBE_FLAGS | QUIET_FLAG | VERBOSE_FLAG))
639d5ace945SErwin T Tsaur error = B_TRUE;
640d5ace945SErwin T Tsaur }
641d5ace945SErwin T Tsaur
642d5ace945SErwin T Tsaur /*
643d5ace945SErwin T Tsaur * Allow only read, write, quiet and verbose flags for
644d5ace945SErwin T Tsaur * interrupt command. Note that INO_SPEC_FLAG and CPU_SPEC_FLAG
645d5ace945SErwin T Tsaur * get set for interrupt command.
646d5ace945SErwin T Tsaur */
647d5ace945SErwin T Tsaur if (parsed_args->flags & INTR_FLAG) {
648d5ace945SErwin T Tsaur if (parsed_args->flags &
649d5ace945SErwin T Tsaur ~(INTR_FLAG | VERBOSE_FLAG | QUIET_FLAG |
650d5ace945SErwin T Tsaur READ_FLAG | WRITE_FLAG | SHOWCTLR_FLAG |
65109b1eac2SEvan Yan SETGRP_FLAG | INO_ALL_FLAG | INO_SPEC_FLAG |
65209b1eac2SEvan Yan MSI_ALL_FLAG | MSI_SPEC_FLAG | CPU_SPEC_FLAG)) {
653d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -v, -q, -r, -w, -c "
65409b1eac2SEvan Yan "-g are only options allowed with "
65509b1eac2SEvan Yan "interrupt command.\n", argv[0]);
656d5ace945SErwin T Tsaur error = B_TRUE;
657d5ace945SErwin T Tsaur }
658d5ace945SErwin T Tsaur
659d5ace945SErwin T Tsaur /* Need cpu and ino values for interrupt set command. */
660d5ace945SErwin T Tsaur if ((parsed_args->flags & WRITE_FLAG) &&
66109b1eac2SEvan Yan !(parsed_args->flags & CPU_SPEC_FLAG) &&
66209b1eac2SEvan Yan !((parsed_args->flags & INO_SPEC_FLAG) ||
66309b1eac2SEvan Yan (parsed_args->flags & MSI_SPEC_FLAG))) {
664d5ace945SErwin T Tsaur (void) fprintf(stderr,
66509b1eac2SEvan Yan "%s: Both cpu and ino/msi must be "
66609b1eac2SEvan Yan "specified explicitly for interrupt "
66709b1eac2SEvan Yan "set command.\n", argv[0]);
668d5ace945SErwin T Tsaur error = B_TRUE;
669d5ace945SErwin T Tsaur }
670d5ace945SErwin T Tsaur
671d5ace945SErwin T Tsaur /* Intr write and show ctlr flags are incompatible. */
672d5ace945SErwin T Tsaur if ((parsed_args->flags &
673d5ace945SErwin T Tsaur (WRITE_FLAG + SHOWCTLR_FLAG)) ==
674d5ace945SErwin T Tsaur (WRITE_FLAG + SHOWCTLR_FLAG)) {
675d5ace945SErwin T Tsaur (void) fprintf(stderr,
676d5ace945SErwin T Tsaur "%s: -w and -c are incompatible for "
677d5ace945SErwin T Tsaur "interrupt command.\n", argv[0]);
678d5ace945SErwin T Tsaur error = B_TRUE;
679d5ace945SErwin T Tsaur }
680d5ace945SErwin T Tsaur
681d5ace945SErwin T Tsaur /* Intr setgrp flag valid only for intr writes. */
682d5ace945SErwin T Tsaur if ((parsed_args->flags & (WRITE_FLAG + SETGRP_FLAG)) ==
683d5ace945SErwin T Tsaur SETGRP_FLAG) {
684d5ace945SErwin T Tsaur (void) fprintf(stderr,
685d5ace945SErwin T Tsaur "%s: -g is incompatible with -r "
686d5ace945SErwin T Tsaur "for interrupt command.\n", argv[0]);
687d5ace945SErwin T Tsaur error = B_TRUE;
688d5ace945SErwin T Tsaur }
689d5ace945SErwin T Tsaur
690d5ace945SErwin T Tsaur /*
691d5ace945SErwin T Tsaur * Disallow read & write together in interrupt command.
692d5ace945SErwin T Tsaur */
693d5ace945SErwin T Tsaur if ((parsed_args->flags & (WRITE_FLAG | READ_FLAG)) ==
694d5ace945SErwin T Tsaur (WRITE_FLAG | READ_FLAG)) {
695d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Only one of -r and "
696d5ace945SErwin T Tsaur "-w can be specified in "
697d5ace945SErwin T Tsaur "interrupt command.\n", argv[0]);
698d5ace945SErwin T Tsaur error = B_TRUE;
699d5ace945SErwin T Tsaur }
700d5ace945SErwin T Tsaur }
701d5ace945SErwin T Tsaur
702d5ace945SErwin T Tsaur /* Bytedump incompatible with some other options. */
703d5ace945SErwin T Tsaur if ((parsed_args->flags & BYTEDUMP_FLAG) &&
704d5ace945SErwin T Tsaur (parsed_args->flags &
705d5ace945SErwin T Tsaur (WRITE_FLAG | PROBE_FLAGS | INTR_FLAG))) {
706d5ace945SErwin T Tsaur (void) fprintf(stderr,
707d5ace945SErwin T Tsaur "%s: -b is incompatible with "
708d5ace945SErwin T Tsaur "another specified option.\n", argv[0]);
709d5ace945SErwin T Tsaur error = B_TRUE;
710d5ace945SErwin T Tsaur }
711d5ace945SErwin T Tsaur
712d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG)) {
713d5ace945SErwin T Tsaur
714d5ace945SErwin T Tsaur if (!(parsed_args->flags & SIZE_FLAG)) {
715d5ace945SErwin T Tsaur parsed_args->size = DEFAULT_SIZE;
716d5ace945SErwin T Tsaur }
717d5ace945SErwin T Tsaur if ((parsed_args->flags & WRITE_FLAG) &&
718d5ace945SErwin T Tsaur parsed_args->size < sizeof (uint64_t) &&
719d5ace945SErwin T Tsaur (parsed_args->write_value >>
720d5ace945SErwin T Tsaur (parsed_args->size * BITS_PER_BYTE))) {
721d5ace945SErwin T Tsaur (void) fprintf(stderr,
722d5ace945SErwin T Tsaur "%s: Data to write is larger than "
723d5ace945SErwin T Tsaur "specified size.\n", argv[0]);
724d5ace945SErwin T Tsaur error = B_TRUE;
725d5ace945SErwin T Tsaur }
726d5ace945SErwin T Tsaur
727d5ace945SErwin T Tsaur } else { /* Looping is compatible only with register cmds. */
728d5ace945SErwin T Tsaur
729d5ace945SErwin T Tsaur if (parsed_args->flags & LOOP_FLAG) {
730d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -l is incompatible "
731d5ace945SErwin T Tsaur "with given command.\n", argv[0]);
732d5ace945SErwin T Tsaur error = B_TRUE;
733d5ace945SErwin T Tsaur }
734d5ace945SErwin T Tsaur }
735d5ace945SErwin T Tsaur
736d5ace945SErwin T Tsaur /* Call out an erroneous -y and then ignore it. */
737d5ace945SErwin T Tsaur if ((confirm) && (!(parsed_args->flags & BASE_SPEC_FLAG))) {
738d5ace945SErwin T Tsaur (void) fprintf(stderr,
739d5ace945SErwin T Tsaur "%s: -y is incompatible with given command."
740d5ace945SErwin T Tsaur " Ignoring.\n", argv[0]);
741d5ace945SErwin T Tsaur }
742d5ace945SErwin T Tsaur }
743d5ace945SErwin T Tsaur
744d5ace945SErwin T Tsaur /* Now fill in the defaults and other holes. */
745d5ace945SErwin T Tsaur if (!(error)) {
746d5ace945SErwin T Tsaur if (!(parsed_args->flags & (READ_FLAG | WRITE_FLAG))) {
747d5ace945SErwin T Tsaur parsed_args->flags |= READ_FLAG;
748d5ace945SErwin T Tsaur }
749d5ace945SErwin T Tsaur
750d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG)) {
751d5ace945SErwin T Tsaur if (!(parsed_args->flags & ENDIAN_FLAG)) {
752d5ace945SErwin T Tsaur parsed_args->big_endian = B_FALSE;
753d5ace945SErwin T Tsaur }
754d5ace945SErwin T Tsaur }
755d5ace945SErwin T Tsaur
756d5ace945SErwin T Tsaur if (parsed_args->flags & BASE_SPEC_FLAG) {
757d5ace945SErwin T Tsaur if (!confirm) {
758d5ace945SErwin T Tsaur confirm = get_confirmation();
759d5ace945SErwin T Tsaur }
760d5ace945SErwin T Tsaur if (!confirm) {
761d5ace945SErwin T Tsaur parsed_args->flags &= ~ALL_COMMANDS;
762d5ace945SErwin T Tsaur }
763d5ace945SErwin T Tsaur }
764d5ace945SErwin T Tsaur
765d5ace945SErwin T Tsaur /*
766d5ace945SErwin T Tsaur * As far as other defaults are concerned:
767d5ace945SErwin T Tsaur * Other fields: bus, device, function, offset, default to
768d5ace945SErwin T Tsaur * zero.
769d5ace945SErwin T Tsaur */
770d5ace945SErwin T Tsaur
771d5ace945SErwin T Tsaur } else { /* An error occurred. */
772d5ace945SErwin T Tsaur
773d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg);
774d5ace945SErwin T Tsaur }
775d5ace945SErwin T Tsaur return (error);
776d5ace945SErwin T Tsaur }
777d5ace945SErwin T Tsaur
778d5ace945SErwin T Tsaur
779d5ace945SErwin T Tsaur /* Module-private functions. */
780d5ace945SErwin T Tsaur
781d5ace945SErwin T Tsaur static void
print_bad_option(char * argv[],int optopt,char * optarg)782d5ace945SErwin T Tsaur print_bad_option(char *argv[], int optopt, char *optarg)
783d5ace945SErwin T Tsaur {
784d5ace945SErwin T Tsaur /* Illegal option operand */
785d5ace945SErwin T Tsaur if (optarg != NULL) {
786d5ace945SErwin T Tsaur (void) fprintf(stderr,
787d5ace945SErwin T Tsaur "%s: illegal operand %s specified for option %c\n",
788d5ace945SErwin T Tsaur argv[0], optarg, optopt);
789d5ace945SErwin T Tsaur
790d5ace945SErwin T Tsaur /* Illegal option */
791d5ace945SErwin T Tsaur } else if (optopt != 0) {
792d5ace945SErwin T Tsaur (void) fprintf(stderr,
793d5ace945SErwin T Tsaur "%s: option %c is illegal or is missing an operand\n",
794d5ace945SErwin T Tsaur argv[0], optopt);
795d5ace945SErwin T Tsaur
796d5ace945SErwin T Tsaur /* getopt wasn't even called. Bad device spec. */
797d5ace945SErwin T Tsaur } else {
798d5ace945SErwin T Tsaur (void) fprintf(stderr,
799500b1e78SAlan Adamson, SD OSSD "%s: device spec must start with %s or %s...\n", argv[0],
800500b1e78SAlan Adamson, SD OSSD DEVNAME_START_PCI, DEVNAME_START_NIU);
801d5ace945SErwin T Tsaur }
802d5ace945SErwin T Tsaur
803d5ace945SErwin T Tsaur (void) fprintf(stderr,
804d5ace945SErwin T Tsaur "%s: Type \"%s -h\" to get help on running this program.\n",
805d5ace945SErwin T Tsaur argv[0], argv[0]);
806d5ace945SErwin T Tsaur }
807d5ace945SErwin T Tsaur
808d5ace945SErwin T Tsaur /*
809d5ace945SErwin T Tsaur * Warn the user and ask for confirmation.
810d5ace945SErwin T Tsaur */
811d5ace945SErwin T Tsaur static boolean_t
get_confirmation()812d5ace945SErwin T Tsaur get_confirmation()
813d5ace945SErwin T Tsaur {
814d5ace945SErwin T Tsaur int i, b;
815d5ace945SErwin T Tsaur
816d5ace945SErwin T Tsaur (void) printf("WARNING: This cmd with a bad addr can panic "
817d5ace945SErwin T Tsaur "the system. Continue [y/n] (n)? ");
818d5ace945SErwin T Tsaur for (i = 0; ; i++) {
819d5ace945SErwin T Tsaur b = getchar();
820d5ace945SErwin T Tsaur switch (b) {
821d5ace945SErwin T Tsaur case ' ':
822d5ace945SErwin T Tsaur case '\t':
823d5ace945SErwin T Tsaur break;
824d5ace945SErwin T Tsaur case 'y':
825d5ace945SErwin T Tsaur case 'Y':
826d5ace945SErwin T Tsaur return (B_TRUE);
827d5ace945SErwin T Tsaur default:
828d5ace945SErwin T Tsaur return (B_FALSE);
829d5ace945SErwin T Tsaur }
830d5ace945SErwin T Tsaur }
831d5ace945SErwin T Tsaur }
832d5ace945SErwin T Tsaur
833d5ace945SErwin T Tsaur
834d5ace945SErwin T Tsaur /*
835d5ace945SErwin T Tsaur * Given a digit string, return a 64 bit value.
836d5ace945SErwin T Tsaur *
837d5ace945SErwin T Tsaur * If the hex_only arg is true, interpret all strings as hex.
838d5ace945SErwin T Tsaur * Otherwise, interpret as strtoull(3C) does with base=0.
839d5ace945SErwin T Tsaur */
840d5ace945SErwin T Tsaur static int
get_value64(char * value_str,uint64_t * value,boolean_t hex_only)841d5ace945SErwin T Tsaur get_value64(char *value_str, uint64_t *value, boolean_t hex_only)
842d5ace945SErwin T Tsaur {
843d5ace945SErwin T Tsaur
844d5ace945SErwin T Tsaur /* This is overkill for now, as everything is in hex. */
845d5ace945SErwin T Tsaur static char dec_digits[] = "0123456789";
846d5ace945SErwin T Tsaur static char hex_digits[] = "01234567890abcdefABCDEF";
847d5ace945SErwin T Tsaur static char oct_digits[] = "01234567";
848d5ace945SErwin T Tsaur
849d5ace945SErwin T Tsaur char *digit_string;
850d5ace945SErwin T Tsaur char *string_to_check;
851d5ace945SErwin T Tsaur
852d5ace945SErwin T Tsaur if ((value_str == NULL) || (strlen(value_str) == 0)) {
853d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing value argument.\n");
854d5ace945SErwin T Tsaur return (FAILURE);
855d5ace945SErwin T Tsaur }
856d5ace945SErwin T Tsaur
857d5ace945SErwin T Tsaur if (!hex_only && (value_str[0] != '0')) {
858d5ace945SErwin T Tsaur digit_string = dec_digits;
859d5ace945SErwin T Tsaur string_to_check = value_str;
860d5ace945SErwin T Tsaur } else if ((value_str[1] == 'X') || (value_str[1] == 'x')) {
861d5ace945SErwin T Tsaur digit_string = hex_digits;
862d5ace945SErwin T Tsaur string_to_check = &value_str[2]; /* Ignore 0x of hex */
863d5ace945SErwin T Tsaur } else if (hex_only) {
864d5ace945SErwin T Tsaur digit_string = hex_digits;
865d5ace945SErwin T Tsaur string_to_check = value_str; /* Hex number, no 0x prefix */
866d5ace945SErwin T Tsaur } else {
867d5ace945SErwin T Tsaur digit_string = oct_digits;
868d5ace945SErwin T Tsaur string_to_check = value_str;
869d5ace945SErwin T Tsaur }
870d5ace945SErwin T Tsaur
871d5ace945SErwin T Tsaur /*
872d5ace945SErwin T Tsaur * Verify value is all proper digits.
873d5ace945SErwin T Tsaur *
874d5ace945SErwin T Tsaur * For some reason, strtoull doesn't return an error when it cannot
875d5ace945SErwin T Tsaur * interpret the value. This is why we do the checking ourselves.
876d5ace945SErwin T Tsaur */
877d5ace945SErwin T Tsaur if (strspn(string_to_check, digit_string) != strlen(string_to_check)) {
878d5ace945SErwin T Tsaur (void) fprintf(stderr,
879d5ace945SErwin T Tsaur "Value must contain only valid digits.\n");
880d5ace945SErwin T Tsaur return (FAILURE);
881d5ace945SErwin T Tsaur }
882d5ace945SErwin T Tsaur
883d5ace945SErwin T Tsaur *value = strtoull(value_str, NULL, (hex_only ? 16 : 0));
884d5ace945SErwin T Tsaur
885d5ace945SErwin T Tsaur return (SUCCESS);
886d5ace945SErwin T Tsaur }
887d5ace945SErwin T Tsaur
888d5ace945SErwin T Tsaur
889d5ace945SErwin T Tsaur /*
890d5ace945SErwin T Tsaur * Parse nexus options. This includes:
891d5ace945SErwin T Tsaur * bank=number
892d5ace945SErwin T Tsaur *
893d5ace945SErwin T Tsaur * input is what the user specified for the options on the commandline,
894d5ace945SErwin T Tsaur * flags_arg is modified with the option set, and bank_arg returns the value
895d5ace945SErwin T Tsaur * specified for bank.
896d5ace945SErwin T Tsaur */
897d5ace945SErwin T Tsaur static int
parse_nexus_opts(char * input,uint64_t * flags_arg,uint8_t * bank_arg,uint64_t * base_addr_arg)898d5ace945SErwin T Tsaur parse_nexus_opts(char *input, uint64_t *flags_arg, uint8_t *bank_arg,
899d5ace945SErwin T Tsaur uint64_t *base_addr_arg)
900d5ace945SErwin T Tsaur {
901d5ace945SErwin T Tsaur typedef enum {
902d5ace945SErwin T Tsaur bank = 0,
903d5ace945SErwin T Tsaur base
904d5ace945SErwin T Tsaur } nexus_opts_index_t;
905d5ace945SErwin T Tsaur
906d5ace945SErwin T Tsaur static char *nexus_opts[] = {
907d5ace945SErwin T Tsaur "bank",
908d5ace945SErwin T Tsaur "base",
909d5ace945SErwin T Tsaur NULL
910d5ace945SErwin T Tsaur };
911d5ace945SErwin T Tsaur
912d5ace945SErwin T Tsaur char *value;
913d5ace945SErwin T Tsaur uint64_t recv64;
914d5ace945SErwin T Tsaur
915d5ace945SErwin T Tsaur int rval = SUCCESS;
916d5ace945SErwin T Tsaur
917d5ace945SErwin T Tsaur if (input == NULL) {
918d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing argument.\n");
919d5ace945SErwin T Tsaur return (FAILURE);
920d5ace945SErwin T Tsaur }
921d5ace945SErwin T Tsaur
922d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) {
923d5ace945SErwin T Tsaur switch (getsubopt(&input, nexus_opts, &value)) {
924d5ace945SErwin T Tsaur case bank:
925d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
926d5ace945SErwin T Tsaur (void) fprintf(stderr, "The bank or bar arg is "
927d5ace945SErwin T Tsaur "specified more than once.\n");
928d5ace945SErwin T Tsaur rval = FAILURE;
929d5ace945SErwin T Tsaur break;
930d5ace945SErwin T Tsaur }
931d5ace945SErwin T Tsaur if (*flags_arg & BASE_SPEC_FLAG) {
932d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank and base address "
933d5ace945SErwin T Tsaur "cannot both be specified.\n");
934d5ace945SErwin T Tsaur rval = FAILURE;
935d5ace945SErwin T Tsaur break;
936d5ace945SErwin T Tsaur }
937d5ace945SErwin T Tsaur if (value == NULL) {
938d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing bank value.\n");
939d5ace945SErwin T Tsaur rval = FAILURE;
940d5ace945SErwin T Tsaur break;
941d5ace945SErwin T Tsaur }
942d5ace945SErwin T Tsaur if ((rval = get_value64(value, &recv64, HEX_ONLY)) !=
943d5ace945SErwin T Tsaur SUCCESS) {
944d5ace945SErwin T Tsaur break;
945d5ace945SErwin T Tsaur }
946d5ace945SErwin T Tsaur *bank_arg = (uint8_t)recv64;
947d5ace945SErwin T Tsaur if (*bank_arg != recv64) {
948d5ace945SErwin T Tsaur (void) fprintf(stderr,
949d5ace945SErwin T Tsaur "Bank argument must fit into 8 bits.\n");
950d5ace945SErwin T Tsaur rval = FAILURE;
951d5ace945SErwin T Tsaur break;
952d5ace945SErwin T Tsaur }
953d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
954d5ace945SErwin T Tsaur break;
955d5ace945SErwin T Tsaur
956d5ace945SErwin T Tsaur case base:
957d5ace945SErwin T Tsaur if (*flags_arg & BASE_SPEC_FLAG) {
958d5ace945SErwin T Tsaur (void) fprintf(stderr, "The base address "
959d5ace945SErwin T Tsaur "is specified more than once.\n");
960d5ace945SErwin T Tsaur rval = FAILURE;
961d5ace945SErwin T Tsaur break;
962d5ace945SErwin T Tsaur }
963d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
964d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank and base address "
965d5ace945SErwin T Tsaur "cannot both be specified.\n");
966d5ace945SErwin T Tsaur rval = FAILURE;
967d5ace945SErwin T Tsaur break;
968d5ace945SErwin T Tsaur }
969d5ace945SErwin T Tsaur if (value == NULL) {
970d5ace945SErwin T Tsaur (void) fprintf(stderr,
971d5ace945SErwin T Tsaur "Missing base addr value.\n");
972d5ace945SErwin T Tsaur rval = FAILURE;
973d5ace945SErwin T Tsaur break;
974d5ace945SErwin T Tsaur }
975d5ace945SErwin T Tsaur if ((rval = get_value64(value, base_addr_arg,
976d5ace945SErwin T Tsaur HEX_ONLY)) != SUCCESS) {
977d5ace945SErwin T Tsaur break;
978d5ace945SErwin T Tsaur }
979d5ace945SErwin T Tsaur *flags_arg |= BASE_SPEC_FLAG;
980d5ace945SErwin T Tsaur break;
981d5ace945SErwin T Tsaur
982d5ace945SErwin T Tsaur default:
983d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -n\n");
984d5ace945SErwin T Tsaur rval = FAILURE;
985d5ace945SErwin T Tsaur break;
986d5ace945SErwin T Tsaur }
987d5ace945SErwin T Tsaur }
988d5ace945SErwin T Tsaur
989d5ace945SErwin T Tsaur return (rval);
990d5ace945SErwin T Tsaur }
991d5ace945SErwin T Tsaur
992d5ace945SErwin T Tsaur
993d5ace945SErwin T Tsaur static int
extract_bdf_arg(char * cvalue,char * fld,uint64_t fld_flag,uint64_t * all_flags,uint8_t * ivalue)994d5ace945SErwin T Tsaur extract_bdf_arg(char *cvalue, char *fld, uint64_t fld_flag, uint64_t *all_flags,
995d5ace945SErwin T Tsaur uint8_t *ivalue)
996d5ace945SErwin T Tsaur {
997d5ace945SErwin T Tsaur uint64_t recv64;
998d5ace945SErwin T Tsaur
999d5ace945SErwin T Tsaur if (*all_flags & fld_flag) {
1000d5ace945SErwin T Tsaur (void) fprintf(stderr,
1001d5ace945SErwin T Tsaur "The %s is specified more than once.\n", fld);
1002d5ace945SErwin T Tsaur return (FAILURE);
1003d5ace945SErwin T Tsaur }
1004d5ace945SErwin T Tsaur if (get_value64(cvalue, &recv64, HEX_ONLY) != SUCCESS)
1005d5ace945SErwin T Tsaur return (FAILURE);
1006d5ace945SErwin T Tsaur
1007d5ace945SErwin T Tsaur *ivalue = (uint8_t)recv64;
1008d5ace945SErwin T Tsaur if (recv64 != *ivalue) {
1009d5ace945SErwin T Tsaur (void) fprintf(stderr,
1010d5ace945SErwin T Tsaur "This program limits the %s argument to 8 bits.\n", fld);
1011d5ace945SErwin T Tsaur (void) fprintf(stderr, "The actual maximum may be "
1012d5ace945SErwin T Tsaur "smaller but cannot be enforced by this program.\n");
1013d5ace945SErwin T Tsaur return (FAILURE);
1014d5ace945SErwin T Tsaur }
1015d5ace945SErwin T Tsaur
1016d5ace945SErwin T Tsaur *all_flags |= fld_flag;
1017d5ace945SErwin T Tsaur return (SUCCESS);
1018d5ace945SErwin T Tsaur }
1019d5ace945SErwin T Tsaur
1020d5ace945SErwin T Tsaur
extract_bdf(char * value,char ** bvalue_p,char ** dvalue_p,char ** fvalue_p)1021d5ace945SErwin T Tsaur static int extract_bdf(char *value, char **bvalue_p, char **dvalue_p,
1022d5ace945SErwin T Tsaur char **fvalue_p)
1023d5ace945SErwin T Tsaur {
1024d5ace945SErwin T Tsaur char *strtok_state;
1025d5ace945SErwin T Tsaur char *dummy;
1026d5ace945SErwin T Tsaur static char *separator = ".";
1027d5ace945SErwin T Tsaur
1028d5ace945SErwin T Tsaur *bvalue_p = strtok_r(value, separator, &strtok_state);
1029d5ace945SErwin T Tsaur *dvalue_p = strtok_r(NULL, separator, &strtok_state);
1030d5ace945SErwin T Tsaur *fvalue_p = strtok_r(NULL, separator, &strtok_state);
1031d5ace945SErwin T Tsaur dummy = strtok_r(NULL, separator, &strtok_state);
1032d5ace945SErwin T Tsaur
1033d5ace945SErwin T Tsaur /* Return failure only if too many values specified. */
1034d5ace945SErwin T Tsaur return ((dummy) ? FAILURE : SUCCESS);
1035d5ace945SErwin T Tsaur }
1036d5ace945SErwin T Tsaur
1037d5ace945SErwin T Tsaur /*
1038d5ace945SErwin T Tsaur * Parse device options. This includes:
1039d5ace945SErwin T Tsaur * bus=number
1040d5ace945SErwin T Tsaur * dev=number
1041d5ace945SErwin T Tsaur * func=number
1042d5ace945SErwin T Tsaur * bank=number
1043d5ace945SErwin T Tsaur * config
1044d5ace945SErwin T Tsaur * bar0
1045d5ace945SErwin T Tsaur * bar1
1046d5ace945SErwin T Tsaur * bar2
1047d5ace945SErwin T Tsaur * bar3
1048d5ace945SErwin T Tsaur * bar4
1049d5ace945SErwin T Tsaur * bar5
1050d5ace945SErwin T Tsaur * rom
1051d5ace945SErwin T Tsaur *
1052d5ace945SErwin T Tsaur * input is what the user specified for the options on the commandline,
1053d5ace945SErwin T Tsaur * flags_arg is modified with the options set, and the rest of the args return
1054d5ace945SErwin T Tsaur * their respective values.
1055d5ace945SErwin T Tsaur */
1056d5ace945SErwin T Tsaur static int
parse_device_opts(char * input,uint64_t * flags_arg,uint8_t * bus_arg,uint8_t * device_arg,uint8_t * func_arg,uint8_t * bank_arg)1057d5ace945SErwin T Tsaur parse_device_opts(
1058d5ace945SErwin T Tsaur char *input, uint64_t *flags_arg, uint8_t *bus_arg, uint8_t *device_arg,
1059d5ace945SErwin T Tsaur uint8_t *func_arg, uint8_t *bank_arg)
1060d5ace945SErwin T Tsaur {
1061d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */
1062d5ace945SErwin T Tsaur typedef enum {
1063d5ace945SErwin T Tsaur bus = 0,
1064d5ace945SErwin T Tsaur dev = 1,
1065d5ace945SErwin T Tsaur func = 2,
1066d5ace945SErwin T Tsaur bdf = 3,
1067d5ace945SErwin T Tsaur bank = 4,
1068d5ace945SErwin T Tsaur config = 5,
1069d5ace945SErwin T Tsaur bar0 = 6,
1070d5ace945SErwin T Tsaur bar1 = 7,
1071d5ace945SErwin T Tsaur bar2 = 8,
1072d5ace945SErwin T Tsaur bar3 = 9,
1073d5ace945SErwin T Tsaur bar4 = 10,
1074d5ace945SErwin T Tsaur bar5 = 11,
1075d5ace945SErwin T Tsaur rom = 12
1076d5ace945SErwin T Tsaur } bdf_opts_index_t;
1077d5ace945SErwin T Tsaur
1078d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */
1079d5ace945SErwin T Tsaur static char *bdf_opts[] = {
1080d5ace945SErwin T Tsaur "bus",
1081d5ace945SErwin T Tsaur "dev",
1082d5ace945SErwin T Tsaur "func",
1083d5ace945SErwin T Tsaur "bdf",
1084d5ace945SErwin T Tsaur "bank",
1085d5ace945SErwin T Tsaur "config",
1086d5ace945SErwin T Tsaur "bar0",
1087d5ace945SErwin T Tsaur "bar1",
1088d5ace945SErwin T Tsaur "bar2",
1089d5ace945SErwin T Tsaur "bar3",
1090d5ace945SErwin T Tsaur "bar4",
1091d5ace945SErwin T Tsaur "bar5",
1092d5ace945SErwin T Tsaur "rom",
1093d5ace945SErwin T Tsaur NULL };
1094d5ace945SErwin T Tsaur
1095d5ace945SErwin T Tsaur char *value; /* Current suboption being processed. */
1096d5ace945SErwin T Tsaur uint64_t recv64; /* Temporary value. */
1097d5ace945SErwin T Tsaur
1098d5ace945SErwin T Tsaur /* This error message is used in many places. */
1099d5ace945SErwin T Tsaur static char bank_err[] =
1100d5ace945SErwin T Tsaur {"The bank or bar arg is specified more than once.\n"};
1101d5ace945SErwin T Tsaur
1102d5ace945SErwin T Tsaur int rval = SUCCESS;
1103d5ace945SErwin T Tsaur
1104d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) {
1105d5ace945SErwin T Tsaur switch (getsubopt(&input, bdf_opts, &value)) {
1106d5ace945SErwin T Tsaur
1107d5ace945SErwin T Tsaur /* bus=number */
1108d5ace945SErwin T Tsaur case bdf: {
1109d5ace945SErwin T Tsaur char *bvalue, *dvalue, *fvalue;
1110d5ace945SErwin T Tsaur
1111d5ace945SErwin T Tsaur if ((rval = extract_bdf(value, &bvalue, &dvalue,
1112d5ace945SErwin T Tsaur &fvalue)) != SUCCESS) {
1113d5ace945SErwin T Tsaur break;
1114d5ace945SErwin T Tsaur }
1115d5ace945SErwin T Tsaur
1116d5ace945SErwin T Tsaur if (!bvalue | !dvalue | !fvalue) {
1117d5ace945SErwin T Tsaur break;
1118d5ace945SErwin T Tsaur }
1119d5ace945SErwin T Tsaur
1120d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(bvalue, "bus",
1121d5ace945SErwin T Tsaur BUS_SPEC_FLAG, flags_arg, bus_arg)) != SUCCESS) {
1122d5ace945SErwin T Tsaur break;
1123d5ace945SErwin T Tsaur }
1124d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(dvalue, "dev",
1125d5ace945SErwin T Tsaur DEV_SPEC_FLAG, flags_arg, device_arg)) != SUCCESS) {
1126d5ace945SErwin T Tsaur break;
1127d5ace945SErwin T Tsaur }
1128d5ace945SErwin T Tsaur rval = extract_bdf_arg(fvalue, "func",
1129d5ace945SErwin T Tsaur FUNC_SPEC_FLAG, flags_arg, func_arg);
1130d5ace945SErwin T Tsaur break;
1131d5ace945SErwin T Tsaur }
1132d5ace945SErwin T Tsaur
1133d5ace945SErwin T Tsaur case bus:
1134d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "bus", BUS_SPEC_FLAG,
1135d5ace945SErwin T Tsaur flags_arg, bus_arg);
1136d5ace945SErwin T Tsaur break;
1137d5ace945SErwin T Tsaur
1138d5ace945SErwin T Tsaur /* dev=number */
1139d5ace945SErwin T Tsaur case dev:
1140d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "dev", DEV_SPEC_FLAG,
1141d5ace945SErwin T Tsaur flags_arg, device_arg);
1142d5ace945SErwin T Tsaur break;
1143d5ace945SErwin T Tsaur
1144d5ace945SErwin T Tsaur /* func=number */
1145d5ace945SErwin T Tsaur case func:
1146d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "func", FUNC_SPEC_FLAG,
1147d5ace945SErwin T Tsaur flags_arg, func_arg);
1148d5ace945SErwin T Tsaur break;
1149d5ace945SErwin T Tsaur
1150d5ace945SErwin T Tsaur /* bank=number */
1151d5ace945SErwin T Tsaur case bank:
1152d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1153d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1154d5ace945SErwin T Tsaur rval = FAILURE;
1155d5ace945SErwin T Tsaur break;
1156d5ace945SErwin T Tsaur }
1157d5ace945SErwin T Tsaur if ((rval = get_value64(value, &recv64, HEX_ONLY)) !=
1158d5ace945SErwin T Tsaur SUCCESS) {
1159d5ace945SErwin T Tsaur break;
1160d5ace945SErwin T Tsaur }
1161d5ace945SErwin T Tsaur *bank_arg = (uint8_t)recv64;
1162d5ace945SErwin T Tsaur if (rval || (*bank_arg != recv64)) {
1163d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank argument must"
1164d5ace945SErwin T Tsaur " fit into 8 bits.\n");
1165d5ace945SErwin T Tsaur rval = FAILURE;
1166d5ace945SErwin T Tsaur break;
1167d5ace945SErwin T Tsaur }
1168d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1169d5ace945SErwin T Tsaur break;
1170d5ace945SErwin T Tsaur
1171d5ace945SErwin T Tsaur /* config */
1172d5ace945SErwin T Tsaur case config:
1173d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1174d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1175d5ace945SErwin T Tsaur rval = FAILURE;
1176d5ace945SErwin T Tsaur break;
1177d5ace945SErwin T Tsaur }
1178d5ace945SErwin T Tsaur *bank_arg = PCITOOL_CONFIG;
1179d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1180d5ace945SErwin T Tsaur break;
1181d5ace945SErwin T Tsaur
1182d5ace945SErwin T Tsaur /* bar0 */
1183d5ace945SErwin T Tsaur case bar0:
1184d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1185d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1186d5ace945SErwin T Tsaur rval = FAILURE;
1187d5ace945SErwin T Tsaur break;
1188d5ace945SErwin T Tsaur }
1189d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR0;
1190d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1191d5ace945SErwin T Tsaur break;
1192d5ace945SErwin T Tsaur
1193d5ace945SErwin T Tsaur /* bar1 */
1194d5ace945SErwin T Tsaur case bar1:
1195d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1196d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1197d5ace945SErwin T Tsaur rval = FAILURE;
1198d5ace945SErwin T Tsaur break;
1199d5ace945SErwin T Tsaur }
1200d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR1;
1201d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1202d5ace945SErwin T Tsaur break;
1203d5ace945SErwin T Tsaur
1204d5ace945SErwin T Tsaur /* bar2 */
1205d5ace945SErwin T Tsaur case bar2:
1206d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1207d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1208d5ace945SErwin T Tsaur rval = FAILURE;
1209d5ace945SErwin T Tsaur break;
1210d5ace945SErwin T Tsaur }
1211d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR2;
1212d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1213d5ace945SErwin T Tsaur break;
1214d5ace945SErwin T Tsaur
1215d5ace945SErwin T Tsaur /* bar3 */
1216d5ace945SErwin T Tsaur case bar3:
1217d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1218d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1219d5ace945SErwin T Tsaur rval = FAILURE;
1220d5ace945SErwin T Tsaur break;
1221d5ace945SErwin T Tsaur }
1222d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR3;
1223d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1224d5ace945SErwin T Tsaur break;
1225d5ace945SErwin T Tsaur
1226d5ace945SErwin T Tsaur /* bar4 */
1227d5ace945SErwin T Tsaur case bar4:
1228d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1229d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1230d5ace945SErwin T Tsaur rval = FAILURE;
1231d5ace945SErwin T Tsaur break;
1232d5ace945SErwin T Tsaur }
1233d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR4;
1234d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1235d5ace945SErwin T Tsaur break;
1236d5ace945SErwin T Tsaur
1237d5ace945SErwin T Tsaur /* bar5 */
1238d5ace945SErwin T Tsaur case bar5:
1239d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1240d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1241d5ace945SErwin T Tsaur rval = FAILURE;
1242d5ace945SErwin T Tsaur break;
1243d5ace945SErwin T Tsaur }
1244d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR5;
1245d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1246d5ace945SErwin T Tsaur break;
1247d5ace945SErwin T Tsaur
1248d5ace945SErwin T Tsaur /* rom */
1249d5ace945SErwin T Tsaur case rom:
1250d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) {
1251d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err);
1252d5ace945SErwin T Tsaur rval = FAILURE;
1253d5ace945SErwin T Tsaur break;
1254d5ace945SErwin T Tsaur }
1255d5ace945SErwin T Tsaur *bank_arg = PCITOOL_ROM;
1256d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1257d5ace945SErwin T Tsaur break;
1258d5ace945SErwin T Tsaur
1259d5ace945SErwin T Tsaur default:
1260d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -d\n");
1261d5ace945SErwin T Tsaur rval = FAILURE;
1262d5ace945SErwin T Tsaur break;
1263d5ace945SErwin T Tsaur }
1264d5ace945SErwin T Tsaur }
1265d5ace945SErwin T Tsaur
1266d5ace945SErwin T Tsaur /* Bus, dev and func must all be specified. */
1267d5ace945SErwin T Tsaur if ((*flags_arg & (BUS_SPEC_FLAG | DEV_SPEC_FLAG | FUNC_SPEC_FLAG)) !=
1268d5ace945SErwin T Tsaur (BUS_SPEC_FLAG | DEV_SPEC_FLAG | FUNC_SPEC_FLAG)) {
1269d5ace945SErwin T Tsaur rval = FAILURE;
1270d5ace945SErwin T Tsaur
1271d5ace945SErwin T Tsaur /* No bank specified in any way. Default to config space */
1272d5ace945SErwin T Tsaur } else if ((*flags_arg & BANK_SPEC_FLAG) == 0) {
1273d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG;
1274d5ace945SErwin T Tsaur *bank_arg = PCITOOL_CONFIG;
1275d5ace945SErwin T Tsaur }
1276d5ace945SErwin T Tsaur
1277d5ace945SErwin T Tsaur return (rval);
1278d5ace945SErwin T Tsaur }
1279d5ace945SErwin T Tsaur
1280d5ace945SErwin T Tsaur
1281d5ace945SErwin T Tsaur /*
128209b1eac2SEvan Yan * Parse INO options. This includes:
128309b1eac2SEvan Yan * ino# | all
1284d5ace945SErwin T Tsaur *
1285d5ace945SErwin T Tsaur * input is the string of options to parse. flags_arg returns modified with
1286d5ace945SErwin T Tsaur * specified options set. Other args return their respective values.
1287d5ace945SErwin T Tsaur */
1288d5ace945SErwin T Tsaur static int
parse_ino_opts(char * input,uint64_t * flags_arg,uint32_t * cpu_arg,uint8_t * ino_arg)12897ff178cdSJimmy Vetayases parse_ino_opts(char *input, uint64_t *flags_arg, uint32_t *cpu_arg,
12907ff178cdSJimmy Vetayases uint8_t *ino_arg)
1291d5ace945SErwin T Tsaur {
129209b1eac2SEvan Yan uint64_t value;
12937ff178cdSJimmy Vetayases char *charvalue;
1294d5ace945SErwin T Tsaur int rval = SUCCESS;
1295d5ace945SErwin T Tsaur
129609b1eac2SEvan Yan if (strcmp(input, "all") == 0) {
129709b1eac2SEvan Yan *flags_arg |= INO_ALL_FLAG;
12987ff178cdSJimmy Vetayases #ifdef __x86
12997ff178cdSJimmy Vetayases } else if (strstr(input, ",") == NULL) {
13007ff178cdSJimmy Vetayases (void) fprintf(stderr,
13017ff178cdSJimmy Vetayases "Interrupt format should be <cpu#,ino#>.\n");
13027ff178cdSJimmy Vetayases rval = FAILURE;
13037ff178cdSJimmy Vetayases #else
13047ff178cdSJimmy Vetayases } else if (strstr(input, ",") == NULL) {
13057ff178cdSJimmy Vetayases if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS)
13067ff178cdSJimmy Vetayases *ino_arg = (uint8_t)value;
13077ff178cdSJimmy Vetayases
13087ff178cdSJimmy Vetayases if (*ino_arg != value) {
13097ff178cdSJimmy Vetayases (void) fprintf(stderr,
13107ff178cdSJimmy Vetayases "ino argument must fit into 8 bits.\n");
13117ff178cdSJimmy Vetayases rval = FAILURE;
13127ff178cdSJimmy Vetayases } else {
13137ff178cdSJimmy Vetayases *flags_arg |= INO_SPEC_FLAG;
13147ff178cdSJimmy Vetayases }
13157ff178cdSJimmy Vetayases #endif
13167ff178cdSJimmy Vetayases } else if (charvalue = strtok(input, ",")) {
13177ff178cdSJimmy Vetayases if ((rval =
13187ff178cdSJimmy Vetayases get_value64(charvalue, &value, HEX_ONLY)) == SUCCESS) {
13197ff178cdSJimmy Vetayases *cpu_arg = (int)value;
13207ff178cdSJimmy Vetayases }
13217ff178cdSJimmy Vetayases
13227ff178cdSJimmy Vetayases input = strtok(NULL, ",");
13237ff178cdSJimmy Vetayases if (input == NULL) {
13247ff178cdSJimmy Vetayases (void) fprintf(stderr, "ino argument is need.\n");
13257ff178cdSJimmy Vetayases return (FAILURE);
13267ff178cdSJimmy Vetayases }
13277ff178cdSJimmy Vetayases
13287ff178cdSJimmy Vetayases if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS)
132909b1eac2SEvan Yan *ino_arg = (uint8_t)value;
1330d5ace945SErwin T Tsaur
133109b1eac2SEvan Yan if (*ino_arg != value) {
1332d5ace945SErwin T Tsaur (void) fprintf(stderr,
133309b1eac2SEvan Yan "ino argument must fit into 8 bits.\n");
1334d5ace945SErwin T Tsaur rval = FAILURE;
133509b1eac2SEvan Yan } else {
1336d5ace945SErwin T Tsaur *flags_arg |= INO_SPEC_FLAG;
133709b1eac2SEvan Yan }
133809b1eac2SEvan Yan } else {
1339d5ace945SErwin T Tsaur (void) fprintf(stderr,
1340d5ace945SErwin T Tsaur "Unrecognized option for -i\n");
1341d5ace945SErwin T Tsaur rval = FAILURE;
1342d5ace945SErwin T Tsaur }
134309b1eac2SEvan Yan
134409b1eac2SEvan Yan return (rval);
134509b1eac2SEvan Yan }
134609b1eac2SEvan Yan
134709b1eac2SEvan Yan
134809b1eac2SEvan Yan /*
134909b1eac2SEvan Yan * Parse MSI options. This includes:
135009b1eac2SEvan Yan * msi# | all
135109b1eac2SEvan Yan *
135209b1eac2SEvan Yan * input is the string of options to parse. flags_arg returns modified with
135309b1eac2SEvan Yan * specified options set. Other args return their respective values.
135409b1eac2SEvan Yan */
135509b1eac2SEvan Yan static int
parse_msi_opts(char * input,uint64_t * flags_arg,uint16_t * msi_arg)135609b1eac2SEvan Yan parse_msi_opts(char *input, uint64_t *flags_arg, uint16_t *msi_arg)
135709b1eac2SEvan Yan {
135809b1eac2SEvan Yan uint64_t value;
135909b1eac2SEvan Yan int rval = SUCCESS;
136009b1eac2SEvan Yan
136109b1eac2SEvan Yan if (strcmp(input, "all") == 0) {
136209b1eac2SEvan Yan *flags_arg |= MSI_ALL_FLAG;
13637ff178cdSJimmy Vetayases } else if (strstr(input, ",") == NULL) {
13647ff178cdSJimmy Vetayases if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS)
13657ff178cdSJimmy Vetayases *msi_arg = (uint16_t)value;
13667ff178cdSJimmy Vetayases
13677ff178cdSJimmy Vetayases if (*msi_arg != value) {
13687ff178cdSJimmy Vetayases (void) fprintf(stderr,
13697ff178cdSJimmy Vetayases "msi argument must fit into 16 bits.\n");
13707ff178cdSJimmy Vetayases rval = FAILURE;
13717ff178cdSJimmy Vetayases } else {
13727ff178cdSJimmy Vetayases *flags_arg |= MSI_SPEC_FLAG;
13737ff178cdSJimmy Vetayases }
13747ff178cdSJimmy Vetayases } else if (strtok(input, ",")) {
13757ff178cdSJimmy Vetayases input = strtok(NULL, ",");
13767ff178cdSJimmy Vetayases if (input == NULL) {
13777ff178cdSJimmy Vetayases (void) fprintf(stderr, "msi argument is need.\n");
13787ff178cdSJimmy Vetayases return (FAILURE);
13797ff178cdSJimmy Vetayases }
13807ff178cdSJimmy Vetayases
13817ff178cdSJimmy Vetayases if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS)
138209b1eac2SEvan Yan *msi_arg = (uint16_t)value;
138309b1eac2SEvan Yan
138409b1eac2SEvan Yan if (*msi_arg != value) {
138509b1eac2SEvan Yan (void) fprintf(stderr,
138609b1eac2SEvan Yan "msi argument must fit into 16 bits.\n");
138709b1eac2SEvan Yan rval = FAILURE;
138809b1eac2SEvan Yan } else {
138909b1eac2SEvan Yan *flags_arg |= MSI_SPEC_FLAG;
139009b1eac2SEvan Yan }
139109b1eac2SEvan Yan } else {
139209b1eac2SEvan Yan (void) fprintf(stderr,
139309b1eac2SEvan Yan "Unrecognized option for -m\n");
139409b1eac2SEvan Yan rval = FAILURE;
1395d5ace945SErwin T Tsaur }
1396d5ace945SErwin T Tsaur
1397d5ace945SErwin T Tsaur return (rval);
1398d5ace945SErwin T Tsaur }
1399d5ace945SErwin T Tsaur
1400d5ace945SErwin T Tsaur
1401d5ace945SErwin T Tsaur /*
1402d5ace945SErwin T Tsaur * Parse interrupt set options. This includes:
1403d5ace945SErwin T Tsaur * cpu=number
1404d5ace945SErwin T Tsaur *
1405d5ace945SErwin T Tsaur * input is the string of options to parse. flags_arg returns modified with
1406d5ace945SErwin T Tsaur * specified options set. Other args return their respective values.
1407d5ace945SErwin T Tsaur */
1408d5ace945SErwin T Tsaur static int
parse_intr_set_opts(char * input,uint64_t * flags_arg,uint32_t * cpu_arg)1409d5ace945SErwin T Tsaur parse_intr_set_opts(char *input, uint64_t *flags_arg, uint32_t *cpu_arg)
1410d5ace945SErwin T Tsaur {
141109b1eac2SEvan Yan uint64_t value;
1412d5ace945SErwin T Tsaur int rval = SUCCESS;
1413d5ace945SErwin T Tsaur
141409b1eac2SEvan Yan if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS) {
1415d5ace945SErwin T Tsaur
141609b1eac2SEvan Yan if ((long)value > sysconf(_SC_CPUID_MAX)) {
1417d5ace945SErwin T Tsaur (void) fprintf(stderr, "Cpu argument "
1418d5ace945SErwin T Tsaur "exceeds maximum for this system type.\n");
1419d5ace945SErwin T Tsaur rval = FAILURE;
142009b1eac2SEvan Yan } else {
142109b1eac2SEvan Yan *cpu_arg = (uint32_t)value;
1422d5ace945SErwin T Tsaur *flags_arg |= CPU_SPEC_FLAG;
1423d5ace945SErwin T Tsaur }
142409b1eac2SEvan Yan } else {
142509b1eac2SEvan Yan (void) fprintf(stderr,
142609b1eac2SEvan Yan "Unrecognized option for -i -m -w\n");
142709b1eac2SEvan Yan rval = FAILURE;
1428d5ace945SErwin T Tsaur }
1429d5ace945SErwin T Tsaur
1430d5ace945SErwin T Tsaur return (rval);
1431d5ace945SErwin T Tsaur }
1432d5ace945SErwin T Tsaur
1433d5ace945SErwin T Tsaur
1434d5ace945SErwin T Tsaur static int
parse_probeone_opts(char * input,uint64_t * flags_arg,uint8_t * bus_arg,uint8_t * device_arg,uint8_t * func_arg)1435d5ace945SErwin T Tsaur parse_probeone_opts(
1436d5ace945SErwin T Tsaur char *input, uint64_t *flags_arg, uint8_t *bus_arg, uint8_t *device_arg,
1437d5ace945SErwin T Tsaur uint8_t *func_arg)
1438d5ace945SErwin T Tsaur {
1439d5ace945SErwin T Tsaur typedef enum {
1440d5ace945SErwin T Tsaur bus = 0,
1441d5ace945SErwin T Tsaur dev = 1,
1442d5ace945SErwin T Tsaur func = 2,
1443d5ace945SErwin T Tsaur bdf = 3
1444d5ace945SErwin T Tsaur } p1_bdf_opts_index_t;
1445d5ace945SErwin T Tsaur
1446d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */
1447d5ace945SErwin T Tsaur static char *p1_bdf_opts[] = {
1448d5ace945SErwin T Tsaur "bus",
1449d5ace945SErwin T Tsaur "dev",
1450d5ace945SErwin T Tsaur "func",
1451d5ace945SErwin T Tsaur "bdf",
1452d5ace945SErwin T Tsaur NULL };
1453d5ace945SErwin T Tsaur
1454d5ace945SErwin T Tsaur char *value; /* Current suboption being processed. */
1455d5ace945SErwin T Tsaur
1456d5ace945SErwin T Tsaur int rval = SUCCESS;
1457d5ace945SErwin T Tsaur
1458d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) {
1459d5ace945SErwin T Tsaur switch (getsubopt(&input, p1_bdf_opts, &value)) {
1460d5ace945SErwin T Tsaur
1461d5ace945SErwin T Tsaur /* bus=number */
1462d5ace945SErwin T Tsaur case bdf: {
1463d5ace945SErwin T Tsaur char *bvalue, *dvalue, *fvalue;
1464d5ace945SErwin T Tsaur
1465d5ace945SErwin T Tsaur if ((rval = extract_bdf(value, &bvalue, &dvalue,
1466d5ace945SErwin T Tsaur &fvalue)) != SUCCESS) {
1467d5ace945SErwin T Tsaur break;
1468d5ace945SErwin T Tsaur }
1469d5ace945SErwin T Tsaur if (bvalue)
1470d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(bvalue, "bus",
1471d5ace945SErwin T Tsaur BUS_SPEC_FLAG, flags_arg, bus_arg)) !=
1472d5ace945SErwin T Tsaur SUCCESS) {
1473d5ace945SErwin T Tsaur break;
1474d5ace945SErwin T Tsaur }
1475d5ace945SErwin T Tsaur if (dvalue)
1476d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(dvalue, "dev",
1477d5ace945SErwin T Tsaur DEV_SPEC_FLAG, flags_arg, device_arg)) !=
1478d5ace945SErwin T Tsaur SUCCESS) {
1479d5ace945SErwin T Tsaur break;
1480d5ace945SErwin T Tsaur }
1481d5ace945SErwin T Tsaur if (fvalue)
1482d5ace945SErwin T Tsaur rval = extract_bdf_arg(fvalue, "func",
1483d5ace945SErwin T Tsaur FUNC_SPEC_FLAG, flags_arg, func_arg);
1484d5ace945SErwin T Tsaur break;
1485d5ace945SErwin T Tsaur }
1486d5ace945SErwin T Tsaur
1487d5ace945SErwin T Tsaur case bus:
1488d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "bus", BUS_SPEC_FLAG,
1489d5ace945SErwin T Tsaur flags_arg, bus_arg);
1490d5ace945SErwin T Tsaur break;
1491d5ace945SErwin T Tsaur
1492d5ace945SErwin T Tsaur /* dev=number */
1493d5ace945SErwin T Tsaur case dev:
1494d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "dev", DEV_SPEC_FLAG,
1495d5ace945SErwin T Tsaur flags_arg, device_arg);
1496d5ace945SErwin T Tsaur break;
1497d5ace945SErwin T Tsaur
1498d5ace945SErwin T Tsaur /* func=number */
1499d5ace945SErwin T Tsaur case func:
1500d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "func", FUNC_SPEC_FLAG,
1501d5ace945SErwin T Tsaur flags_arg, func_arg);
1502d5ace945SErwin T Tsaur break;
1503d5ace945SErwin T Tsaur
1504d5ace945SErwin T Tsaur default:
1505d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -p\n");
1506d5ace945SErwin T Tsaur rval = FAILURE;
1507d5ace945SErwin T Tsaur break;
1508d5ace945SErwin T Tsaur }
1509d5ace945SErwin T Tsaur }
1510d5ace945SErwin T Tsaur
1511d5ace945SErwin T Tsaur return (rval);
1512d5ace945SErwin T Tsaur }
1513d5ace945SErwin T Tsaur
1514d5ace945SErwin T Tsaur
1515d5ace945SErwin T Tsaur #ifdef DEBUG
1516d5ace945SErwin T Tsaur
1517d5ace945SErwin T Tsaur static void
dump_struct(pcitool_uiargs_t * dumpthis)1518d5ace945SErwin T Tsaur dump_struct(pcitool_uiargs_t *dumpthis) {
1519d5ace945SErwin T Tsaur (void) printf("flags:0x%x\n", dumpthis->flags);
1520d5ace945SErwin T Tsaur (void) printf("bus:%d (0x%x)\n",
1521d5ace945SErwin T Tsaur dumpthis->bus, dumpthis->bus);
1522d5ace945SErwin T Tsaur (void) printf("device:%d (0x%x)\n", dumpthis->device,
1523d5ace945SErwin T Tsaur dumpthis->device);
1524d5ace945SErwin T Tsaur (void) printf("function:%d (0x%x)\n", dumpthis->function,
1525d5ace945SErwin T Tsaur dumpthis->function);
1526d5ace945SErwin T Tsaur (void) printf("write_value:%" PRIu64 " (0x%" PRIx64 ")\n",
1527d5ace945SErwin T Tsaur dumpthis->write_value, dumpthis->write_value);
1528d5ace945SErwin T Tsaur (void) printf("bank:%d (0x%x)\n",
1529d5ace945SErwin T Tsaur dumpthis->bank, dumpthis->bank);
1530d5ace945SErwin T Tsaur (void) printf("offset:%d (0x%x)\n", dumpthis->offset, dumpthis->offset);
1531d5ace945SErwin T Tsaur (void) printf("size:%d, endian:%s\n", dumpthis->size,
1532d5ace945SErwin T Tsaur dumpthis->big_endian ? "BIG" : "little");
1533d5ace945SErwin T Tsaur (void) printf("ino:%d, cpu:%d\n",
1534d5ace945SErwin T Tsaur dumpthis->intr_ino, dumpthis->intr_cpu);
1535d5ace945SErwin T Tsaur }
1536d5ace945SErwin T Tsaur
1537d5ace945SErwin T Tsaur #ifdef STANDALONE
1538d5ace945SErwin T Tsaur
1539d5ace945SErwin T Tsaur /* Test program for this module. Useful when implementing new options. */
1540d5ace945SErwin T Tsaur int
main(int argc,char * argv[])1541d5ace945SErwin T Tsaur main(int argc, char *argv[])
1542d5ace945SErwin T Tsaur {
1543d5ace945SErwin T Tsaur int status;
1544d5ace945SErwin T Tsaur pcitool_uiargs_t parsed_args;
1545d5ace945SErwin T Tsaur
1546d5ace945SErwin T Tsaur status = get_commandline_args(argc, argv, &parsed_args);
1547d5ace945SErwin T Tsaur if (status) {
1548d5ace945SErwin T Tsaur (void) printf("Error getting command.\n");
1549d5ace945SErwin T Tsaur }
1550d5ace945SErwin T Tsaur dump_struct(&parsed_args);
1551d5ace945SErwin T Tsaur
1552d5ace945SErwin T Tsaur return (SUCCESS);
1553d5ace945SErwin T Tsaur }
1554d5ace945SErwin T Tsaur
1555d5ace945SErwin T Tsaur #endif /* STANDALONE */
1556d5ace945SErwin T Tsaur #endif /* DEBUG */
1557