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