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
commitc7cee585aada78f1ead17be17300c6450bc2ef55 (patch)
tree3bb1e8461b1f345c410882e85b6e40b0115c6fec
parent857ea0e4b4bff0c0fd4d2309991158e4358b18e5 (diff)
downloadaer-inject-c7cee585aada78f1ead17be17300c6450bc2ef55.tar.gz
aer-inject: use lspci-style PCI ID
Use the lspci -s style of specificying a PCI device [<domain>]:]<bus>:<slot>.<func> instead of DOMAIN <domain> BUS <bus> DEV <dev> FN <func>. Huang Ying: check the syntax and extract the string of PCI_ID in lex, then parse the string later in yacc. Signed-off-by: Andrew Patterson <andrew.patterson@hp.com> Signed-off-by: Huang Ying <ying.huang@intel.com>
-rw-r--r--SPEC25
-rw-r--r--aer.h1
-rw-r--r--aer.lex10
-rw-r--r--aer.y38
4 files changed, 62 insertions, 12 deletions
diff --git a/SPEC b/SPEC
index 00bade3..d2c66db 100644
--- a/SPEC
+++ b/SPEC
@@ -22,12 +22,29 @@ The error always starts with:
AER
-The description of error follows:
+Followed by
+
+PCI_ID pci_id
+
+These specify the PCI device or port via domain number, bus number,
+dev number and function number using the same format as the lspci
+command:
+
+ WWWW:XX:YY.Z
+
+ Where
+
+ WWWW is the domain (segment) in hexidecimal (optional)
+ XX is the bus number in hexidecimal
+ YY is the device number in hexidecimal
+ Z is the function number in hexidecimal
+
+Alternatively, you can use:
BUS number DEV number FN number
-These specify the PCI device or port via PCI bus number, dev number
-and function number
+Number can be a decimal or hex (using 0x).
+
COR_STATUS {RCVR|BAD_TLP|BAD_DLLP|REP_ROLL|REP_TIMER|number}
@@ -41,7 +58,7 @@ injected and corresponding TLP header log.
multiple fields can be on a line.
-number can be hex/octal/decimal in the usual C format.
+number (except for pci_id) can be hex/octal/decimal in the usual C format.
Multiple errors can be in a single file, each new one starts with
"AER".
diff --git a/aer.h b/aer.h
index 00d98cd..4a2c7e3 100644
--- a/aer.h
+++ b/aer.h
@@ -36,6 +36,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 char *filename;
extern int yylineno;
diff --git a/aer.lex b/aer.lex
index b79733a..932ba97 100644
--- a/aer.lex
+++ b/aer.lex
@@ -29,13 +29,16 @@ static int lookup_symbol(const char *);
%option nounput
+HEXC [0-9a-fA-F]
+
%%
#.*\n /* comment */;
\n ++yylineno;
-0x[0-9a-fA-F]+ |
+({HEXC}{4}:)?{HEXC}{2}:{HEXC}{2}\.{HEXC} { yylval.str = strdup(yytext); return PCI_ID_STR; }
+0x{HEXC}+ |
0[0-7]+ |
-[0-9]+ yylval = strtoull(yytext, NULL, 0); return NUMBER;
+[0-9]+ yylval.num = strtoull(yytext, NULL, 0); return NUMBER;
[:{}<>] return yytext[0];
[_a-zA-Z][_a-zA-Z0-9]* return lookup_symbol(yytext);
[ \t]+ /* white space */;
@@ -57,6 +60,7 @@ static struct key {
KEY(BUS),
KEY(DEV),
KEY(FN),
+ KEY(PCI_ID),
KEY(UNCOR_STATUS),
KEY(COR_STATUS),
KEY(HEADER_LOG),
@@ -92,7 +96,7 @@ static int lookup_symbol(const char *name)
key.name = name;
k = bsearch(&key, keys, ARRAY_SIZE(keys), sizeof(struct key), cmp_key);
if (k != NULL) {
- yylval = k->val;
+ yylval.num = k->val;
return k->tok;
}
return SYMBOL;
diff --git a/aer.y b/aer.y
index f30ad8b..a8ad063 100644
--- a/aer.y
+++ b/aer.y
@@ -27,11 +27,19 @@ static void init(void);
%}
-%token AER DOMAIN BUS DEV FN UNCOR_STATUS COR_STATUS HEADER_LOG
-%token TRAIN DLP POISON_TLP FCP COMP_TIME COMP_ABORT UNX_COMP RX_OVER MALF_TLP
-%token ECRC UNSUP
-%token RCVR BAD_TLP BAD_DLLP REP_ROLL REP_TIMER
-%token NUMBER SYMBOL
+%union {
+ int num;
+ char *str;
+}
+
+%token AER DOMAIN BUS DEV FN PCI_ID UNCOR_STATUS COR_STATUS HEADER_LOG
+%token <num> TRAIN DLP POISON_TLP FCP COMP_TIME COMP_ABORT UNX_COMP RX_OVER
+%token <num> MALF_TLP ECRC UNSUP
+%token <num> RCVR BAD_TLP BAD_DLLP REP_ROLL REP_TIMER
+%token <num> SYMBOL NUMBER
+%token <str> PCI_ID_STR
+
+%type<num> uncor_status_list uncor_status cor_status_list cor_status
%%
@@ -56,6 +64,8 @@ aer_term: UNCOR_STATUS uncor_status_list { aerr.uncor_status = $2; }
aerr.bus = $2;
aerr.dev = $4;
aerr.fn = $6; }
+ | PCI_ID PCI_ID_STR { parse_pci_id($2, &aerr);
+ free($2); }
| HEADER_LOG NUMBER NUMBER NUMBER NUMBER { aerr.header_log0 = $2;
aerr.header_log1 = $3;
aerr.header_log2 = $4;
@@ -84,6 +94,24 @@ static void init(void)
init_aer(&aerr);
}
+int parse_pci_id(const char *str, struct aer_error_inj *aerr)
+{
+ int cnt;
+
+ cnt = sscanf(str, "%04hx:%02hhx:%02hhx.%01hhx",
+ &aerr->domain, &aerr->bus, &aerr->dev, &aerr->fn);
+ if (cnt != 4) {
+ cnt = sscanf(str, "%02hhx:%02hhx.%01hhx",
+ &aerr->bus, &aerr->dev, &aerr->fn);
+ if (cnt == 3)
+ aerr->domain = 0;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
void yyerror(char const *msg, ...)
{
va_list ap;