1
0
Files
irix-657m-src/irix/cmd/icrash_old/lib/libfru/fru_matcher.c
2022-09-29 17:59:04 +03:00

252 lines
5.2 KiB
C

/*
* fru_matcher.c-
*
* This file contains code to compare the hardware error state
* structure with various patterns to allow us to diagnose difficult
* cases directly. This works in conjuction with pattern matching code
* in each of the fru_*.c files for the various kinds of boards.
*
*/
#ifdef FRU_PATTERN_MATCHER
#include "evfru.h"
#include "fru_pattern.h"
fru_entry_t *token;
fru_case_t *case_ptr;
fru_case_t *find_case(int);
int
fru_check_patterns(everror_t *ee, evcfginfo_t *ec, whatswrong_t *diag)
{
int case_id;
int board_id;
int match;
token = fru_patterns;
while ((token = next_token(token)) &&
(token->entry_type != ENDPATTERNS)) {
if (token->entry_type != BEGINCASE) {
FRU_PRINTF("Bad token! Should start with BEGINCASE\n");
return -1;
}
/* BEGINCASE tokens include the case id in the "value" field. */
case_id = token->value;
case_ptr = find_case(case_id);
while (token = next_token(token)) {
if (token->entry_type == ENDCASE) {
break;
}
if (token->entry_type != BEGINBOARD) {
FRU_PRINTF("Bad token: %s! Board should start with BEGINBOARD\n",
decode_control_token(token));
return -1;
}
/* XXX - Need to add code to make sure that the boards exist before declaring
* a match. */
switch(token->value) {
case EVTYPE_IP19:
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("EVTYPE_IP19\n");
#endif
match = match_ip19board(&token, ee, ec, diag, case_ptr);
break;
case EVTYPE_IP21:
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("EVTYPE_IP21\n");
#endif
match = match_ip21board(&token, ee, ec, diag, case_ptr);
break;
case EVTYPE_IO4:
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("EVTYPE_IO4\n");
#endif
match = match_io4board(&token, ee, ec, diag, case_ptr);
break;
case EVTYPE_MC3:
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("EVTYPE_MC3\n");
#endif
match = match_mc3board(&token, ee, ec, diag, case_ptr);
break;
default:
FRU_PRINTF("Bad board type (0x%x)\n", token->value);
break;
}
if (!match) {
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("No match! (Case %d)\n", CASE_ID(case_ptr));
#endif
/* We didn't match, skip the rest of this case. */
token = find_case_end(token);
continue;
}
}
if (match == -1) {
FRU_PRINTF("Error in case %d description, aborting.\n", case_id);
return 0;
}
if (token->entry_type == ENDCASE) {
/* We _did_ match. Return the information */
#ifdef DEBUG
if (fru_debug)
FRU_PRINTF("Case %d match!\n");
#endif
return CONFIDENCE(case_ptr);
}
}
}
fru_case_t *find_case(int case_id)
{
int i;
for (i = 0; i < num_fru_cases; i++) {
if (fru_cases[i].case_id == case_id)
return &fru_cases[i];
}
return (fru_case_t *)0;
}
void update_pattern(whatswrong_t *ww, fru_case_t *cp, short utype, short unum)
{
ww->confidence = CONFIDENCE(cp);
ww->case_id = CASE_ID(cp);
ww->src.unit_type = utype;
ww->src.unit_num = unum;
ww->dest.unit_type = FRU_NONE;
}
fru_entry_t *next_token(fru_entry_t *cur_token)
{
cur_token++;
if ((__psint_t)cur_token < (__psint_t)&fru_patterns[0]) {
FRU_PRINTF("Token pointer (0x%x) below minimum\n", cur_token);
return (fru_entry_t *)0;
}
if ((__psint_t)cur_token > (__psint_t)&fru_patterns[num_fru_patterns]) {
FRU_PRINTF("Token pointer (0x%x) above maximum\n", cur_token);
return (fru_entry_t *)0;
}
return cur_token;
}
fru_entry_t *find_case_end(fru_entry_t *cur_token)
{
while (cur_token && (cur_token->entry_type != ENDCASE))
cur_token = next_token(cur_token);
return cur_token;
}
fru_entry_t *find_board_end(fru_entry_t *cur_token)
{
while (cur_token && (cur_token->entry_type != ENDBOARD))
cur_token = next_token(cur_token);
return cur_token;
}
fru_entry_t *prev_token(fru_entry_t *cur_token)
{
cur_token--;
if ((__psint_t)cur_token < (__psint_t)&fru_patterns[0]) {
FRU_PRINTF("Token pointer (0x%x) below minimum\n", cur_token);
return (fru_entry_t *)0;
}
if ((__psint_t)cur_token > (__psint_t)(&fru_patterns[num_fru_patterns])) {
FRU_PRINTF("Token pointer (0x%x) above maximum\n", cur_token);
return (fru_entry_t *)0;
}
return cur_token;
}
int is_control_token(fru_entry_t *token)
{
if ((token->entry_type == BEGINCASE) ||
(token->entry_type == BEGINBOARD) ||
(token->entry_type == BEGINSUBUNIT) ||
(token->entry_type == ENDSUBUNIT) ||
(token->entry_type == ENDBOARD) ||
(token->entry_type == ENDCASE) ||
(token->entry_type == ENDPATTERNS))
return 1;
else
return 0;
}
int is_fru_token(fru_entry_t *token)
{
if (token->entry_type == FRU_POINTER)
return 1;
else
return 0;
}
char *decode_control_token(fru_entry_t *token)
{
switch(token->entry_type) {
case BEGINPATTERNS:
return "BEGINPATTERNS";
case BEGINCASE:
return "BEGINCASE";
case BEGINBOARD:
return "BEGINBOARD";
case BEGINSUBUNIT:
return "BEGINSUBUNIT";
case ENDSUBUNIT:
return "ENDSUBUNIT";
case ENDBOARD:
return "ENDBOARD";
case ENDCASE:
return "ENDCASE";
case ENDPATTERNS:
return "ENDPATTERNS";
case FRU_POINTER:
return "FRU_POINTER";
default:
return "Not a control token";
}
}
#endif /* FRU_PATTERN_MATCHER */