diff options
author | Andrew Patterson <andrew.patterson@hp.com> | 2010-03-10 16:01:01 +0800 |
---|---|---|
committer | Huang Ying <ying.huang@intel.com> | 2010-03-10 16:01:01 +0800 |
commit | 2a78abc1c40e7d5a57e34bfd5ff6a841757b42cf (patch) | |
tree | d34afb0750dc875bce72d36b53bb1c1e41052e20 | |
parent | c7cee585aada78f1ead17be17300c6450bc2ef55 (diff) | |
download | aer-inject-2a78abc1c40e7d5a57e34bfd5ff6a841757b42cf.tar.gz |
aer-inject: use command-line option to specify PCI ID
The PCI ID may be specified on the command-line using -s|--id instead
of taking it from the data file using the PCI_ID keyword. The PCI_ID
specified in data file will be overrided by the command-line option.
Added -v|--version and -h|--help command-line options.
Signed-off-by: Andrew Patterson <andrew.patterson@hp.com>
Signed-off-by: Huang Ying <ying.huang@intel.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | aer-inject.c | 93 | ||||
-rw-r--r-- | aer.h | 3 | ||||
-rw-r--r-- | aer.lex | 4 |
4 files changed, 99 insertions, 3 deletions
@@ -1,5 +1,5 @@ PREFIX = /usr/local -CFLAGS := -g -Wall +CFLAGS := -g -Wall -D_GNU_SOURCE LDFLAGS += -lpthread DESTDIR = diff --git a/aer-inject.c b/aer-inject.c index 1bcfc54..74e7f72 100644 --- a/aer-inject.c +++ b/aer-inject.c @@ -15,11 +15,47 @@ #include <string.h> #include <fcntl.h> #include <unistd.h> +#include <getopt.h> #include "aer.h" #include "util.h" #define AER_DEV "/dev/aer_inject" +#define CMDLINE_PCI_ID 0x0001 + +const char *prg_name; + +static struct aer_error_inj aerr_cmdline; +static unsigned int cmdline_flags = 0; + +void usage(const char *prgname) +{ + fprintf(stderr, +"Usage: %s [-s|--id=PCI_ID] [FILE]\n" +" or: %s -v|--version\n" +" or: %s -h|--help\n" +"Inject an error into a PCIe device\n" +"\n" +" PCI_ID The [<domain>:]<bus>:<slot>.<func> of the device in\n" +" hex (same as lspci)\n" +" FILE Error data file (use stdin if ommitted)\n" + , prgname, prgname, prgname); +} + +void version(const char *prgname) +{ + fprintf(stderr, +"%s %s\n" +"Copyright 2009 Intel Corporation.\n" +"Huang Ying <ying.huang@intel.com>\n" +"\n" +"This program is free software; you can redistribute it and/or\n" +"modify it under the terms of the GNU General Public License as\n" +"published by the Free Software Foundation; version 2 of the\n" +"License.\n" + , prgname, AER_VERSION); +} + void init_aer(struct aer_error_inj *aerr) { memset(aerr, 0, sizeof(struct aer_error_inj)); @@ -29,9 +65,66 @@ void submit_aer(struct aer_error_inj *err) { int fd, ret; + if (cmdline_flags & CMDLINE_PCI_ID) { + err->domain = aerr_cmdline.domain; + err->bus = aerr_cmdline.bus; + err->dev = aerr_cmdline.dev; + err->fn = aerr_cmdline.fn; + } fd = open(AER_DEV, O_WRONLY); ERROR_EXIT_ON(fd <= 0, "Failed to open device file: %s", AER_DEV); ret = write(fd, err, sizeof(struct aer_error_inj)); ERROR_EXIT_ON(ret != sizeof(struct aer_error_inj), "Failed to write"); close(fd); } + +int parse_options(int argc, char ***argv) +{ + int ret; + int c, opt_index; + struct option long_options[] = { + {"version", 0, 0, 'v'}, + {"help", 0, 0, 'h'}, + {"id", 1, 0, 's'}, + {0, 0, 0, 0} + }; + + prg_name = basename(*argv[0]); + + while (1) { + c = getopt_long(argc, *argv, "vhs:", long_options, &opt_index); + if (c == -1) + break; + switch (c) { + case 0: + break; + case 'v': + version(prg_name); + return 1; + case 's': + ret = parse_pci_id(optarg, &aerr_cmdline); + ERROR_EXIT_ON(ret, "Can not parse PCI_ID: %s\n", + optarg); + cmdline_flags |= CMDLINE_PCI_ID; + break; + case 'h': + case '?': + usage(prg_name); + return 1; + default: + usage(prg_name); + break; + } + } + + (*argv) += optind; + return 0; +} + +int main(int argc, char **argv) +{ + init_aer(&aerr_cmdline); + if (parse_options(argc, &argv)) + exit(1); + return parse_data(argv); +} @@ -3,6 +3,8 @@ #include <stdint.h> +#define AER_VERSION "0.1" + struct aer_error_inj { int8_t bus; @@ -37,6 +39,7 @@ struct aer_error_inj extern void init_aer(struct aer_error_inj *err); extern void submit_aer(struct aer_error_inj *err); extern int parse_pci_id(const char *str, struct aer_error_inj *err); +extern int parse_data(char **argv); extern char *filename; extern int yylineno; @@ -121,10 +121,10 @@ int yywrap(void) return 0; } -int main(int ac, char **av) +int parse_data(char **av) { init_lex(); - argv = ++av; + argv = av; if (*argv) yywrap(); return yyparse(); |