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