[ 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 ]