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