aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Patterson <andrew.patterson@hp.com>2010-03-10 16:01:01 +0800
committerHuang Ying <ying.huang@intel.com>2010-03-10 16:01:01 +0800
commit2a78abc1c40e7d5a57e34bfd5ff6a841757b42cf (patch)
treed34afb0750dc875bce72d36b53bb1c1e41052e20
parentc7cee585aada78f1ead17be17300c6450bc2ef55 (diff)
downloadaer-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--Makefile2
-rw-r--r--aer-inject.c93
-rw-r--r--aer.h3
-rw-r--r--aer.lex4
4 files changed, 99 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 7071bf5..ec0703a 100644
--- a/Makefile
+++ b/Makefile
@@ -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);
+}
diff --git a/aer.h b/aer.h
index 4a2c7e3..fa488b2 100644
--- a/aer.h
+++ b/aer.h
@@ -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;
diff --git a/aer.lex b/aer.lex
index 932ba97..a2dea48 100644
--- a/aer.lex
+++ b/aer.lex
@@ -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();