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 /* 22d5ace945SErwin T Tsaur * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23d5ace945SErwin T Tsaur * Use is subject to license terms. 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 56d5ace945SErwin T Tsaur #define DEVNAME_START "/pci" 57d5ace945SErwin T Tsaur 58d5ace945SErwin T Tsaur /* Default read/write size when -s not specified. */ 59d5ace945SErwin T Tsaur #define DEFAULT_SIZE 4 60d5ace945SErwin T Tsaur 61d5ace945SErwin T Tsaur /* For get_value64 */ 62d5ace945SErwin T Tsaur #define HEX_ONLY B_TRUE 63d5ace945SErwin T Tsaur #define BASE_BY_PREFIX B_FALSE 64d5ace945SErwin T Tsaur 65d5ace945SErwin T Tsaur #define BITS_PER_BYTE 8 66d5ace945SErwin T Tsaur 67d5ace945SErwin T Tsaur /* 68d5ace945SErwin T Tsaur * This defines which main options can be specified by the user. 69d5ace945SErwin T Tsaur * Options with colons after them require arguments. 70d5ace945SErwin T Tsaur */ 71*09b1eac2SEvan Yan static char *opt_string = ":n:d:i:m:p:rw:o:s:e:b:vaqlcxgy"; 72d5ace945SErwin T Tsaur 73d5ace945SErwin T Tsaur /* This defines options used singly and only by themselves (no nexus). */ 74d5ace945SErwin T Tsaur static char *no_dev_opt_string = "ahpqv"; 75d5ace945SErwin T Tsaur 76d5ace945SErwin T Tsaur static void print_bad_option(char *argv[], int optopt, char *optarg); 77d5ace945SErwin T Tsaur static boolean_t get_confirmation(void); 78d5ace945SErwin T Tsaur static int get_value64(char *value_str, uint64_t *value, boolean_t hex_only); 79d5ace945SErwin T Tsaur static int parse_nexus_opts(char *input, uint64_t *flags_arg, uint8_t *bank_arg, 80d5ace945SErwin T Tsaur uint64_t *base_addr_arg); 81d5ace945SErwin T Tsaur static int extract_bdf_arg(char *cvalue, char *fld, uint64_t fld_flag, 82d5ace945SErwin T Tsaur uint64_t *all_flags, uint8_t *ivalue); 83d5ace945SErwin T Tsaur static int extract_bdf(char *value, char **bvalue_p, char **dvalue_p, 84d5ace945SErwin T Tsaur char **fvalue_p); 85d5ace945SErwin T Tsaur static int parse_device_opts(char *input, uint64_t *flags_arg, 86d5ace945SErwin T Tsaur uint8_t *bus_arg, uint8_t *device_arg, uint8_t *func_arg, 87d5ace945SErwin T Tsaur uint8_t *bank_arg); 88*09b1eac2SEvan Yan static int parse_ino_opts(char *input, uint64_t *flags_arg, uint8_t *ino_arg); 89*09b1eac2SEvan Yan static int parse_msi_opts(char *input, uint64_t *flags_arg, uint16_t *msi_arg); 90d5ace945SErwin T Tsaur static int parse_intr_set_opts(char *input, uint64_t *flags_arg, 91d5ace945SErwin T Tsaur uint32_t *cpu_arg); 92d5ace945SErwin T Tsaur static int parse_probeone_opts(char *input, uint64_t *flags_arg, 93d5ace945SErwin T Tsaur uint8_t *bus_arg, uint8_t *device_arg, uint8_t *func_arg); 94d5ace945SErwin T Tsaur 95d5ace945SErwin T Tsaur #ifdef DEBUG 96d5ace945SErwin T Tsaur void dump_struct(pcitool_uiargs_t *dump_this); 97d5ace945SErwin T Tsaur #endif 98d5ace945SErwin T Tsaur 99d5ace945SErwin T Tsaur /* Exported functions. */ 100d5ace945SErwin T Tsaur 101d5ace945SErwin T Tsaur /* 102d5ace945SErwin T Tsaur * Main commandline argument parsing routine. 103d5ace945SErwin T Tsaur * 104d5ace945SErwin T Tsaur * Takes argc and argv straight from the commandline. 105d5ace945SErwin T Tsaur * Returns a pcitool_uiargs_t with flags of options specified, and values 106d5ace945SErwin T Tsaur * associated with them. 107d5ace945SErwin T Tsaur */ 108d5ace945SErwin T Tsaur int 109d5ace945SErwin T Tsaur get_commandline_args(int argc, char *argv[], pcitool_uiargs_t *parsed_args) 110d5ace945SErwin T Tsaur { 111d5ace945SErwin T Tsaur int c; /* Current option being processed. */ 112d5ace945SErwin T Tsaur boolean_t error = B_FALSE; 113d5ace945SErwin T Tsaur boolean_t confirm = B_FALSE; 114d5ace945SErwin T Tsaur uint64_t recv64; 115d5ace945SErwin T Tsaur 116d5ace945SErwin T Tsaur /* Needed for getopt(3C) */ 117d5ace945SErwin T Tsaur extern char *optarg; /* Current commandline string. */ 118d5ace945SErwin T Tsaur extern int optind; /* Index of current commandline string. */ 119d5ace945SErwin T Tsaur extern int optopt; /* Option (char) which is missing an operand. */ 120d5ace945SErwin T Tsaur extern int opterr; /* Set to 0 to disable getopt err reporting. */ 121d5ace945SErwin T Tsaur 122d5ace945SErwin T Tsaur opterr = 0; 123d5ace945SErwin T Tsaur 124d5ace945SErwin T Tsaur bzero(parsed_args, sizeof (pcitool_uiargs_t)); 125d5ace945SErwin T Tsaur 126d5ace945SErwin T Tsaur /* No args. probe mode accounting for bus ranges, nonverbose. */ 127d5ace945SErwin T Tsaur if (argc == 1) { 128d5ace945SErwin T Tsaur usage(argv[0]); 129d5ace945SErwin T Tsaur parsed_args->flags = 0; 130d5ace945SErwin T Tsaur return (SUCCESS); 131d5ace945SErwin T Tsaur } 132d5ace945SErwin T Tsaur 133d5ace945SErwin T Tsaur /* 1st arg is not a device name. */ 134d5ace945SErwin T Tsaur if (strstr(argv[1], DEVNAME_START) != argv[1]) { 135d5ace945SErwin T Tsaur 136d5ace945SErwin T Tsaur /* Default is to probe all trees accounting for bus ranges. */ 137d5ace945SErwin T Tsaur parsed_args->flags = PROBEALL_FLAG | PROBERNG_FLAG; 138d5ace945SErwin T Tsaur 139d5ace945SErwin T Tsaur /* Loop thru the options until complete or an error is found. */ 140d5ace945SErwin T Tsaur while (((c = getopt(argc, argv, no_dev_opt_string)) != -1) && 141d5ace945SErwin T Tsaur (error == B_FALSE)) { 142d5ace945SErwin T Tsaur 143d5ace945SErwin T Tsaur switch (c) { 144d5ace945SErwin T Tsaur 145d5ace945SErwin T Tsaur /* Help requested. */ 146d5ace945SErwin T Tsaur case 'h': 147d5ace945SErwin T Tsaur usage(argv[0]); 148d5ace945SErwin T Tsaur parsed_args->flags = 0; 149d5ace945SErwin T Tsaur return (SUCCESS); 150d5ace945SErwin T Tsaur 151d5ace945SErwin T Tsaur case 'p': 152d5ace945SErwin T Tsaur /* Take default probe mode */ 153d5ace945SErwin T Tsaur break; 154d5ace945SErwin T Tsaur 155d5ace945SErwin T Tsaur case 'a': 156d5ace945SErwin T Tsaur /* 157d5ace945SErwin T Tsaur * Enable display of ALL bus numbers. 158d5ace945SErwin T Tsaur * 159d5ace945SErwin T Tsaur * This takes precidence over PROBERNG as -a 160d5ace945SErwin T Tsaur * is explicitly specified. 161d5ace945SErwin T Tsaur */ 162d5ace945SErwin T Tsaur parsed_args->flags &= ~PROBERNG_FLAG; 163d5ace945SErwin T Tsaur break; 164d5ace945SErwin T Tsaur 165d5ace945SErwin T Tsaur case 'q': 166d5ace945SErwin T Tsaur parsed_args->flags |= QUIET_FLAG; 167d5ace945SErwin T Tsaur break; 168d5ace945SErwin T Tsaur 169d5ace945SErwin T Tsaur /* Verbose mode for full probe. */ 170d5ace945SErwin T Tsaur case 'v': 171d5ace945SErwin T Tsaur parsed_args->flags |= VERBOSE_FLAG; 172d5ace945SErwin T Tsaur break; 173d5ace945SErwin T Tsaur 174d5ace945SErwin T Tsaur default: 175d5ace945SErwin T Tsaur error = B_TRUE; 176d5ace945SErwin T Tsaur break; 177d5ace945SErwin T Tsaur } 178d5ace945SErwin T Tsaur } 179d5ace945SErwin T Tsaur 180d5ace945SErwin T Tsaur /* Check for values straggling at the end of the command. */ 181d5ace945SErwin T Tsaur if (optind != argc) { 182d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Unrecognized parameter " 183d5ace945SErwin T Tsaur "at the end of the command.\n", argv[0]); 184d5ace945SErwin T Tsaur error = B_TRUE; 185d5ace945SErwin T Tsaur } 186d5ace945SErwin T Tsaur 187d5ace945SErwin T Tsaur if (error) { 188d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg); 189d5ace945SErwin T Tsaur return (FAILURE); 190d5ace945SErwin T Tsaur } 191d5ace945SErwin T Tsaur 192d5ace945SErwin T Tsaur return (SUCCESS); 193d5ace945SErwin T Tsaur } 194d5ace945SErwin T Tsaur 195d5ace945SErwin T Tsaur /* Device node specified on commandline. */ 196d5ace945SErwin T Tsaur 197d5ace945SErwin T Tsaur /* Skip argv[1] before continuing below. */ 198d5ace945SErwin T Tsaur optind++; 199d5ace945SErwin T Tsaur 200d5ace945SErwin T Tsaur /* Loop through the options until complete or an error is found. */ 201d5ace945SErwin T Tsaur while (((c = getopt(argc, argv, opt_string)) != -1) && 202d5ace945SErwin T Tsaur (error == B_FALSE)) { 203d5ace945SErwin T Tsaur 204d5ace945SErwin T Tsaur switch (c) { 205d5ace945SErwin T Tsaur 206d5ace945SErwin T Tsaur /* Nexus */ 207d5ace945SErwin T Tsaur case 'n': 208d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | 209d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) { 210d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -n set with " 211d5ace945SErwin T Tsaur "-d, -p or -i or is set twice\n", argv[0]); 212d5ace945SErwin T Tsaur error = B_TRUE; 213d5ace945SErwin T Tsaur break; 214d5ace945SErwin T Tsaur } 215d5ace945SErwin T Tsaur parsed_args->flags |= NEXUS_FLAG; 216d5ace945SErwin T Tsaur if (parse_nexus_opts(optarg, &parsed_args->flags, 217d5ace945SErwin T Tsaur &parsed_args->bank, &parsed_args->base_address) != 218d5ace945SErwin T Tsaur SUCCESS) { 219d5ace945SErwin T Tsaur (void) fprintf(stderr, 220d5ace945SErwin T Tsaur "%s: Error parsing -n options\n", argv[0]); 221d5ace945SErwin T Tsaur error = B_TRUE; 222d5ace945SErwin T Tsaur break; 223d5ace945SErwin T Tsaur } 224d5ace945SErwin T Tsaur break; 225d5ace945SErwin T Tsaur 226d5ace945SErwin T Tsaur /* Device (leaf node) */ 227d5ace945SErwin T Tsaur case 'd': 228d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | 229d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) { 230d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -d set with " 231d5ace945SErwin T Tsaur "-n, -p or -i or is set twice\n", argv[0]); 232d5ace945SErwin T Tsaur error = B_TRUE; 233d5ace945SErwin T Tsaur break; 234d5ace945SErwin T Tsaur } 235d5ace945SErwin T Tsaur parsed_args->flags |= LEAF_FLAG; 236d5ace945SErwin T Tsaur if (parse_device_opts(optarg, &parsed_args->flags, 237d5ace945SErwin T Tsaur &parsed_args->bus, &parsed_args->device, 238d5ace945SErwin T Tsaur &parsed_args->function, 239d5ace945SErwin T Tsaur &parsed_args->bank) != SUCCESS) { 240d5ace945SErwin T Tsaur (void) fprintf(stderr, 241d5ace945SErwin T Tsaur "%s: Error parsing -d options\n", argv[0]); 242d5ace945SErwin T Tsaur error = B_TRUE; 243d5ace945SErwin T Tsaur break; 244d5ace945SErwin T Tsaur } 245d5ace945SErwin T Tsaur break; 246d5ace945SErwin T Tsaur 247d5ace945SErwin T Tsaur /* Interrupt */ 248d5ace945SErwin T Tsaur case 'i': 249d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | 250d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) { 251*09b1eac2SEvan Yan (void) fprintf(stderr, "%s: -i set with -m, " 252d5ace945SErwin T Tsaur "-n, -d or -p or is set twice\n", argv[0]); 253d5ace945SErwin T Tsaur error = B_TRUE; 254d5ace945SErwin T Tsaur break; 255d5ace945SErwin T Tsaur } 256d5ace945SErwin T Tsaur parsed_args->flags |= INTR_FLAG; 257d5ace945SErwin T Tsaur 258d5ace945SErwin T Tsaur /* parse input to get ino value. */ 259*09b1eac2SEvan Yan if (parse_ino_opts(optarg, &parsed_args->flags, 260d5ace945SErwin T Tsaur &parsed_args->intr_ino) != SUCCESS) { 261d5ace945SErwin T Tsaur (void) fprintf(stderr, 262d5ace945SErwin T Tsaur "%s: Error parsing interrupt options\n", 263d5ace945SErwin T Tsaur argv[0]); 264d5ace945SErwin T Tsaur error = B_TRUE; 265d5ace945SErwin T Tsaur } 266d5ace945SErwin T Tsaur break; 267*09b1eac2SEvan Yan /* Interrupt */ 268*09b1eac2SEvan Yan case 'm': 269*09b1eac2SEvan Yan if (parsed_args->flags & (LEAF_FLAG | 270*09b1eac2SEvan Yan NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) { 271*09b1eac2SEvan Yan (void) fprintf(stderr, "%s: -m set with -i, " 272*09b1eac2SEvan Yan "-n, -d or -p or is set twice\n", argv[0]); 273*09b1eac2SEvan Yan error = B_TRUE; 274*09b1eac2SEvan Yan break; 275*09b1eac2SEvan Yan } 276*09b1eac2SEvan Yan parsed_args->flags |= INTR_FLAG; 277d5ace945SErwin T Tsaur 278*09b1eac2SEvan Yan /* parse input to get msi value. */ 279*09b1eac2SEvan Yan if (parse_msi_opts(optarg, &parsed_args->flags, 280*09b1eac2SEvan Yan &parsed_args->intr_msi) != SUCCESS) { 281*09b1eac2SEvan Yan (void) fprintf(stderr, 282*09b1eac2SEvan Yan "%s: Error parsing interrupt options\n", 283*09b1eac2SEvan Yan argv[0]); 284*09b1eac2SEvan Yan error = B_TRUE; 285*09b1eac2SEvan Yan } 286*09b1eac2SEvan Yan break; 287d5ace945SErwin T Tsaur /* Probe */ 288d5ace945SErwin T Tsaur case 'p': 289d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | 290d5ace945SErwin T Tsaur NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS)) { 291d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -p set with " 292d5ace945SErwin T Tsaur "-n, -d or -i or is set twice\n", argv[0]); 293d5ace945SErwin T Tsaur error = B_TRUE; 294d5ace945SErwin T Tsaur break; 295d5ace945SErwin T Tsaur } 296d5ace945SErwin T Tsaur 297d5ace945SErwin T Tsaur /* Process -p with no dedicated options to it. */ 298d5ace945SErwin T Tsaur if (optarg[0] == '-') { 299d5ace945SErwin T Tsaur optind--; 300d5ace945SErwin T Tsaur 301d5ace945SErwin T Tsaur /* Probe given tree observing ranges */ 302d5ace945SErwin T Tsaur parsed_args->flags |= 303d5ace945SErwin T Tsaur (PROBETREE_FLAG | PROBERNG_FLAG); 304d5ace945SErwin T Tsaur continue; 305d5ace945SErwin T Tsaur } 306d5ace945SErwin T Tsaur 307d5ace945SErwin T Tsaur /* parse input to get ino value. */ 308d5ace945SErwin T Tsaur if (parse_probeone_opts(optarg, &parsed_args->flags, 309d5ace945SErwin T Tsaur &parsed_args->bus, &parsed_args->device, 310d5ace945SErwin T Tsaur &parsed_args->function) != SUCCESS) { 311d5ace945SErwin T Tsaur (void) fprintf(stderr, 312d5ace945SErwin T Tsaur "%s: Error parsing probe options\n", 313d5ace945SErwin T Tsaur argv[0]); 314d5ace945SErwin T Tsaur error = B_TRUE; 315d5ace945SErwin T Tsaur } else { 316d5ace945SErwin T Tsaur /* 317d5ace945SErwin T Tsaur * parse_probeone_opts found options to 318d5ace945SErwin T Tsaur * set up bdf. 319d5ace945SErwin T Tsaur */ 320d5ace945SErwin T Tsaur parsed_args->flags |= PROBEDEV_FLAG; 321d5ace945SErwin T Tsaur } 322d5ace945SErwin T Tsaur break; 323d5ace945SErwin T Tsaur 324d5ace945SErwin T Tsaur /* Probe all busses */ 325d5ace945SErwin T Tsaur case 'a': 326d5ace945SErwin T Tsaur /* Must follow -p, and -p must have no bdf. */ 327d5ace945SErwin T Tsaur if (!(parsed_args->flags & PROBETREE_FLAG)) { 328d5ace945SErwin T Tsaur error = B_TRUE; 329d5ace945SErwin T Tsaur break; 330d5ace945SErwin T Tsaur } 331d5ace945SErwin T Tsaur 332d5ace945SErwin T Tsaur parsed_args->flags &= ~PROBERNG_FLAG; 333d5ace945SErwin T Tsaur break; 334d5ace945SErwin T Tsaur 335d5ace945SErwin T Tsaur /* Read */ 336d5ace945SErwin T Tsaur case 'r': 337d5ace945SErwin T Tsaur if (!(parsed_args->flags & 338d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG))) { 339d5ace945SErwin T Tsaur error = B_TRUE; 340d5ace945SErwin T Tsaur break; 341d5ace945SErwin T Tsaur } 342d5ace945SErwin T Tsaur 343d5ace945SErwin T Tsaur /* 344d5ace945SErwin T Tsaur * Allow read and write to be set together for now, 345d5ace945SErwin T Tsaur * since this means write then read back for device and 346d5ace945SErwin T Tsaur * nexus accesses. Check for this and disallow with 347d5ace945SErwin T Tsaur * interrupt command later. 348d5ace945SErwin T Tsaur */ 349d5ace945SErwin T Tsaur parsed_args->flags |= READ_FLAG; 350d5ace945SErwin T Tsaur break; 351d5ace945SErwin T Tsaur 352d5ace945SErwin T Tsaur /* Write */ 353d5ace945SErwin T Tsaur case 'w': 354d5ace945SErwin T Tsaur if (!(parsed_args->flags & 355d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG))) { 356d5ace945SErwin T Tsaur error = B_TRUE; 357d5ace945SErwin T Tsaur break; 358d5ace945SErwin T Tsaur } 359d5ace945SErwin T Tsaur if (parsed_args->flags & WRITE_FLAG) { 360d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -w set twice\n", 361d5ace945SErwin T Tsaur argv[0]); 362d5ace945SErwin T Tsaur error = B_TRUE; 363d5ace945SErwin T Tsaur break; 364d5ace945SErwin T Tsaur } 365d5ace945SErwin T Tsaur 366d5ace945SErwin T Tsaur /* 367d5ace945SErwin T Tsaur * For device and nexus, get a single register value 368d5ace945SErwin T Tsaur * to write. 369d5ace945SErwin T Tsaur */ 370d5ace945SErwin T Tsaur if (parsed_args->flags & (NEXUS_FLAG | LEAF_FLAG)) { 371d5ace945SErwin T Tsaur parsed_args->flags |= WRITE_FLAG; 372d5ace945SErwin T Tsaur if (get_value64(optarg, 373d5ace945SErwin T Tsaur &parsed_args->write_value, HEX_ONLY) != 374d5ace945SErwin T Tsaur SUCCESS) { 375d5ace945SErwin T Tsaur (void) fprintf(stderr, 376d5ace945SErwin T Tsaur "%s: Error reading value to " 377d5ace945SErwin T Tsaur "write.\n", argv[0]); 378d5ace945SErwin T Tsaur error = B_TRUE; 379d5ace945SErwin T Tsaur break; 380d5ace945SErwin T Tsaur } 381d5ace945SErwin T Tsaur 382d5ace945SErwin T Tsaur /* For interrupt, parse input to get cpu value. */ 383d5ace945SErwin T Tsaur } else if (parsed_args->flags & INTR_FLAG) { 384d5ace945SErwin T Tsaur parsed_args->flags |= WRITE_FLAG; 385d5ace945SErwin T Tsaur if (parse_intr_set_opts(optarg, 386d5ace945SErwin T Tsaur &parsed_args->flags, 387d5ace945SErwin T Tsaur &parsed_args->intr_cpu) != SUCCESS) { 388d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Error " 389d5ace945SErwin T Tsaur "parsing interrupt options.\n", 390d5ace945SErwin T Tsaur argv[0]); 391d5ace945SErwin T Tsaur error = B_TRUE; 392d5ace945SErwin T Tsaur break; 393d5ace945SErwin T Tsaur } 394d5ace945SErwin T Tsaur 395d5ace945SErwin T Tsaur } else { 396d5ace945SErwin T Tsaur error = B_TRUE; 397d5ace945SErwin T Tsaur break; 398d5ace945SErwin T Tsaur } 399d5ace945SErwin T Tsaur break; 400d5ace945SErwin T Tsaur 401d5ace945SErwin T Tsaur /* Offset */ 402d5ace945SErwin T Tsaur case 'o': 403d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) { 404d5ace945SErwin T Tsaur error = B_TRUE; 405d5ace945SErwin T Tsaur break; 406d5ace945SErwin T Tsaur } 407d5ace945SErwin T Tsaur if (parsed_args->flags & OFFSET_FLAG) { 408d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -o set twice\n", 409d5ace945SErwin T Tsaur argv[0]); 410d5ace945SErwin T Tsaur error = B_TRUE; 411d5ace945SErwin T Tsaur break; 412d5ace945SErwin T Tsaur } 413d5ace945SErwin T Tsaur parsed_args->flags |= OFFSET_FLAG; 414d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) { 415d5ace945SErwin T Tsaur (void) fprintf(stderr, 416d5ace945SErwin T Tsaur "%s: Error in offset argument\n", argv[0]); 417d5ace945SErwin T Tsaur error = B_TRUE; 418d5ace945SErwin T Tsaur break; 419d5ace945SErwin T Tsaur } 420d5ace945SErwin T Tsaur parsed_args->offset = (uint32_t)recv64; 421d5ace945SErwin T Tsaur if (parsed_args->offset != recv64) { 422d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Offset argument " 423d5ace945SErwin T Tsaur "too large for 32 bits\n", argv[0]); 424d5ace945SErwin T Tsaur error = B_TRUE; 425d5ace945SErwin T Tsaur break; 426d5ace945SErwin T Tsaur } 427d5ace945SErwin T Tsaur break; 428d5ace945SErwin T Tsaur 429d5ace945SErwin T Tsaur /* Size */ 430d5ace945SErwin T Tsaur case 's': 431d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) { 432d5ace945SErwin T Tsaur error = B_TRUE; 433d5ace945SErwin T Tsaur break; 434d5ace945SErwin T Tsaur } 435d5ace945SErwin T Tsaur if (parsed_args->flags & SIZE_FLAG) { 436d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -s set twice\n", 437d5ace945SErwin T Tsaur argv[0]); 438d5ace945SErwin T Tsaur error = B_TRUE; 439d5ace945SErwin T Tsaur break; 440d5ace945SErwin T Tsaur } 441d5ace945SErwin T Tsaur parsed_args->flags |= SIZE_FLAG; 442d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) { 443d5ace945SErwin T Tsaur (void) fprintf(stderr, 444d5ace945SErwin T Tsaur "%s: Error in size argument\n", argv[0]); 445d5ace945SErwin T Tsaur error = B_TRUE; 446d5ace945SErwin T Tsaur break; 447d5ace945SErwin T Tsaur } 448d5ace945SErwin T Tsaur switch (recv64) { 449d5ace945SErwin T Tsaur case 1: 450d5ace945SErwin T Tsaur case 2: 451d5ace945SErwin T Tsaur case 4: 452d5ace945SErwin T Tsaur case 8: 453d5ace945SErwin T Tsaur break; 454d5ace945SErwin T Tsaur default: 455d5ace945SErwin T Tsaur error = B_TRUE; 456d5ace945SErwin T Tsaur (void) fprintf(stderr, 457d5ace945SErwin T Tsaur "%s: Error in size argument\n", argv[0]); 458d5ace945SErwin T Tsaur break; 459d5ace945SErwin T Tsaur } 460d5ace945SErwin T Tsaur parsed_args->size |= (uint8_t)recv64; 461d5ace945SErwin T Tsaur break; 462d5ace945SErwin T Tsaur 463d5ace945SErwin T Tsaur /* Endian. */ 464d5ace945SErwin T Tsaur case 'e': 465d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) { 466d5ace945SErwin T Tsaur error = B_TRUE; 467d5ace945SErwin T Tsaur break; 468d5ace945SErwin T Tsaur } 469d5ace945SErwin T Tsaur if (parsed_args->flags & ENDIAN_FLAG) { 470d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -e set twice\n", 471d5ace945SErwin T Tsaur argv[0]); 472d5ace945SErwin T Tsaur error = B_TRUE; 473d5ace945SErwin T Tsaur break; 474d5ace945SErwin T Tsaur } 475d5ace945SErwin T Tsaur parsed_args->flags |= ENDIAN_FLAG; 476d5ace945SErwin T Tsaur 477d5ace945SErwin T Tsaur /* Only a single character allowed. */ 478d5ace945SErwin T Tsaur if (optarg[1] != '\0') { 479d5ace945SErwin T Tsaur (void) fprintf(stderr, 480d5ace945SErwin T Tsaur "%s: Error in endian argument\n", argv[0]); 481d5ace945SErwin T Tsaur error = B_TRUE; 482d5ace945SErwin T Tsaur break; 483d5ace945SErwin T Tsaur } 484d5ace945SErwin T Tsaur 485d5ace945SErwin T Tsaur switch (optarg[0]) { 486d5ace945SErwin T Tsaur case 'b': 487d5ace945SErwin T Tsaur parsed_args->big_endian = B_TRUE; 488d5ace945SErwin T Tsaur break; 489d5ace945SErwin T Tsaur case 'l': 490d5ace945SErwin T Tsaur break; 491d5ace945SErwin T Tsaur default: 492d5ace945SErwin T Tsaur (void) fprintf(stderr, 493d5ace945SErwin T Tsaur "%s: Error in endian argument\n", argv[0]); 494d5ace945SErwin T Tsaur error = B_TRUE; 495d5ace945SErwin T Tsaur break; 496d5ace945SErwin T Tsaur } 497d5ace945SErwin T Tsaur break; 498d5ace945SErwin T Tsaur 499d5ace945SErwin T Tsaur /* (Byte)dump */ 500d5ace945SErwin T Tsaur case 'b': 501d5ace945SErwin T Tsaur if (!(parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG))) { 502d5ace945SErwin T Tsaur error = B_TRUE; 503d5ace945SErwin T Tsaur break; 504d5ace945SErwin T Tsaur } 505d5ace945SErwin T Tsaur if (parsed_args->flags & BYTEDUMP_FLAG) { 506d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -b set twice\n", 507d5ace945SErwin T Tsaur argv[0]); 508d5ace945SErwin T Tsaur error = B_TRUE; 509d5ace945SErwin T Tsaur break; 510d5ace945SErwin T Tsaur } 511d5ace945SErwin T Tsaur parsed_args->flags |= BYTEDUMP_FLAG; 512d5ace945SErwin T Tsaur if (get_value64(optarg, &recv64, HEX_ONLY) != SUCCESS) { 513d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Error in " 514d5ace945SErwin T Tsaur "bytedump argument\n", argv[0]); 515d5ace945SErwin T Tsaur error = B_TRUE; 516d5ace945SErwin T Tsaur break; 517d5ace945SErwin T Tsaur } 518d5ace945SErwin T Tsaur parsed_args->bytedump_amt = (uint32_t)recv64; 519d5ace945SErwin T Tsaur if (parsed_args->bytedump_amt != recv64) { 520d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Bytedump amount " 521d5ace945SErwin T Tsaur "too large for 32 bits\n", argv[0]); 522d5ace945SErwin T Tsaur error = B_TRUE; 523d5ace945SErwin T Tsaur break; 524d5ace945SErwin T Tsaur } 525d5ace945SErwin T Tsaur break; 526d5ace945SErwin T Tsaur 527d5ace945SErwin T Tsaur /* Verbose. */ 528d5ace945SErwin T Tsaur case 'v': 529d5ace945SErwin T Tsaur parsed_args->flags |= VERBOSE_FLAG; 530d5ace945SErwin T Tsaur break; 531d5ace945SErwin T Tsaur 532d5ace945SErwin T Tsaur /* 533d5ace945SErwin T Tsaur * Quiet - no errors reported as messages. 534d5ace945SErwin T Tsaur * (Status still returned by program, however.) 535d5ace945SErwin T Tsaur */ 536d5ace945SErwin T Tsaur case 'q': 537d5ace945SErwin T Tsaur parsed_args->flags |= QUIET_FLAG; 538d5ace945SErwin T Tsaur break; 539d5ace945SErwin T Tsaur 540d5ace945SErwin T Tsaur /* Loop. */ 541d5ace945SErwin T Tsaur case 'l': 542d5ace945SErwin T Tsaur parsed_args->flags |= LOOP_FLAG; 543d5ace945SErwin T Tsaur break; 544d5ace945SErwin T Tsaur 545d5ace945SErwin T Tsaur /* 546d5ace945SErwin T Tsaur * Dump characters with bytedump (-b). 547d5ace945SErwin T Tsaur * Show controller info with -i. 548d5ace945SErwin T Tsaur */ 549d5ace945SErwin T Tsaur case 'c': 550d5ace945SErwin T Tsaur if (parsed_args->flags & BYTEDUMP_FLAG) { 551d5ace945SErwin T Tsaur parsed_args->flags |= CHARDUMP_FLAG; 552d5ace945SErwin T Tsaur 553d5ace945SErwin T Tsaur } else if (parsed_args->flags & INTR_FLAG) { 554d5ace945SErwin T Tsaur parsed_args->flags |= SHOWCTLR_FLAG; 555d5ace945SErwin T Tsaur 556d5ace945SErwin T Tsaur } else { 557d5ace945SErwin T Tsaur error = B_TRUE; 558d5ace945SErwin T Tsaur } 559d5ace945SErwin T Tsaur break; 560d5ace945SErwin T Tsaur 561d5ace945SErwin T Tsaur /* Continue on errors with bytedump (-b). */ 562d5ace945SErwin T Tsaur case 'x': 563d5ace945SErwin T Tsaur if (!(parsed_args->flags & BYTEDUMP_FLAG)) { 564d5ace945SErwin T Tsaur error = B_TRUE; 565d5ace945SErwin T Tsaur break; 566d5ace945SErwin T Tsaur } 567d5ace945SErwin T Tsaur parsed_args->flags |= ERRCONT_FLAG; 568d5ace945SErwin T Tsaur break; 569d5ace945SErwin T Tsaur 570d5ace945SErwin T Tsaur case 'g': 571d5ace945SErwin T Tsaur if (!(parsed_args->flags & INTR_FLAG)) { 572d5ace945SErwin T Tsaur error = B_TRUE; 573d5ace945SErwin T Tsaur break; 574d5ace945SErwin T Tsaur } 575d5ace945SErwin T Tsaur parsed_args->flags |= SETGRP_FLAG; 576d5ace945SErwin T Tsaur break; 577d5ace945SErwin T Tsaur 578d5ace945SErwin T Tsaur /* Take -y as confirmation and don't ask (where applicable). */ 579d5ace945SErwin T Tsaur case 'y': 580d5ace945SErwin T Tsaur confirm = B_TRUE; 581d5ace945SErwin T Tsaur break; 582d5ace945SErwin T Tsaur 583d5ace945SErwin T Tsaur /* Option without operand. */ 584d5ace945SErwin T Tsaur case ':': 585d5ace945SErwin T Tsaur switch (optopt) { 586d5ace945SErwin T Tsaur case 'p': 587d5ace945SErwin T Tsaur /* Allow -p without bdf spec. */ 588d5ace945SErwin T Tsaur parsed_args->flags |= 589d5ace945SErwin T Tsaur (PROBETREE_FLAG | PROBERNG_FLAG); 590d5ace945SErwin T Tsaur break; 591d5ace945SErwin T Tsaur default: 592d5ace945SErwin T Tsaur error = B_TRUE; 593d5ace945SErwin T Tsaur break; 594d5ace945SErwin T Tsaur } 595d5ace945SErwin T Tsaur break; 596d5ace945SErwin T Tsaur 597d5ace945SErwin T Tsaur /* Unrecognized option. */ 598d5ace945SErwin T Tsaur case '?': 599d5ace945SErwin T Tsaur error = B_TRUE; 600d5ace945SErwin T Tsaur break; 601d5ace945SErwin T Tsaur } 602d5ace945SErwin T Tsaur } 603d5ace945SErwin T Tsaur 604d5ace945SErwin T Tsaur /* 605d5ace945SErwin T Tsaur * Commandline has been parsed. Check for errors which can be checked 606d5ace945SErwin T Tsaur * only after commandline parsing is complete. 607d5ace945SErwin T Tsaur */ 608d5ace945SErwin T Tsaur 609d5ace945SErwin T Tsaur if (!error) { 610d5ace945SErwin T Tsaur 611d5ace945SErwin T Tsaur /* Check for values straggling at the end of the command. */ 612d5ace945SErwin T Tsaur if (optind != argc) { 613d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Unrecognized parameter " 614d5ace945SErwin T Tsaur "at the end of the command.\n", argv[0]); 615d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg); 616d5ace945SErwin T Tsaur return (FAILURE); 617d5ace945SErwin T Tsaur } 618d5ace945SErwin T Tsaur 619d5ace945SErwin T Tsaur /* No args other than nexus. Default to probing that nexus */ 620d5ace945SErwin T Tsaur if (!(parsed_args->flags & 621d5ace945SErwin T Tsaur (LEAF_FLAG | NEXUS_FLAG | INTR_FLAG | PROBE_FLAGS))) { 622d5ace945SErwin T Tsaur usage(argv[0]); 623d5ace945SErwin T Tsaur parsed_args->flags = 0; 624d5ace945SErwin T Tsaur return (SUCCESS); 625d5ace945SErwin T Tsaur } 626d5ace945SErwin T Tsaur 627d5ace945SErwin T Tsaur /* 628d5ace945SErwin T Tsaur * Don't allow any options other than all-bus, verbose or 629d5ace945SErwin T Tsaur * quiet with probe command. Set default probe flags if nexus 630d5ace945SErwin T Tsaur * or leaf options are not specified. 631d5ace945SErwin T Tsaur */ 632d5ace945SErwin T Tsaur if (parsed_args->flags & (PROBETREE_FLAG | PROBEALL_FLAG)) { 633d5ace945SErwin T Tsaur if (parsed_args->flags & 634d5ace945SErwin T Tsaur ~(PROBE_FLAGS | QUIET_FLAG | VERBOSE_FLAG)) 635d5ace945SErwin T Tsaur error = B_TRUE; 636d5ace945SErwin T Tsaur } 637d5ace945SErwin T Tsaur 638d5ace945SErwin T Tsaur /* 639d5ace945SErwin T Tsaur * Allow only read, write, quiet and verbose flags for 640d5ace945SErwin T Tsaur * interrupt command. Note that INO_SPEC_FLAG and CPU_SPEC_FLAG 641d5ace945SErwin T Tsaur * get set for interrupt command. 642d5ace945SErwin T Tsaur */ 643d5ace945SErwin T Tsaur if (parsed_args->flags & INTR_FLAG) { 644d5ace945SErwin T Tsaur if (parsed_args->flags & 645d5ace945SErwin T Tsaur ~(INTR_FLAG | VERBOSE_FLAG | QUIET_FLAG | 646d5ace945SErwin T Tsaur READ_FLAG | WRITE_FLAG | SHOWCTLR_FLAG | 647*09b1eac2SEvan Yan SETGRP_FLAG | INO_ALL_FLAG | INO_SPEC_FLAG | 648*09b1eac2SEvan Yan MSI_ALL_FLAG | MSI_SPEC_FLAG | CPU_SPEC_FLAG)) { 649d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -v, -q, -r, -w, -c " 650*09b1eac2SEvan Yan "-g are only options allowed with " 651*09b1eac2SEvan Yan "interrupt command.\n", argv[0]); 652d5ace945SErwin T Tsaur error = B_TRUE; 653d5ace945SErwin T Tsaur } 654d5ace945SErwin T Tsaur 655d5ace945SErwin T Tsaur /* Need cpu and ino values for interrupt set command. */ 656d5ace945SErwin T Tsaur if ((parsed_args->flags & WRITE_FLAG) && 657*09b1eac2SEvan Yan !(parsed_args->flags & CPU_SPEC_FLAG) && 658*09b1eac2SEvan Yan !((parsed_args->flags & INO_SPEC_FLAG) || 659*09b1eac2SEvan Yan (parsed_args->flags & MSI_SPEC_FLAG))) { 660d5ace945SErwin T Tsaur (void) fprintf(stderr, 661*09b1eac2SEvan Yan "%s: Both cpu and ino/msi must be " 662*09b1eac2SEvan Yan "specified explicitly for interrupt " 663*09b1eac2SEvan Yan "set command.\n", argv[0]); 664d5ace945SErwin T Tsaur error = B_TRUE; 665d5ace945SErwin T Tsaur } 666d5ace945SErwin T Tsaur 667d5ace945SErwin T Tsaur /* Intr write and show ctlr flags are incompatible. */ 668d5ace945SErwin T Tsaur if ((parsed_args->flags & 669d5ace945SErwin T Tsaur (WRITE_FLAG + SHOWCTLR_FLAG)) == 670d5ace945SErwin T Tsaur (WRITE_FLAG + SHOWCTLR_FLAG)) { 671d5ace945SErwin T Tsaur (void) fprintf(stderr, 672d5ace945SErwin T Tsaur "%s: -w and -c are incompatible for " 673d5ace945SErwin T Tsaur "interrupt command.\n", argv[0]); 674d5ace945SErwin T Tsaur error = B_TRUE; 675d5ace945SErwin T Tsaur } 676d5ace945SErwin T Tsaur 677d5ace945SErwin T Tsaur /* Intr setgrp flag valid only for intr writes. */ 678d5ace945SErwin T Tsaur if ((parsed_args->flags & (WRITE_FLAG + SETGRP_FLAG)) == 679d5ace945SErwin T Tsaur SETGRP_FLAG) { 680d5ace945SErwin T Tsaur (void) fprintf(stderr, 681d5ace945SErwin T Tsaur "%s: -g is incompatible with -r " 682d5ace945SErwin T Tsaur "for interrupt command.\n", argv[0]); 683d5ace945SErwin T Tsaur error = B_TRUE; 684d5ace945SErwin T Tsaur } 685d5ace945SErwin T Tsaur 686d5ace945SErwin T Tsaur /* 687d5ace945SErwin T Tsaur * Disallow read & write together in interrupt command. 688d5ace945SErwin T Tsaur */ 689d5ace945SErwin T Tsaur if ((parsed_args->flags & (WRITE_FLAG | READ_FLAG)) == 690d5ace945SErwin T Tsaur (WRITE_FLAG | READ_FLAG)) { 691d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: Only one of -r and " 692d5ace945SErwin T Tsaur "-w can be specified in " 693d5ace945SErwin T Tsaur "interrupt command.\n", argv[0]); 694d5ace945SErwin T Tsaur error = B_TRUE; 695d5ace945SErwin T Tsaur } 696d5ace945SErwin T Tsaur } 697d5ace945SErwin T Tsaur 698d5ace945SErwin T Tsaur /* Bytedump incompatible with some other options. */ 699d5ace945SErwin T Tsaur if ((parsed_args->flags & BYTEDUMP_FLAG) && 700d5ace945SErwin T Tsaur (parsed_args->flags & 701d5ace945SErwin T Tsaur (WRITE_FLAG | PROBE_FLAGS | INTR_FLAG))) { 702d5ace945SErwin T Tsaur (void) fprintf(stderr, 703d5ace945SErwin T Tsaur "%s: -b is incompatible with " 704d5ace945SErwin T Tsaur "another specified option.\n", argv[0]); 705d5ace945SErwin T Tsaur error = B_TRUE; 706d5ace945SErwin T Tsaur } 707d5ace945SErwin T Tsaur 708d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG)) { 709d5ace945SErwin T Tsaur 710d5ace945SErwin T Tsaur if (!(parsed_args->flags & SIZE_FLAG)) { 711d5ace945SErwin T Tsaur parsed_args->size = DEFAULT_SIZE; 712d5ace945SErwin T Tsaur } 713d5ace945SErwin T Tsaur if ((parsed_args->flags & WRITE_FLAG) && 714d5ace945SErwin T Tsaur parsed_args->size < sizeof (uint64_t) && 715d5ace945SErwin T Tsaur (parsed_args->write_value >> 716d5ace945SErwin T Tsaur (parsed_args->size * BITS_PER_BYTE))) { 717d5ace945SErwin T Tsaur (void) fprintf(stderr, 718d5ace945SErwin T Tsaur "%s: Data to write is larger than " 719d5ace945SErwin T Tsaur "specified size.\n", argv[0]); 720d5ace945SErwin T Tsaur error = B_TRUE; 721d5ace945SErwin T Tsaur } 722d5ace945SErwin T Tsaur 723d5ace945SErwin T Tsaur } else { /* Looping is compatible only with register cmds. */ 724d5ace945SErwin T Tsaur 725d5ace945SErwin T Tsaur if (parsed_args->flags & LOOP_FLAG) { 726d5ace945SErwin T Tsaur (void) fprintf(stderr, "%s: -l is incompatible " 727d5ace945SErwin T Tsaur "with given command.\n", argv[0]); 728d5ace945SErwin T Tsaur error = B_TRUE; 729d5ace945SErwin T Tsaur } 730d5ace945SErwin T Tsaur } 731d5ace945SErwin T Tsaur 732d5ace945SErwin T Tsaur /* Call out an erroneous -y and then ignore it. */ 733d5ace945SErwin T Tsaur if ((confirm) && (!(parsed_args->flags & BASE_SPEC_FLAG))) { 734d5ace945SErwin T Tsaur (void) fprintf(stderr, 735d5ace945SErwin T Tsaur "%s: -y is incompatible with given command." 736d5ace945SErwin T Tsaur " Ignoring.\n", argv[0]); 737d5ace945SErwin T Tsaur } 738d5ace945SErwin T Tsaur } 739d5ace945SErwin T Tsaur 740d5ace945SErwin T Tsaur /* Now fill in the defaults and other holes. */ 741d5ace945SErwin T Tsaur if (!(error)) { 742d5ace945SErwin T Tsaur if (!(parsed_args->flags & (READ_FLAG | WRITE_FLAG))) { 743d5ace945SErwin T Tsaur parsed_args->flags |= READ_FLAG; 744d5ace945SErwin T Tsaur } 745d5ace945SErwin T Tsaur 746d5ace945SErwin T Tsaur if (parsed_args->flags & (LEAF_FLAG | NEXUS_FLAG)) { 747d5ace945SErwin T Tsaur if (!(parsed_args->flags & ENDIAN_FLAG)) { 748d5ace945SErwin T Tsaur parsed_args->big_endian = B_FALSE; 749d5ace945SErwin T Tsaur } 750d5ace945SErwin T Tsaur } 751d5ace945SErwin T Tsaur 752d5ace945SErwin T Tsaur if (parsed_args->flags & BASE_SPEC_FLAG) { 753d5ace945SErwin T Tsaur if (!confirm) { 754d5ace945SErwin T Tsaur confirm = get_confirmation(); 755d5ace945SErwin T Tsaur } 756d5ace945SErwin T Tsaur if (!confirm) { 757d5ace945SErwin T Tsaur parsed_args->flags &= ~ALL_COMMANDS; 758d5ace945SErwin T Tsaur } 759d5ace945SErwin T Tsaur } 760d5ace945SErwin T Tsaur 761d5ace945SErwin T Tsaur /* 762d5ace945SErwin T Tsaur * As far as other defaults are concerned: 763d5ace945SErwin T Tsaur * Other fields: bus, device, function, offset, default to 764d5ace945SErwin T Tsaur * zero. 765d5ace945SErwin T Tsaur */ 766d5ace945SErwin T Tsaur 767d5ace945SErwin T Tsaur } else { /* An error occurred. */ 768d5ace945SErwin T Tsaur 769d5ace945SErwin T Tsaur print_bad_option(argv, optopt, optarg); 770d5ace945SErwin T Tsaur } 771d5ace945SErwin T Tsaur return (error); 772d5ace945SErwin T Tsaur } 773d5ace945SErwin T Tsaur 774d5ace945SErwin T Tsaur 775d5ace945SErwin T Tsaur /* Module-private functions. */ 776d5ace945SErwin T Tsaur 777d5ace945SErwin T Tsaur static void 778d5ace945SErwin T Tsaur print_bad_option(char *argv[], int optopt, char *optarg) 779d5ace945SErwin T Tsaur { 780d5ace945SErwin T Tsaur /* Illegal option operand */ 781d5ace945SErwin T Tsaur if (optarg != NULL) { 782d5ace945SErwin T Tsaur (void) fprintf(stderr, 783d5ace945SErwin T Tsaur "%s: illegal operand %s specified for option %c\n", 784d5ace945SErwin T Tsaur argv[0], optarg, optopt); 785d5ace945SErwin T Tsaur 786d5ace945SErwin T Tsaur /* Illegal option */ 787d5ace945SErwin T Tsaur } else if (optopt != 0) { 788d5ace945SErwin T Tsaur (void) fprintf(stderr, 789d5ace945SErwin T Tsaur "%s: option %c is illegal or is missing an operand\n", 790d5ace945SErwin T Tsaur argv[0], optopt); 791d5ace945SErwin T Tsaur 792d5ace945SErwin T Tsaur /* getopt wasn't even called. Bad device spec. */ 793d5ace945SErwin T Tsaur } else { 794d5ace945SErwin T Tsaur (void) fprintf(stderr, 795d5ace945SErwin T Tsaur "%s: device spec must start with %s...\n", argv[0], 796d5ace945SErwin T Tsaur DEVNAME_START); 797d5ace945SErwin T Tsaur } 798d5ace945SErwin T Tsaur 799d5ace945SErwin T Tsaur (void) fprintf(stderr, 800d5ace945SErwin T Tsaur "%s: Type \"%s -h\" to get help on running this program.\n", 801d5ace945SErwin T Tsaur argv[0], argv[0]); 802d5ace945SErwin T Tsaur } 803d5ace945SErwin T Tsaur 804d5ace945SErwin T Tsaur /* 805d5ace945SErwin T Tsaur * Warn the user and ask for confirmation. 806d5ace945SErwin T Tsaur */ 807d5ace945SErwin T Tsaur static boolean_t 808d5ace945SErwin T Tsaur get_confirmation() 809d5ace945SErwin T Tsaur { 810d5ace945SErwin T Tsaur int i, b; 811d5ace945SErwin T Tsaur 812d5ace945SErwin T Tsaur (void) printf("WARNING: This cmd with a bad addr can panic " 813d5ace945SErwin T Tsaur "the system. Continue [y/n] (n)? "); 814d5ace945SErwin T Tsaur for (i = 0; ; i++) { 815d5ace945SErwin T Tsaur b = getchar(); 816d5ace945SErwin T Tsaur switch (b) { 817d5ace945SErwin T Tsaur case ' ': 818d5ace945SErwin T Tsaur case '\t': 819d5ace945SErwin T Tsaur break; 820d5ace945SErwin T Tsaur case 'y': 821d5ace945SErwin T Tsaur case 'Y': 822d5ace945SErwin T Tsaur return (B_TRUE); 823d5ace945SErwin T Tsaur break; 824d5ace945SErwin T Tsaur default: 825d5ace945SErwin T Tsaur return (B_FALSE); 826d5ace945SErwin T Tsaur break; 827d5ace945SErwin T Tsaur } 828d5ace945SErwin T Tsaur } 829d5ace945SErwin T Tsaur } 830d5ace945SErwin T Tsaur 831d5ace945SErwin T Tsaur 832d5ace945SErwin T Tsaur /* 833d5ace945SErwin T Tsaur * Given a digit string, return a 64 bit value. 834d5ace945SErwin T Tsaur * 835d5ace945SErwin T Tsaur * If the hex_only arg is true, interpret all strings as hex. 836d5ace945SErwin T Tsaur * Otherwise, interpret as strtoull(3C) does with base=0. 837d5ace945SErwin T Tsaur */ 838d5ace945SErwin T Tsaur static int 839d5ace945SErwin T Tsaur get_value64(char *value_str, uint64_t *value, boolean_t hex_only) 840d5ace945SErwin T Tsaur { 841d5ace945SErwin T Tsaur 842d5ace945SErwin T Tsaur /* This is overkill for now, as everything is in hex. */ 843d5ace945SErwin T Tsaur static char dec_digits[] = "0123456789"; 844d5ace945SErwin T Tsaur static char hex_digits[] = "01234567890abcdefABCDEF"; 845d5ace945SErwin T Tsaur static char oct_digits[] = "01234567"; 846d5ace945SErwin T Tsaur 847d5ace945SErwin T Tsaur char *digit_string; 848d5ace945SErwin T Tsaur char *string_to_check; 849d5ace945SErwin T Tsaur 850d5ace945SErwin T Tsaur if ((value_str == NULL) || (strlen(value_str) == 0)) { 851d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing value argument.\n"); 852d5ace945SErwin T Tsaur return (FAILURE); 853d5ace945SErwin T Tsaur } 854d5ace945SErwin T Tsaur 855d5ace945SErwin T Tsaur if (!hex_only && (value_str[0] != '0')) { 856d5ace945SErwin T Tsaur digit_string = dec_digits; 857d5ace945SErwin T Tsaur string_to_check = value_str; 858d5ace945SErwin T Tsaur } else if ((value_str[1] == 'X') || (value_str[1] == 'x')) { 859d5ace945SErwin T Tsaur digit_string = hex_digits; 860d5ace945SErwin T Tsaur string_to_check = &value_str[2]; /* Ignore 0x of hex */ 861d5ace945SErwin T Tsaur } else if (hex_only) { 862d5ace945SErwin T Tsaur digit_string = hex_digits; 863d5ace945SErwin T Tsaur string_to_check = value_str; /* Hex number, no 0x prefix */ 864d5ace945SErwin T Tsaur } else { 865d5ace945SErwin T Tsaur digit_string = oct_digits; 866d5ace945SErwin T Tsaur string_to_check = value_str; 867d5ace945SErwin T Tsaur } 868d5ace945SErwin T Tsaur 869d5ace945SErwin T Tsaur /* 870d5ace945SErwin T Tsaur * Verify value is all proper digits. 871d5ace945SErwin T Tsaur * 872d5ace945SErwin T Tsaur * For some reason, strtoull doesn't return an error when it cannot 873d5ace945SErwin T Tsaur * interpret the value. This is why we do the checking ourselves. 874d5ace945SErwin T Tsaur */ 875d5ace945SErwin T Tsaur if (strspn(string_to_check, digit_string) != strlen(string_to_check)) { 876d5ace945SErwin T Tsaur (void) fprintf(stderr, 877d5ace945SErwin T Tsaur "Value must contain only valid digits.\n"); 878d5ace945SErwin T Tsaur return (FAILURE); 879d5ace945SErwin T Tsaur } 880d5ace945SErwin T Tsaur 881d5ace945SErwin T Tsaur *value = strtoull(value_str, NULL, (hex_only ? 16 : 0)); 882d5ace945SErwin T Tsaur 883d5ace945SErwin T Tsaur return (SUCCESS); 884d5ace945SErwin T Tsaur } 885d5ace945SErwin T Tsaur 886d5ace945SErwin T Tsaur 887d5ace945SErwin T Tsaur /* 888d5ace945SErwin T Tsaur * Parse nexus options. This includes: 889d5ace945SErwin T Tsaur * bank=number 890d5ace945SErwin T Tsaur * 891d5ace945SErwin T Tsaur * input is what the user specified for the options on the commandline, 892d5ace945SErwin T Tsaur * flags_arg is modified with the option set, and bank_arg returns the value 893d5ace945SErwin T Tsaur * specified for bank. 894d5ace945SErwin T Tsaur */ 895d5ace945SErwin T Tsaur static int 896d5ace945SErwin T Tsaur parse_nexus_opts(char *input, uint64_t *flags_arg, uint8_t *bank_arg, 897d5ace945SErwin T Tsaur uint64_t *base_addr_arg) 898d5ace945SErwin T Tsaur { 899d5ace945SErwin T Tsaur typedef enum { 900d5ace945SErwin T Tsaur bank = 0, 901d5ace945SErwin T Tsaur base 902d5ace945SErwin T Tsaur } nexus_opts_index_t; 903d5ace945SErwin T Tsaur 904d5ace945SErwin T Tsaur static char *nexus_opts[] = { 905d5ace945SErwin T Tsaur "bank", 906d5ace945SErwin T Tsaur "base", 907d5ace945SErwin T Tsaur NULL 908d5ace945SErwin T Tsaur }; 909d5ace945SErwin T Tsaur 910d5ace945SErwin T Tsaur char *value; 911d5ace945SErwin T Tsaur uint64_t recv64; 912d5ace945SErwin T Tsaur 913d5ace945SErwin T Tsaur int rval = SUCCESS; 914d5ace945SErwin T Tsaur 915d5ace945SErwin T Tsaur if (input == NULL) { 916d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing argument.\n"); 917d5ace945SErwin T Tsaur return (FAILURE); 918d5ace945SErwin T Tsaur } 919d5ace945SErwin T Tsaur 920d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) { 921d5ace945SErwin T Tsaur switch (getsubopt(&input, nexus_opts, &value)) { 922d5ace945SErwin T Tsaur case bank: 923d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 924d5ace945SErwin T Tsaur (void) fprintf(stderr, "The bank or bar arg is " 925d5ace945SErwin T Tsaur "specified more than once.\n"); 926d5ace945SErwin T Tsaur rval = FAILURE; 927d5ace945SErwin T Tsaur break; 928d5ace945SErwin T Tsaur } 929d5ace945SErwin T Tsaur if (*flags_arg & BASE_SPEC_FLAG) { 930d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank and base address " 931d5ace945SErwin T Tsaur "cannot both be specified.\n"); 932d5ace945SErwin T Tsaur rval = FAILURE; 933d5ace945SErwin T Tsaur break; 934d5ace945SErwin T Tsaur } 935d5ace945SErwin T Tsaur if (value == NULL) { 936d5ace945SErwin T Tsaur (void) fprintf(stderr, "Missing bank value.\n"); 937d5ace945SErwin T Tsaur rval = FAILURE; 938d5ace945SErwin T Tsaur break; 939d5ace945SErwin T Tsaur } 940d5ace945SErwin T Tsaur if ((rval = get_value64(value, &recv64, HEX_ONLY)) != 941d5ace945SErwin T Tsaur SUCCESS) { 942d5ace945SErwin T Tsaur break; 943d5ace945SErwin T Tsaur } 944d5ace945SErwin T Tsaur *bank_arg = (uint8_t)recv64; 945d5ace945SErwin T Tsaur if (*bank_arg != recv64) { 946d5ace945SErwin T Tsaur (void) fprintf(stderr, 947d5ace945SErwin T Tsaur "Bank argument must fit into 8 bits.\n"); 948d5ace945SErwin T Tsaur rval = FAILURE; 949d5ace945SErwin T Tsaur break; 950d5ace945SErwin T Tsaur } 951d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 952d5ace945SErwin T Tsaur break; 953d5ace945SErwin T Tsaur 954d5ace945SErwin T Tsaur case base: 955d5ace945SErwin T Tsaur if (*flags_arg & BASE_SPEC_FLAG) { 956d5ace945SErwin T Tsaur (void) fprintf(stderr, "The base address " 957d5ace945SErwin T Tsaur "is specified more than once.\n"); 958d5ace945SErwin T Tsaur rval = FAILURE; 959d5ace945SErwin T Tsaur break; 960d5ace945SErwin T Tsaur } 961d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 962d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank and base address " 963d5ace945SErwin T Tsaur "cannot both be specified.\n"); 964d5ace945SErwin T Tsaur rval = FAILURE; 965d5ace945SErwin T Tsaur break; 966d5ace945SErwin T Tsaur } 967d5ace945SErwin T Tsaur if (value == NULL) { 968d5ace945SErwin T Tsaur (void) fprintf(stderr, 969d5ace945SErwin T Tsaur "Missing base addr value.\n"); 970d5ace945SErwin T Tsaur rval = FAILURE; 971d5ace945SErwin T Tsaur break; 972d5ace945SErwin T Tsaur } 973d5ace945SErwin T Tsaur if ((rval = get_value64(value, base_addr_arg, 974d5ace945SErwin T Tsaur HEX_ONLY)) != SUCCESS) { 975d5ace945SErwin T Tsaur break; 976d5ace945SErwin T Tsaur } 977d5ace945SErwin T Tsaur *flags_arg |= BASE_SPEC_FLAG; 978d5ace945SErwin T Tsaur break; 979d5ace945SErwin T Tsaur 980d5ace945SErwin T Tsaur default: 981d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -n\n"); 982d5ace945SErwin T Tsaur rval = FAILURE; 983d5ace945SErwin T Tsaur break; 984d5ace945SErwin T Tsaur } 985d5ace945SErwin T Tsaur } 986d5ace945SErwin T Tsaur 987d5ace945SErwin T Tsaur return (rval); 988d5ace945SErwin T Tsaur } 989d5ace945SErwin T Tsaur 990d5ace945SErwin T Tsaur 991d5ace945SErwin T Tsaur static int 992d5ace945SErwin T Tsaur extract_bdf_arg(char *cvalue, char *fld, uint64_t fld_flag, uint64_t *all_flags, 993d5ace945SErwin T Tsaur uint8_t *ivalue) 994d5ace945SErwin T Tsaur { 995d5ace945SErwin T Tsaur uint64_t recv64; 996d5ace945SErwin T Tsaur 997d5ace945SErwin T Tsaur if (*all_flags & fld_flag) { 998d5ace945SErwin T Tsaur (void) fprintf(stderr, 999d5ace945SErwin T Tsaur "The %s is specified more than once.\n", fld); 1000d5ace945SErwin T Tsaur return (FAILURE); 1001d5ace945SErwin T Tsaur } 1002d5ace945SErwin T Tsaur if (get_value64(cvalue, &recv64, HEX_ONLY) != SUCCESS) 1003d5ace945SErwin T Tsaur return (FAILURE); 1004d5ace945SErwin T Tsaur 1005d5ace945SErwin T Tsaur *ivalue = (uint8_t)recv64; 1006d5ace945SErwin T Tsaur if (recv64 != *ivalue) { 1007d5ace945SErwin T Tsaur (void) fprintf(stderr, 1008d5ace945SErwin T Tsaur "This program limits the %s argument to 8 bits.\n", fld); 1009d5ace945SErwin T Tsaur (void) fprintf(stderr, "The actual maximum may be " 1010d5ace945SErwin T Tsaur "smaller but cannot be enforced by this program.\n"); 1011d5ace945SErwin T Tsaur return (FAILURE); 1012d5ace945SErwin T Tsaur } 1013d5ace945SErwin T Tsaur 1014d5ace945SErwin T Tsaur *all_flags |= fld_flag; 1015d5ace945SErwin T Tsaur return (SUCCESS); 1016d5ace945SErwin T Tsaur } 1017d5ace945SErwin T Tsaur 1018d5ace945SErwin T Tsaur 1019d5ace945SErwin T Tsaur static int extract_bdf(char *value, char **bvalue_p, char **dvalue_p, 1020d5ace945SErwin T Tsaur char **fvalue_p) 1021d5ace945SErwin T Tsaur { 1022d5ace945SErwin T Tsaur char *strtok_state; 1023d5ace945SErwin T Tsaur char *dummy; 1024d5ace945SErwin T Tsaur static char *separator = "."; 1025d5ace945SErwin T Tsaur 1026d5ace945SErwin T Tsaur *bvalue_p = strtok_r(value, separator, &strtok_state); 1027d5ace945SErwin T Tsaur *dvalue_p = strtok_r(NULL, separator, &strtok_state); 1028d5ace945SErwin T Tsaur *fvalue_p = strtok_r(NULL, separator, &strtok_state); 1029d5ace945SErwin T Tsaur dummy = strtok_r(NULL, separator, &strtok_state); 1030d5ace945SErwin T Tsaur 1031d5ace945SErwin T Tsaur /* Return failure only if too many values specified. */ 1032d5ace945SErwin T Tsaur return ((dummy) ? FAILURE : SUCCESS); 1033d5ace945SErwin T Tsaur } 1034d5ace945SErwin T Tsaur 1035d5ace945SErwin T Tsaur /* 1036d5ace945SErwin T Tsaur * Parse device options. This includes: 1037d5ace945SErwin T Tsaur * bus=number 1038d5ace945SErwin T Tsaur * dev=number 1039d5ace945SErwin T Tsaur * func=number 1040d5ace945SErwin T Tsaur * bank=number 1041d5ace945SErwin T Tsaur * config 1042d5ace945SErwin T Tsaur * bar0 1043d5ace945SErwin T Tsaur * bar1 1044d5ace945SErwin T Tsaur * bar2 1045d5ace945SErwin T Tsaur * bar3 1046d5ace945SErwin T Tsaur * bar4 1047d5ace945SErwin T Tsaur * bar5 1048d5ace945SErwin T Tsaur * rom 1049d5ace945SErwin T Tsaur * 1050d5ace945SErwin T Tsaur * input is what the user specified for the options on the commandline, 1051d5ace945SErwin T Tsaur * flags_arg is modified with the options set, and the rest of the args return 1052d5ace945SErwin T Tsaur * their respective values. 1053d5ace945SErwin T Tsaur */ 1054d5ace945SErwin T Tsaur static int 1055d5ace945SErwin T Tsaur parse_device_opts( 1056d5ace945SErwin T Tsaur char *input, uint64_t *flags_arg, uint8_t *bus_arg, uint8_t *device_arg, 1057d5ace945SErwin T Tsaur uint8_t *func_arg, uint8_t *bank_arg) 1058d5ace945SErwin T Tsaur { 1059d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */ 1060d5ace945SErwin T Tsaur typedef enum { 1061d5ace945SErwin T Tsaur bus = 0, 1062d5ace945SErwin T Tsaur dev = 1, 1063d5ace945SErwin T Tsaur func = 2, 1064d5ace945SErwin T Tsaur bdf = 3, 1065d5ace945SErwin T Tsaur bank = 4, 1066d5ace945SErwin T Tsaur config = 5, 1067d5ace945SErwin T Tsaur bar0 = 6, 1068d5ace945SErwin T Tsaur bar1 = 7, 1069d5ace945SErwin T Tsaur bar2 = 8, 1070d5ace945SErwin T Tsaur bar3 = 9, 1071d5ace945SErwin T Tsaur bar4 = 10, 1072d5ace945SErwin T Tsaur bar5 = 11, 1073d5ace945SErwin T Tsaur rom = 12 1074d5ace945SErwin T Tsaur } bdf_opts_index_t; 1075d5ace945SErwin T Tsaur 1076d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */ 1077d5ace945SErwin T Tsaur static char *bdf_opts[] = { 1078d5ace945SErwin T Tsaur "bus", 1079d5ace945SErwin T Tsaur "dev", 1080d5ace945SErwin T Tsaur "func", 1081d5ace945SErwin T Tsaur "bdf", 1082d5ace945SErwin T Tsaur "bank", 1083d5ace945SErwin T Tsaur "config", 1084d5ace945SErwin T Tsaur "bar0", 1085d5ace945SErwin T Tsaur "bar1", 1086d5ace945SErwin T Tsaur "bar2", 1087d5ace945SErwin T Tsaur "bar3", 1088d5ace945SErwin T Tsaur "bar4", 1089d5ace945SErwin T Tsaur "bar5", 1090d5ace945SErwin T Tsaur "rom", 1091d5ace945SErwin T Tsaur NULL }; 1092d5ace945SErwin T Tsaur 1093d5ace945SErwin T Tsaur char *value; /* Current suboption being processed. */ 1094d5ace945SErwin T Tsaur uint64_t recv64; /* Temporary value. */ 1095d5ace945SErwin T Tsaur 1096d5ace945SErwin T Tsaur /* This error message is used in many places. */ 1097d5ace945SErwin T Tsaur static char bank_err[] = 1098d5ace945SErwin T Tsaur {"The bank or bar arg is specified more than once.\n"}; 1099d5ace945SErwin T Tsaur 1100d5ace945SErwin T Tsaur int rval = SUCCESS; 1101d5ace945SErwin T Tsaur 1102d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) { 1103d5ace945SErwin T Tsaur switch (getsubopt(&input, bdf_opts, &value)) { 1104d5ace945SErwin T Tsaur 1105d5ace945SErwin T Tsaur /* bus=number */ 1106d5ace945SErwin T Tsaur case bdf: { 1107d5ace945SErwin T Tsaur char *bvalue, *dvalue, *fvalue; 1108d5ace945SErwin T Tsaur 1109d5ace945SErwin T Tsaur if ((rval = extract_bdf(value, &bvalue, &dvalue, 1110d5ace945SErwin T Tsaur &fvalue)) != SUCCESS) { 1111d5ace945SErwin T Tsaur break; 1112d5ace945SErwin T Tsaur } 1113d5ace945SErwin T Tsaur 1114d5ace945SErwin T Tsaur if (!bvalue | !dvalue | !fvalue) { 1115d5ace945SErwin T Tsaur break; 1116d5ace945SErwin T Tsaur } 1117d5ace945SErwin T Tsaur 1118d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(bvalue, "bus", 1119d5ace945SErwin T Tsaur BUS_SPEC_FLAG, flags_arg, bus_arg)) != SUCCESS) { 1120d5ace945SErwin T Tsaur break; 1121d5ace945SErwin T Tsaur } 1122d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(dvalue, "dev", 1123d5ace945SErwin T Tsaur DEV_SPEC_FLAG, flags_arg, device_arg)) != SUCCESS) { 1124d5ace945SErwin T Tsaur break; 1125d5ace945SErwin T Tsaur } 1126d5ace945SErwin T Tsaur rval = extract_bdf_arg(fvalue, "func", 1127d5ace945SErwin T Tsaur FUNC_SPEC_FLAG, flags_arg, func_arg); 1128d5ace945SErwin T Tsaur break; 1129d5ace945SErwin T Tsaur } 1130d5ace945SErwin T Tsaur 1131d5ace945SErwin T Tsaur case bus: 1132d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "bus", BUS_SPEC_FLAG, 1133d5ace945SErwin T Tsaur flags_arg, bus_arg); 1134d5ace945SErwin T Tsaur break; 1135d5ace945SErwin T Tsaur 1136d5ace945SErwin T Tsaur /* dev=number */ 1137d5ace945SErwin T Tsaur case dev: 1138d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "dev", DEV_SPEC_FLAG, 1139d5ace945SErwin T Tsaur flags_arg, device_arg); 1140d5ace945SErwin T Tsaur break; 1141d5ace945SErwin T Tsaur 1142d5ace945SErwin T Tsaur /* func=number */ 1143d5ace945SErwin T Tsaur case func: 1144d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "func", FUNC_SPEC_FLAG, 1145d5ace945SErwin T Tsaur flags_arg, func_arg); 1146d5ace945SErwin T Tsaur break; 1147d5ace945SErwin T Tsaur 1148d5ace945SErwin T Tsaur /* bank=number */ 1149d5ace945SErwin T Tsaur case bank: 1150d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1151d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1152d5ace945SErwin T Tsaur rval = FAILURE; 1153d5ace945SErwin T Tsaur break; 1154d5ace945SErwin T Tsaur } 1155d5ace945SErwin T Tsaur if ((rval = get_value64(value, &recv64, HEX_ONLY)) != 1156d5ace945SErwin T Tsaur SUCCESS) { 1157d5ace945SErwin T Tsaur break; 1158d5ace945SErwin T Tsaur } 1159d5ace945SErwin T Tsaur *bank_arg = (uint8_t)recv64; 1160d5ace945SErwin T Tsaur if (rval || (*bank_arg != recv64)) { 1161d5ace945SErwin T Tsaur (void) fprintf(stderr, "Bank argument must" 1162d5ace945SErwin T Tsaur " fit into 8 bits.\n"); 1163d5ace945SErwin T Tsaur rval = FAILURE; 1164d5ace945SErwin T Tsaur break; 1165d5ace945SErwin T Tsaur } 1166d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1167d5ace945SErwin T Tsaur break; 1168d5ace945SErwin T Tsaur 1169d5ace945SErwin T Tsaur /* config */ 1170d5ace945SErwin T Tsaur case config: 1171d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1172d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1173d5ace945SErwin T Tsaur rval = FAILURE; 1174d5ace945SErwin T Tsaur break; 1175d5ace945SErwin T Tsaur } 1176d5ace945SErwin T Tsaur *bank_arg = PCITOOL_CONFIG; 1177d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1178d5ace945SErwin T Tsaur break; 1179d5ace945SErwin T Tsaur 1180d5ace945SErwin T Tsaur /* bar0 */ 1181d5ace945SErwin T Tsaur case bar0: 1182d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1183d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1184d5ace945SErwin T Tsaur rval = FAILURE; 1185d5ace945SErwin T Tsaur break; 1186d5ace945SErwin T Tsaur } 1187d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR0; 1188d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1189d5ace945SErwin T Tsaur break; 1190d5ace945SErwin T Tsaur 1191d5ace945SErwin T Tsaur /* bar1 */ 1192d5ace945SErwin T Tsaur case bar1: 1193d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1194d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1195d5ace945SErwin T Tsaur rval = FAILURE; 1196d5ace945SErwin T Tsaur break; 1197d5ace945SErwin T Tsaur } 1198d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR1; 1199d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1200d5ace945SErwin T Tsaur break; 1201d5ace945SErwin T Tsaur 1202d5ace945SErwin T Tsaur /* bar2 */ 1203d5ace945SErwin T Tsaur case bar2: 1204d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1205d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1206d5ace945SErwin T Tsaur rval = FAILURE; 1207d5ace945SErwin T Tsaur break; 1208d5ace945SErwin T Tsaur } 1209d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR2; 1210d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1211d5ace945SErwin T Tsaur break; 1212d5ace945SErwin T Tsaur 1213d5ace945SErwin T Tsaur /* bar3 */ 1214d5ace945SErwin T Tsaur case bar3: 1215d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1216d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1217d5ace945SErwin T Tsaur rval = FAILURE; 1218d5ace945SErwin T Tsaur break; 1219d5ace945SErwin T Tsaur } 1220d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR3; 1221d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1222d5ace945SErwin T Tsaur break; 1223d5ace945SErwin T Tsaur 1224d5ace945SErwin T Tsaur /* bar4 */ 1225d5ace945SErwin T Tsaur case bar4: 1226d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1227d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1228d5ace945SErwin T Tsaur rval = FAILURE; 1229d5ace945SErwin T Tsaur break; 1230d5ace945SErwin T Tsaur } 1231d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR4; 1232d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1233d5ace945SErwin T Tsaur break; 1234d5ace945SErwin T Tsaur 1235d5ace945SErwin T Tsaur /* bar5 */ 1236d5ace945SErwin T Tsaur case bar5: 1237d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1238d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1239d5ace945SErwin T Tsaur rval = FAILURE; 1240d5ace945SErwin T Tsaur break; 1241d5ace945SErwin T Tsaur } 1242d5ace945SErwin T Tsaur *bank_arg = PCITOOL_BAR5; 1243d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1244d5ace945SErwin T Tsaur break; 1245d5ace945SErwin T Tsaur 1246d5ace945SErwin T Tsaur /* rom */ 1247d5ace945SErwin T Tsaur case rom: 1248d5ace945SErwin T Tsaur if (*flags_arg & BANK_SPEC_FLAG) { 1249d5ace945SErwin T Tsaur (void) fprintf(stderr, bank_err); 1250d5ace945SErwin T Tsaur rval = FAILURE; 1251d5ace945SErwin T Tsaur break; 1252d5ace945SErwin T Tsaur } 1253d5ace945SErwin T Tsaur *bank_arg = PCITOOL_ROM; 1254d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1255d5ace945SErwin T Tsaur break; 1256d5ace945SErwin T Tsaur 1257d5ace945SErwin T Tsaur default: 1258d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -d\n"); 1259d5ace945SErwin T Tsaur rval = FAILURE; 1260d5ace945SErwin T Tsaur break; 1261d5ace945SErwin T Tsaur } 1262d5ace945SErwin T Tsaur } 1263d5ace945SErwin T Tsaur 1264d5ace945SErwin T Tsaur /* Bus, dev and func must all be specified. */ 1265d5ace945SErwin T Tsaur if ((*flags_arg & (BUS_SPEC_FLAG | DEV_SPEC_FLAG | FUNC_SPEC_FLAG)) != 1266d5ace945SErwin T Tsaur (BUS_SPEC_FLAG | DEV_SPEC_FLAG | FUNC_SPEC_FLAG)) { 1267d5ace945SErwin T Tsaur rval = FAILURE; 1268d5ace945SErwin T Tsaur 1269d5ace945SErwin T Tsaur /* No bank specified in any way. Default to config space */ 1270d5ace945SErwin T Tsaur } else if ((*flags_arg & BANK_SPEC_FLAG) == 0) { 1271d5ace945SErwin T Tsaur *flags_arg |= BANK_SPEC_FLAG; 1272d5ace945SErwin T Tsaur *bank_arg = PCITOOL_CONFIG; 1273d5ace945SErwin T Tsaur } 1274d5ace945SErwin T Tsaur 1275d5ace945SErwin T Tsaur return (rval); 1276d5ace945SErwin T Tsaur } 1277d5ace945SErwin T Tsaur 1278d5ace945SErwin T Tsaur 1279d5ace945SErwin T Tsaur /* 1280*09b1eac2SEvan Yan * Parse INO options. This includes: 1281*09b1eac2SEvan Yan * ino# | all 1282d5ace945SErwin T Tsaur * 1283d5ace945SErwin T Tsaur * input is the string of options to parse. flags_arg returns modified with 1284d5ace945SErwin T Tsaur * specified options set. Other args return their respective values. 1285d5ace945SErwin T Tsaur */ 1286d5ace945SErwin T Tsaur static int 1287*09b1eac2SEvan Yan parse_ino_opts(char *input, uint64_t *flags_arg, uint8_t *ino_arg) 1288d5ace945SErwin T Tsaur { 1289*09b1eac2SEvan Yan uint64_t value; 1290d5ace945SErwin T Tsaur int rval = SUCCESS; 1291d5ace945SErwin T Tsaur 1292*09b1eac2SEvan Yan if (strcmp(input, "all") == 0) { 1293*09b1eac2SEvan Yan *flags_arg |= INO_ALL_FLAG; 1294*09b1eac2SEvan Yan } else if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS) { 1295*09b1eac2SEvan Yan *ino_arg = (uint8_t)value; 1296d5ace945SErwin T Tsaur 1297*09b1eac2SEvan Yan if (*ino_arg != value) { 1298d5ace945SErwin T Tsaur (void) fprintf(stderr, 1299*09b1eac2SEvan Yan "ino argument must fit into 8 bits.\n"); 1300d5ace945SErwin T Tsaur rval = FAILURE; 1301*09b1eac2SEvan Yan } else { 1302d5ace945SErwin T Tsaur *flags_arg |= INO_SPEC_FLAG; 1303*09b1eac2SEvan Yan } 1304*09b1eac2SEvan Yan } else { 1305d5ace945SErwin T Tsaur (void) fprintf(stderr, 1306d5ace945SErwin T Tsaur "Unrecognized option for -i\n"); 1307d5ace945SErwin T Tsaur rval = FAILURE; 1308d5ace945SErwin T Tsaur } 1309*09b1eac2SEvan Yan 1310*09b1eac2SEvan Yan return (rval); 1311*09b1eac2SEvan Yan } 1312*09b1eac2SEvan Yan 1313*09b1eac2SEvan Yan 1314*09b1eac2SEvan Yan /* 1315*09b1eac2SEvan Yan * Parse MSI options. This includes: 1316*09b1eac2SEvan Yan * msi# | all 1317*09b1eac2SEvan Yan * 1318*09b1eac2SEvan Yan * input is the string of options to parse. flags_arg returns modified with 1319*09b1eac2SEvan Yan * specified options set. Other args return their respective values. 1320*09b1eac2SEvan Yan */ 1321*09b1eac2SEvan Yan static int 1322*09b1eac2SEvan Yan parse_msi_opts(char *input, uint64_t *flags_arg, uint16_t *msi_arg) 1323*09b1eac2SEvan Yan { 1324*09b1eac2SEvan Yan uint64_t value; 1325*09b1eac2SEvan Yan int rval = SUCCESS; 1326*09b1eac2SEvan Yan 1327*09b1eac2SEvan Yan if (strcmp(input, "all") == 0) { 1328*09b1eac2SEvan Yan *flags_arg |= MSI_ALL_FLAG; 1329*09b1eac2SEvan Yan } else if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS) { 1330*09b1eac2SEvan Yan *msi_arg = (uint16_t)value; 1331*09b1eac2SEvan Yan 1332*09b1eac2SEvan Yan if (*msi_arg != value) { 1333*09b1eac2SEvan Yan (void) fprintf(stderr, 1334*09b1eac2SEvan Yan "msi argument must fit into 16 bits.\n"); 1335*09b1eac2SEvan Yan rval = FAILURE; 1336*09b1eac2SEvan Yan } else { 1337*09b1eac2SEvan Yan *flags_arg |= MSI_SPEC_FLAG; 1338*09b1eac2SEvan Yan } 1339*09b1eac2SEvan Yan } else { 1340*09b1eac2SEvan Yan (void) fprintf(stderr, 1341*09b1eac2SEvan Yan "Unrecognized option for -m\n"); 1342*09b1eac2SEvan Yan rval = FAILURE; 1343d5ace945SErwin T Tsaur } 1344d5ace945SErwin T Tsaur 1345d5ace945SErwin T Tsaur return (rval); 1346d5ace945SErwin T Tsaur } 1347d5ace945SErwin T Tsaur 1348d5ace945SErwin T Tsaur 1349d5ace945SErwin T Tsaur /* 1350d5ace945SErwin T Tsaur * Parse interrupt set options. This includes: 1351d5ace945SErwin T Tsaur * cpu=number 1352d5ace945SErwin T Tsaur * 1353d5ace945SErwin T Tsaur * input is the string of options to parse. flags_arg returns modified with 1354d5ace945SErwin T Tsaur * specified options set. Other args return their respective values. 1355d5ace945SErwin T Tsaur */ 1356d5ace945SErwin T Tsaur static int 1357d5ace945SErwin T Tsaur parse_intr_set_opts(char *input, uint64_t *flags_arg, uint32_t *cpu_arg) 1358d5ace945SErwin T Tsaur { 1359*09b1eac2SEvan Yan uint64_t value; 1360d5ace945SErwin T Tsaur int rval = SUCCESS; 1361d5ace945SErwin T Tsaur 1362*09b1eac2SEvan Yan if ((rval = get_value64(input, &value, HEX_ONLY)) == SUCCESS) { 1363d5ace945SErwin T Tsaur 1364*09b1eac2SEvan Yan if ((long)value > sysconf(_SC_CPUID_MAX)) { 1365d5ace945SErwin T Tsaur (void) fprintf(stderr, "Cpu argument " 1366d5ace945SErwin T Tsaur "exceeds maximum for this system type.\n"); 1367d5ace945SErwin T Tsaur rval = FAILURE; 1368*09b1eac2SEvan Yan } else { 1369*09b1eac2SEvan Yan *cpu_arg = (uint32_t)value; 1370d5ace945SErwin T Tsaur *flags_arg |= CPU_SPEC_FLAG; 1371d5ace945SErwin T Tsaur } 1372*09b1eac2SEvan Yan } else { 1373*09b1eac2SEvan Yan (void) fprintf(stderr, 1374*09b1eac2SEvan Yan "Unrecognized option for -i -m -w\n"); 1375*09b1eac2SEvan Yan rval = FAILURE; 1376d5ace945SErwin T Tsaur } 1377d5ace945SErwin T Tsaur 1378d5ace945SErwin T Tsaur return (rval); 1379d5ace945SErwin T Tsaur } 1380d5ace945SErwin T Tsaur 1381d5ace945SErwin T Tsaur 1382d5ace945SErwin T Tsaur static int 1383d5ace945SErwin T Tsaur parse_probeone_opts( 1384d5ace945SErwin T Tsaur char *input, uint64_t *flags_arg, uint8_t *bus_arg, uint8_t *device_arg, 1385d5ace945SErwin T Tsaur uint8_t *func_arg) 1386d5ace945SErwin T Tsaur { 1387d5ace945SErwin T Tsaur typedef enum { 1388d5ace945SErwin T Tsaur bus = 0, 1389d5ace945SErwin T Tsaur dev = 1, 1390d5ace945SErwin T Tsaur func = 2, 1391d5ace945SErwin T Tsaur bdf = 3 1392d5ace945SErwin T Tsaur } p1_bdf_opts_index_t; 1393d5ace945SErwin T Tsaur 1394d5ace945SErwin T Tsaur /* Needed by getsubopt(3C) */ 1395d5ace945SErwin T Tsaur static char *p1_bdf_opts[] = { 1396d5ace945SErwin T Tsaur "bus", 1397d5ace945SErwin T Tsaur "dev", 1398d5ace945SErwin T Tsaur "func", 1399d5ace945SErwin T Tsaur "bdf", 1400d5ace945SErwin T Tsaur NULL }; 1401d5ace945SErwin T Tsaur 1402d5ace945SErwin T Tsaur char *value; /* Current suboption being processed. */ 1403d5ace945SErwin T Tsaur 1404d5ace945SErwin T Tsaur int rval = SUCCESS; 1405d5ace945SErwin T Tsaur 1406d5ace945SErwin T Tsaur while ((*input != '\0') && (rval == SUCCESS)) { 1407d5ace945SErwin T Tsaur switch (getsubopt(&input, p1_bdf_opts, &value)) { 1408d5ace945SErwin T Tsaur 1409d5ace945SErwin T Tsaur /* bus=number */ 1410d5ace945SErwin T Tsaur case bdf: { 1411d5ace945SErwin T Tsaur char *bvalue, *dvalue, *fvalue; 1412d5ace945SErwin T Tsaur 1413d5ace945SErwin T Tsaur if ((rval = extract_bdf(value, &bvalue, &dvalue, 1414d5ace945SErwin T Tsaur &fvalue)) != SUCCESS) { 1415d5ace945SErwin T Tsaur break; 1416d5ace945SErwin T Tsaur } 1417d5ace945SErwin T Tsaur if (bvalue) 1418d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(bvalue, "bus", 1419d5ace945SErwin T Tsaur BUS_SPEC_FLAG, flags_arg, bus_arg)) != 1420d5ace945SErwin T Tsaur SUCCESS) { 1421d5ace945SErwin T Tsaur break; 1422d5ace945SErwin T Tsaur } 1423d5ace945SErwin T Tsaur if (dvalue) 1424d5ace945SErwin T Tsaur if ((rval = extract_bdf_arg(dvalue, "dev", 1425d5ace945SErwin T Tsaur DEV_SPEC_FLAG, flags_arg, device_arg)) != 1426d5ace945SErwin T Tsaur SUCCESS) { 1427d5ace945SErwin T Tsaur break; 1428d5ace945SErwin T Tsaur } 1429d5ace945SErwin T Tsaur if (fvalue) 1430d5ace945SErwin T Tsaur rval = extract_bdf_arg(fvalue, "func", 1431d5ace945SErwin T Tsaur FUNC_SPEC_FLAG, flags_arg, func_arg); 1432d5ace945SErwin T Tsaur break; 1433d5ace945SErwin T Tsaur } 1434d5ace945SErwin T Tsaur 1435d5ace945SErwin T Tsaur case bus: 1436d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "bus", BUS_SPEC_FLAG, 1437d5ace945SErwin T Tsaur flags_arg, bus_arg); 1438d5ace945SErwin T Tsaur break; 1439d5ace945SErwin T Tsaur 1440d5ace945SErwin T Tsaur /* dev=number */ 1441d5ace945SErwin T Tsaur case dev: 1442d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "dev", DEV_SPEC_FLAG, 1443d5ace945SErwin T Tsaur flags_arg, device_arg); 1444d5ace945SErwin T Tsaur break; 1445d5ace945SErwin T Tsaur 1446d5ace945SErwin T Tsaur /* func=number */ 1447d5ace945SErwin T Tsaur case func: 1448d5ace945SErwin T Tsaur rval = extract_bdf_arg(value, "func", FUNC_SPEC_FLAG, 1449d5ace945SErwin T Tsaur flags_arg, func_arg); 1450d5ace945SErwin T Tsaur break; 1451d5ace945SErwin T Tsaur 1452d5ace945SErwin T Tsaur default: 1453d5ace945SErwin T Tsaur (void) fprintf(stderr, "Unrecognized option for -p\n"); 1454d5ace945SErwin T Tsaur rval = FAILURE; 1455d5ace945SErwin T Tsaur break; 1456d5ace945SErwin T Tsaur } 1457d5ace945SErwin T Tsaur } 1458d5ace945SErwin T Tsaur 1459d5ace945SErwin T Tsaur return (rval); 1460d5ace945SErwin T Tsaur } 1461d5ace945SErwin T Tsaur 1462d5ace945SErwin T Tsaur 1463d5ace945SErwin T Tsaur #ifdef DEBUG 1464d5ace945SErwin T Tsaur 1465d5ace945SErwin T Tsaur static void 1466d5ace945SErwin T Tsaur dump_struct(pcitool_uiargs_t *dumpthis) { 1467d5ace945SErwin T Tsaur (void) printf("flags:0x%x\n", dumpthis->flags); 1468d5ace945SErwin T Tsaur (void) printf("bus:%d (0x%x)\n", 1469d5ace945SErwin T Tsaur dumpthis->bus, dumpthis->bus); 1470d5ace945SErwin T Tsaur (void) printf("device:%d (0x%x)\n", dumpthis->device, 1471d5ace945SErwin T Tsaur dumpthis->device); 1472d5ace945SErwin T Tsaur (void) printf("function:%d (0x%x)\n", dumpthis->function, 1473d5ace945SErwin T Tsaur dumpthis->function); 1474d5ace945SErwin T Tsaur (void) printf("write_value:%" PRIu64 " (0x%" PRIx64 ")\n", 1475d5ace945SErwin T Tsaur dumpthis->write_value, dumpthis->write_value); 1476d5ace945SErwin T Tsaur (void) printf("bank:%d (0x%x)\n", 1477d5ace945SErwin T Tsaur dumpthis->bank, dumpthis->bank); 1478d5ace945SErwin T Tsaur (void) printf("offset:%d (0x%x)\n", dumpthis->offset, dumpthis->offset); 1479d5ace945SErwin T Tsaur (void) printf("size:%d, endian:%s\n", dumpthis->size, 1480d5ace945SErwin T Tsaur dumpthis->big_endian ? "BIG" : "little"); 1481d5ace945SErwin T Tsaur (void) printf("ino:%d, cpu:%d\n", 1482d5ace945SErwin T Tsaur dumpthis->intr_ino, dumpthis->intr_cpu); 1483d5ace945SErwin T Tsaur } 1484d5ace945SErwin T Tsaur 1485d5ace945SErwin T Tsaur #ifdef STANDALONE 1486d5ace945SErwin T Tsaur 1487d5ace945SErwin T Tsaur /* Test program for this module. Useful when implementing new options. */ 1488d5ace945SErwin T Tsaur int 1489d5ace945SErwin T Tsaur main(int argc, char *argv[]) 1490d5ace945SErwin T Tsaur { 1491d5ace945SErwin T Tsaur int status; 1492d5ace945SErwin T Tsaur pcitool_uiargs_t parsed_args; 1493d5ace945SErwin T Tsaur 1494d5ace945SErwin T Tsaur status = get_commandline_args(argc, argv, &parsed_args); 1495d5ace945SErwin T Tsaur if (status) { 1496d5ace945SErwin T Tsaur (void) printf("Error getting command.\n"); 1497d5ace945SErwin T Tsaur } 1498d5ace945SErwin T Tsaur dump_struct(&parsed_args); 1499d5ace945SErwin T Tsaur 1500d5ace945SErwin T Tsaur return (SUCCESS); 1501d5ace945SErwin T Tsaur } 1502d5ace945SErwin T Tsaur 1503d5ace945SErwin T Tsaur #endif /* STANDALONE */ 1504d5ace945SErwin T Tsaur #endif /* DEBUG */ 1505