[ Previous |
Next |
Contents |
Home |
Search ]
AIX Version 4.3 Understanding the Diagnostic Subsystem for AIX
Example Diagnostic Application
/*
* COMPONENT_NAME : DAXYZ - diagnostic application for resource xyz
*
* FUNCTIONS : main
tu_test
clean_up
stand_by_screen
loop_stand_by_screen
check_rc
ela
check_microcode
*/
#include <stdio.h>
#include <locale.h>
#include <cf.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ldr.h>
/* ... etc (any necessary system header files)*/
#include <diag/da.h>
#include <diag/diago.h>
#include <diag/diag.h>
#include <diag/tm_input.h>
#include <diag/tmdefs.h>
#include <diag/diag_exit.h>
#include "dxyz_msg.h"
#include "dxyz.h"
/************************************************/
/* If the application wants detailed error data */
/* then include the header file containing the */
/* structures for the error or output data, else*/
/* do not include. This header file is normally */
/* dropped with the test unit code. */
/************************************************/
#include "device_err_detail.h"
/************************************************/
/* If the application uses special input data */
/* then include the header file which must be */
/* common between the DA and TU, else */
/* do not include. Manufacturing and HTX use */
/* only. This header file is normally */
/* dropped with the test unit code. */
/************************************************/
#include "device_input_params.h"
/************************************************/
/* Include the tucb header file. */
/************************************************/
#include <diag/tucb.h>
/* TU operation defines */
#define TU_OPEN 1
#define TU_CLOSE 0xEFFF
/* OTHERS AS REQUIRED */
int reg_tu_seq[6] =
{
TU_OPEN,
18,
19,
3,
4,
TU_CLOSE /*Problem determination sequence*/
};
int sys_tu_seq[8] =
{
TU_OPEN,
18,
19,
3,
4,
8,
17,
TU_CLOSE /*System checkout sequence*/
};
/*fru_bucket is a structure that holds information for the diagnostic
program to return to the diagnostic controller when a failure is
found that needs to be reported. (FRU means Field Replaceable Unit).
*/
struct fru_bucket frub[] =
{
{"", FRUB1, 0x849, 0x210, R_XYZ_ADAPTER,
{
{87,"","",0,DA_NAME,NONEXEMPT},
{13,"DRAM Sip","00-00-00",F_XYZ_DRAM,NOT_IN_DB,EXEMPT},
},
},
{"", FRUB1, 0x849, 0, R_ELA,
{
{90,"","",0,DA_NAME,NONEXEMPT},
{10,"","",0,PARENT_NAME, NONEXEMPT},
},
},
{"", FRUB1, 0x849, 0x160, R_V35_CABLE,
{
{95,"V35 Cable", "",CABLEFRU,0,0},
{5,"","",0,DA_NAME,NONEXEMPT},
},
},
};
struct msglist plug_37[] = {
{Q_PLUG_37_PIN,Q_PLUG_37_PIN_TITLE},
{Q_PLUG_37_PIN,Q_PLUG_37_PIN_YES},
{Q_PLUG_37_PIN,Q_PLUG_37_PIN_NO},
{Q_PLUG_37_PIN,Q_PLUG_37_PIN_ACTION},
NULL
};
/* The above messages are stored in the DA message file - dxyz.msg.
The following screen will be displayed by making an ASL
call during the execution of this DA. The complete DA will have
more menus displayed during different instances. */
#define IS_CONSOLE ((int)(tm_input.console == CONSOLE_TRUE))
/* include your own macros here */
static ASL_SCR_INFO q_plug_37[DIAG_NUM_ENTRIES(plug_37)];
/* include additional msglist here */
static ASL_SCR_TYPE menutype = DM_TYPE_DEFAULTS;
/* static variables */
struct tm_input tm_input;
struct errdata err_data;
struct stat *tmpbuf;
int envflag;
char *slot;
char *libpath = NULL;
nl_catd fdes;
short state;
int diskette_based;
int fd;
int rc;
int i;
int val;
int (*tu_entry)();
FILE *fd;
TU_TYPE dev_tucb;
TU_TYPE *dev_tucb_ptr;
TU_INFO_HANDLE *tu_handle = (TU_INFO_HANDLE *)NULL;
TU_RETURN_TYPE tu_rc;
void tu_test(int);
/* external functions */
extern getdainput();
extern addfrub();
unsigned int dtoh();
main()
{
/*variables declaration */
DA_SETRC_STATUS(DA_STATUS_GOOD);
DA_SETRC_ERROR(DA_ERROR_NONE);
DA_SETRC_USER(DA_USER_NOKEY);
DA_SETRC_TESTS(DA_TEST_FULL);
DA_SETRC_MORE(DA_MORE_NOCONT);
/*initialize locale environment*/
setlocale(LC_ALL, "");
/*initialize the Configuration database*/
init_dgodm();
/* get input environment */
if (getdainput(&tm_input)!= 0) {
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
}
/*if using console - initialize ASL and open message catalog*/
if (IS_CONSOLE) {
diag_asl_init("DEFAULT");
fdes=diag_catopen(MF_XYZ,0);
}
/*display initial screen depending on loopmode*/
if(tm_input.loopmode==LOOPMODE_NOTLM) {
stand_by_screen();
}
else
loop_stand_by_screen();
/*verify existence of any microcode needed to run*/
check_microcode();
/* TU initialization*/
dev_tucb_ptr = &dev_tucb;
dev_tucb_ptr->resource_name = tm_input.dname;
/* If detailed output data is not desired, then set to NULL */
dev_tucb_ptr->parms.data_log = (void *)NULL;
dev_tucb_ptr->parms.data_log_length = (long)0;
/* Else If detailed output data is expected, then malloc some space */
dev_tucb_ptr->parms.data_log =
(OUTPUT_DATA*)malloc(sizeof(OUTPUT_DATA));
/* This particular test wants to use the crc_test structure */
/* See {device}_err_detail.h file for details */
dev_tucb_ptr->parms.data_log_length = (long)sizeof(
dev_tucb_ptr->parms.data_log->crc_test);
/* If specific input data is not used, then set to NULL */
dev_tucb_ptr->parms.tu_data = (void *)NULL;
dev_tucb_ptr->parms.tu_data_length = (long)0;
/* Else If specific input data is used, then malloc some space */
dev_tucb_ptr->parms.tu_data = (INPUT_DATA *)malloc(sizeof(INPUT_DATA));
dev_tucb_ptr->parms.tu_data_length = (long)sizeof(
dev_tucb_ptr->parms.tu_data);
/* and set whatever input parameters required */
dev_tucb_ptr->parms.tu_data->mfg_mode = 5;
/* If not using a file for debug messages, set to NULL */
/* Use the environment variable DIAG_DEBUG */
if( (char *)getenv("DA_DEBUG") == (char *)NULL)
dev_tucb_ptr->parms.msg_file = (FILE *)NULL;
/* Else open a file and set FILE * */
else {
fd = (FILE *)fopen("/tmp/debug.file", "w");
dev_tucb_ptr->parms.msg_file = fd;
}
/*--------------------------------------*/
/*- Load the Test Unit Library -*/
/*--------------------------------------*/
/* The path for the test unit library will be */
/* in /usr/lpp/diagnostics/lib directory. */
if( (libpath = (char *)getenv("DIAGNOSTICS_TU_LIB")) != NULL )
tu_entry = load("libtu_device", L_LIBPATH_EXEC, libpath);
else
tu_entry = load("/usr/lpp/diagnostics/lib/libtu_device",
L_LIBPATH_EXEC, (char *)NULL);
if (tm_input.dmode!=DMODE_ELA) {
if(tm_input.system==SYSTEM_TRUE) {
/* System Checkout*/
if (tm_input.loopmode==LOOPMODE_NOTLM)
stand_by_screen();
else
loop_stand_by_screen();
/* Execute system checkout sequence*/
for(i=0;i<10; ++i)
tu_test(sys_tu_seq[i]);
}
/* Diagnostic Routines */
else if (tm_input.loopmode==LOOPMODE_NOTLM) {
stand_by_screen();
if (IS_CONSOLE) {
/*Execute problem determination sequence */
for (i=0; i<9; ++i)
/*Problem Determination */
tu_test(reg_tu_seq[i]);
/* After running "regular" TUs, see if Advanced Diag is invoked */
if(tm_input.advanced==ADVANCED_TRUE) {
/* Ask user if a particular wrap plug
is available */
rc=diag_diplay(0x00,fdes,plug_37,DIAG_IO,
ASL_DIAG_LIST_CANCEL_EXIT_SC,&menutype,q_plug_37);
check_rc(rc);
if (rc==DIAG_ASL_COMMIT)
switch (DIAG_ITEM_SELECTED(menutype)) {
case 1: /* Answer is YES */
slot = tm_input.dnameloc;
rc=diag_msg(0x902000,fdes,
PLUG_37_PIN,
PLUG_37_PIN_TITLE,slot);
check_rc(rc);
stand_by_screen();
tu_test(10);
rc=diag_msg(0x902001,fdes,
UNPLUG_37_PIN,
UNPLUG_37_PIN_TITLE,slot);
check_rc(rc);
break;
case 2: /* Answer is NO */
break;
default:
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
break;
} /* end switch */
}/* end Advanced Tests*/
stand_by_screen();
/* execute remaining tests in problem determination, if any */
tu_test(17);
}
else { /*Console false - execute System Checkout
sequence */
for (i=0; i<10; ++i)
tu_test(sys_tu_seq[i]);
}
} /* end problem determination - diagnostic routines */
else
{/* Must be loop mode */
switch (tm_input.loopmode) {
case LOOPMODE_ENTERLM:
loop_stand_by_screen();
val = 0;
putdavar(tm_input.dname, "vname",
DIAG_INT, &val);
/* Do what is necessary - enter loop mode */
ela();
break;
case LOOPMODE_INLM:
loop_stand_by_screen();
getdavar(tm_input.dname, "vname",
DIAG_INT, &val);
/* Do what is necessary - IN loop mode */
break;
case LOOPMODE_EXITLM:
getdavar(tm_input.dname, "vname",
DIAG_INT, &val);
/* Do what is necessary - EXIT loop mode.
For example,put of menus to restore
machine's original state. */
break;
default:
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
break;
} /* end switch - loop mode */
} /* end if-else - loop mode */
} /* end if ! ELA *//PRE
PREA NAME="A2710A0F224melh"/A /* Performing Error Log Analysis */
if (((tm_input.dmode==DMODE_PD) || (tm_input.dmode==DMODE_ELA))
&& (tm_input.loopmode==LOOPMODE_NOTLM))
ela();
DA_SETRC_ERROR(DA_ERROR_NONE);
DA_SETRC_TESTS(DA_TEST_FULL);
clean_up();
} /*end main *//PRE
PREA NAME="A2710A0F251melh"/A
/*
* NAME : tu_test
*
* FUNCTION : Executes test units and reports FRUs to the controller
* if a failure is found.
*
* EXECUTION ENVIRONMENT :
*
* Called by the main program to execute test units.
* Call external routine exectu to actually execute the test units.
* Call external routine diag_asl_read to get user's input to screen
* e.g. Cancel or Exit.
* Call external routines insert_frub and addfrub when a failure
* is found.
* Call clean_up after a fru is reported to the controller.
*
* RETURNS : NONE
*
*/
void tu_test(int tunum)
{
ulong major_rc; /*return code from test unit */
dev_tucb_ptr->parms.tu = tunum;
dev_tucb_ptr->parms.loop = 1; /* command loop */
major_rc = tu_entry(dev_tucb_ptr, &tu_handle, &tu_rc);
if ( fd != (FILE *) NULL)
fprintf( fd,"(DA)TU_OPEN - major_rc = %d\n", tu_rc.major_rc);
if (IS_CONSOLE) {
rc = diag_asl_read(ASL_DIAG_KEYS_ENTER_SC,FALSE,NULL);
check_rc(rc);
}
if (major_rc !=0 ) {
switch (tunum) {
case 1:
if (major_rc < 0x00) {
rc = insert_frub(&tm_input,&frub[2]);
if (rc != 0) {
DA_SETRC_STATUS(DA_STATUS_BAD);
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
}
strncpy (frub[2].dname,
tm_input.dname,sizeof(frub[0].dname));
addfrub(&frub[2]);
}
break;
case 3:
case 9:
case 10:
/*etc*/
case 16:
break;
default :
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
break;
} /* end switch*/
DA_SETRC_STATUS(DA_STATUS_BAD);
DA_SETRC_MORE(DA_MORE_NOCONT);
DA_SETRC_TESTS(DA_TEST_FULL);
clean_up();
} /* end - if*/
} /* end tu_test */
/* clean_up */
clean_up()
{
if (fd>0)
close (fd);
/*--------------------------------------*/
/*- UnLoad the Test Unit Library -*/
/*--------------------------------------*/
rc = unload((void *)tu_entry);
/* Restore machine to original state, if you need to switch back
microcode, do it here. */
if (IS_CONSOLE) {
diag_asl_quit(); /* close ASL */
catclose(fdes);
}
term_dgodm(); /* close ODM */
DA_EXIT();
} /* end clean_up*/
/*stand_by_screen*/
int
stand_by_screen()
{
char *text_array[3];
text_array[0] = diag_cat_gets(fdes, DESC, MSG1 );
text_array[1] = tm_input.dname;
text_array[2] = tm_input.dnameloc;
if (IS_CONSOLE) {
switch (tm_input.advanced) {
case ADVANCED_TRUE:
rc = diag_display_menu(ADVANCED_TESTING_MENU,0x902002,
text_array,0,0);
break;
case ADVANCED_FALSE:
rc = diag_display_menu(CUSTOMER_TESTING_MENU,0x902003,
text_array,0,0);
break;
default:
break;/*not really necessary*/
}
check_rc(rc);
}
} /*end stand_by_screen */
/* loop_stand_by_screen */
int
loop_stand_by_screen()
{
char *text_array[3];
text_array[0] = diag_cat_gets(fdes, DESC, MSG1 );
text_array[1] = tm_input.dname;
text_array[2] = tm_input.dnameloc;
if (IS_CONSOLE) {
rc = diag_display_menu(LOOPMODE_TESTING_MENU,0x902004,
text_array, tm_input.lcount,tm_input.lerrors);
check_rc(rc);
}
} /*end loop_stand_by_screen */
/* check_rc */
int
check_rc(rc)
int rc; /* user's input */
{
if (rc == DIAG_ASL_CANCEL) {
/*force microcode swap - if applies */
tm_input.loopmode = LOOPMODE_EXITLM;
DA_SETRC_USER(DA_USER_QUIT);
DA_SETRC_TESTS(DA_TEST_FULL);
clean_up();
}
if (rc == DIAG_ASL_EXIT) {
DA_SETRC_USER(DA_USER_EXIT);
DA_SETRC_TESTS(DA_TEST_FULL);
clean_up();
}
return (rc);
} /* end check_rc */
/* ela */
int
ela()
{
char crit[255];
sprintf(crit, "-N %s %s", tm_input.dname,tm_input.date);
rc = error_log_get (INIT,crit,&err_data);
while (rc !=0) {
if (rc == -1) {
DA_SETRC_STATUS(DA_STATUS_GOOD);
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
}
else if (rc>0) {
if((err_data.err_id == 0x0000000) || (err_data.err_id == 0x000000)) {
rc = insert_frub(&tm_input,&frub[1]);
if (rc !=0) {
DA_SETRC_STATUS(DA_STATUS_GOOD);
DA_SETRC_ERROR(DA_ERROR_OTHER);
DA_SETRC_TESTS(DA_TEST_FULL);
clean_up();
}
strncpy (frub[1].dname,tm_input.dname,
sizeof(frub[1].dname));
addfrub (&frub[1]);
DA_SETRC_STATUS(DA_STATUS_BAD);
clean_up();
} /* end if */
rc = error_log_get (SUBSEQ,crit,&err_data);
}
rc = error_log_get (TERMI,crit,&err_data);
if (rc == -1) {
DA_SETRC_STATUS(DA_STATUS_GOOD);
DA_SETRC_ERROR(DA_ERROR_OTHER);
clean_up();
}
}
}
/* check_microcode */
int
check_microcode()
{
char mpath[255];
char *no_rcm_msg;
char *no_diag_msg;
/* Check if the functional microcode file xxxx.xxx is present.
Check only if diagnostics is run off hard disk */
envflag = ipl_mode(&diskette_based);
if (diskette_based == DIAG_FALSE) {
if (0 > (rc = findmcode("funcmcode",mpath,VERSIONING, NULL))) {
sprintf(no_rcm_msg,catgets(fdes,NO_RCM,NO_RCM_TITLE,
NULL));
menugoal(no_rcm_msg);
}
}
/* Check if all the diagnostic microcode files are present. */
if (0 > (rc = findmcode("diagmcode", mpath, VERSIONING, NULL))) {
sprintf(no_diag_msg,catgets(fdes,MENU_SET,NO_
DIAGMICROCODE_MENU,NULL));
menugoal(no_diag_msg);
clean_up();
}
}
[ Previous |
Next |
Contents |
Home |
Search ]