CLEAR_ERRORS zeroes out the error count for all devices on a VMS Alpha system.  
CPU and memory errors are also zeroed out.

The error count for a device is stored in a data structure called a unit 
control block (UCB). All device UCBs of a particular kind (e.g. DGA1:, DGA2:, 
etc.) are linked together. The first UCB in the list is pointed to by a device 
data block (DDB).  The last UCB in the list contains a null value (0) as a 
pointer.  So the structure might look like:

           DDB
            |
            ---> UCB
                  link  ----> UCB
                  err cnt      link  ----> UCB
                               err cnt       0
                                           err cnt

Note that the UCB has over 100 fields. The above diagram just depicts a few 
fields.

All of the DDBs are linked together.  The first DDB in the list is pointed to 
by an SCS system block (SB).  The last DDB contains a null value (0) as a 
pointer.  The structure might look like:

           SB 
            |
            ---> DDB
                  link  ----> DDB
                               link  ----> DDB
                                             0
                                                   
Note that the DDB has over 20 fields. The above diagram just depicts the link 
field.

All of the SBs are arranged in a doubly linked list.  The first SB in the list 
is pointed to by the global symbol SCS$GQ_CONFIG.  The structure might look 
like:

             ------------------------------------------------
             |                                              |
    ---> SCS$GQ_CONFIG <------------------------------      |
    |        |                                        |     |
    |        --->SB                                   |     |
    |            flink  ----> SB                      |     |
    |----------  blink        flink  ----> SB         |     |
                   ^--------- blink        flink  ----|     |
                                ^--------- blink            |
                                             ^--------------|
                                                             
Note that the SB has over 20 fields. The above diagram just depicts the link 
fields.

Each VMS system has at least one SB that points to all the local devices.  If 
the system is clustered, then there will be one SB for each cluster member.  If 
there are HSJ, HSC, or HSD controllers connected, there will be one SB for each.

CLEAR_ERRORS starts at SCS$GQ_CONFIG and works its way through all these 
linked lists, zeroing the error fields at it goes.

EXE$GL_MEMERRS and EXE$CL_MCHKERRS point to memory cells that hold the number 
of memory and cpu errors, respectively.  Both are set to zero.

Zeroing the error fields can only be done from kernel mode and should be 
appropriately synchronized by acquiring the write mutex on the I/O device 
database and raising interrupt priority level(IPL).  The SYS$CMKRNL system 
service is used to reach kernel mode, and the SCH_STD$IOLOCKW internal routine 
acquires the mutex and raises IPL. An internal routine called SCH_STD$IOUNLOCK 
is used to release the mutex and lower IPL.

There is always a risk of a system crash when executing in kernel mode, 
invoking undocumented routines, and navigating internal data structures.  
CLEAR_ERRORS performs two steps to minimize the chance of a system crash. The 
first is to see if CLEAR_ERRORS is executing on the same release of VMS that it 
was linked on.  The VMS release id (e.g. V7.3-1) is not stored in the image 
header.  However, the image id of the linker is, and this is compared to the 
image id in SYS$SYSTEM:LINK.EXE.  If they match, then we assume the VMS 
releases are the same. If they don't match, then we abort.  For VMS V7.1-1H1 
the linker image id is A11-39, for V7.2-1 it is A11-50, and for V7.3 and V7.3-1 
it is A12-03.

The second step to minimize the chance of a crash is to declare a condition 
handler as soon as we reach kernel mode.  In CLEAR_ERRORS, "nocrash" is the 
name of the exit handler. If "nocrash" executes it will release the mutex on 
the I/O device database if one was acquired and drop IPL.  This will avoid a 
crash, but the process will likely be deleted if a SYS$EXIT is performed.  So 
"nocrash" calls EXE$REI_INIT_STACK to change the access mode from kernel to 
user.  EXE$REI_INIT_STACK turns control over to a routine called 
"graceful_exit" after the mode change.

CLEAR_ERRORS was compiled, linked, and tested on VMS V7.3 using C V6.5-001.  
The object was also linked and tested on VMS V7.1-1H1 and V7.2-1. 

The error handler ("nocrash") was also tested by causing an access violation 
in kernel mode at elevated IPL with the I/O database locked, and "nocrash" was 
able to avoid a system crash.
