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 | c7cee585aada78f1ead17be17300c6450bc2ef55 (patch) | |
tree | 3bb1e8461b1f345c410882e85b6e40b0115c6fec | |
parent | 857ea0e4b4bff0c0fd4d2309991158e4358b18e5 (diff) | |
download | aer-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-- | SPEC | 25 | ||||
-rw-r--r-- | aer.h | 1 | ||||
-rw-r--r-- | aer.lex | 10 | ||||
-rw-r--r-- | aer.y | 38 |
4 files changed, 62 insertions, 12 deletions
@@ -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". @@ -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; @@ -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; @@ -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; |