MODULE iom$log_disk_data;
?? RIGHT := 110 ??

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cml$disk_device_usage_data
*copyc cml$disk_path_usage_data
*copyc cml$end_disk_usage_interval
*copyc oss$job_paged_literal
*copyc oss$mainframe_paged_literal
*copyc oss$task_shared
*copyc iot$disk_statistics
*copyc iot$pp_response
*copyc iot$unit_type
*copyc ost$status
?? POP ??
*copyc cmp$return_descriptor_data
*copyc sfp$activate_system_statistic
*copyc sfp$emit_statistic
*copyc iov$disk_pp_usage_p
*copyc iov$disk_unit_usage_p
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    iov$time_to_log_usage_stats: [XDCL, oss$task_shared] integer := 0;

  CONST
    c$das_type_string_size = 8 * (ioc$dt_msntdd_6 - ioc$dt_ms5832_1 + 1);

  VAR
    das_type: [STATIC, READ, oss$mainframe_paged_literal] string (c$das_type_string_size) :=
          '5832_1  5832_2  'cat
          '5833_1  5833_1P 5833_2  5833_3P 5833_4  'cat
          '5838_1  5838_1P 5838_2  5838_3P 5838_4  'cat
          '47444_1 47444_1P47444_2 47444_3P47444_4 'cat
          '5837_1  5837_1P 5837_2  5837_3P 5837_4  'cat
          'NTDD_1  NTDD_2  NTDD_3  NTDD_4  NTDD_5  'cat
          'NTDD_6  ';

?? OLDTITLE ??
?? NEWTITLE := 'ESTABLISH_STATISTICS', EJECT ??

  PROCEDURE establish_statistics
    (VAR status: ost$status);

    CONST
      number_of_statistics = 7;

    VAR
      i: integer,
      statistics: array [1 .. number_of_statistics] of sft$statistic_code;

    statistics [1] := cml$10395_11_failure_data;
    statistics [2] := cml$7154_failure_data;
    statistics [3] := cml$7155_1x_failure_data;
    statistics [4] := cml$fa7b4_d_failure_data;
    statistics [5] := cml$7165_2x_failure_data;
    statistics [6] := cml$887_failure_data;
    statistics [7] := cml$9836_1_failure_data;

    FOR i := 1 TO number_of_statistics DO
      sfp$activate_system_statistic (statistics [i], $sft$binary_logset [pmc$engineering_log], status);
      IF status.normal = FALSE THEN
        RETURN; {----->
      IFEND;
    FOREND;

  PROCEND establish_statistics;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] IOP$LOG_DISK_DATA', EJECT ??

  PROCEDURE [XDCL] iop$log_disk_data
    (    p_datap: ^SEQ ( * );
     VAR status: ost$status);

    CONST
      status_length = ioc$disk_detailed_status_length * 4;

    VAR
      datap: ^SEQ ( * ),
      i: integer,
      j: integer,
      cell_p: ^cell,
      packets_p: ^array [0 .. 38] of ost$word,
      status_bytes_p: ^array [1 .. status_length] of 0 .. 0ffff(16),
      seq_p: ^SEQ ( * ),
      detail_status: SEQ (REP status_length of 0 .. 0ffff(16)),
      detailed_status_p: ^iot$common_disk_status,
      disk_885_status_p: ^iot$disk_detailed_status_885,
      disk_895_status_p: ^iot$895_detailed_status,
      hydra_status_p: ^iot$hydra_status,
      disk_9836_status_p: ^iot$detailed_status_9836_1,
      statistics_established: [STATIC] boolean := FALSE,
      length: integer,
      disk_log_data_p: ^iot$disk_log_data,
      counters_p: ^array [1 .. * ] of sft$counter,
      counters_p2: ^array [1 .. * ] of sft$counter,
      statistic_code: sft$statistic_code,
      symptom_code: integer,
      descriptor_data: ost$string,
      pp_number: 0 .. 0ff(16),
      iou_number: dst$iou_number,
      channel: cmt$physical_channel,
      equipment: cmt$physical_equipment_number,
      logical_unit: iot$logical_unit;


    status.normal := TRUE;
    IF NOT statistics_established THEN
      establish_statistics (status);
      IF status.normal THEN
        statistics_established := TRUE;
      ELSE
        RETURN; {----->
      IFEND;
    IFEND;
    datap := p_datap;

    NEXT disk_log_data_p IN datap;

    seq_p := ^detail_status;
    RESET seq_p;
    NEXT detailed_status_p IN seq_p;
    detailed_status_p^ := disk_log_data_p^.detailed_status;
    RESET seq_p;
    NEXT status_bytes_p IN seq_p;
    RESET seq_p;
    NEXT disk_885_status_p IN seq_p;
    RESET seq_p;
    NEXT disk_895_status_p IN seq_p;
    RESET seq_p;
    NEXT disk_9836_status_p IN seq_p;

{Get descriptor data.

    iou_number := disk_log_data_p^.iou_number;
    channel := disk_log_data_p^.channel;
    equipment := disk_log_data_p^.equipment;
    logical_unit := disk_log_data_p^.logical_unit;

    cmp$return_descriptor_data (channel, iou_number, equipment, logical_unit,
          descriptor_data, pp_number);


    CASE disk_log_data_p^.controller_type OF
    = 1 =
      statistic_code := cml$7154_failure_data;
    = 2 =
      statistic_code := cml$7155_1x_failure_data;
    = 3 =
      statistic_code := cml$10395_11_failure_data;
    = 4 =
      statistic_code := cml$fa7b4_d_failure_data;
    = 5 =
      statistic_code := cml$7165_2x_failure_data;
    = 6 =
      statistic_code := cml$887_failure_data;
    = 7, 8 =
      statistic_code := cml$9836_1_failure_data;
    ELSE
    CASEND;


    CASE statistic_code OF
    = cml$7154_failure_data, cml$7155_1x_failure_data, cml$10395_11_failure_data,
      cml$fa7b4_d_failure_data =
      IF disk_log_data_p^.failure_severity = 0 THEN
        length := 39;
      ELSE
        length := 60;
      IFEND;
    = cml$7165_2x_failure_data =
      IF disk_log_data_p^.failure_severity = 0 THEN
        length := 40;
      ELSE
        length := 62;
      IFEND;
    = cml$887_failure_data =
      length := 59;
    = cml$9836_1_failure_data =
{     length := 40;   24 fixed counters, 16 (= 64 * 16 bit words) of the response packet
      length := 50; { 24 fixed counters, 26 (= 104 * 16 bit words) of the response packet
    ELSE
    CASEND;

    PUSH counters_p: [1 .. length];

    {   Set counter [1] to the PP number. Set bit 57 for an I4 concurrent PP.
    {                                     Set bits 46 - 51 to IOU number.
    {   Set counter [2] to the Channel number.  Set bit 57 if an I4 concurrent channel.
    {                                           Set bit 56 if I4 concurrent PORT B.
    {                                           Set bit 55 if I4 concurrent PORT A.
    {                                           Set bits 46 - 51 to IOU number.
    CASE disk_log_data_p^.channel.port OF
    = cmc$port_a =
      counters_p^ [1] := pp_number + 40(16);
      counters_p^ [2] := disk_log_data_p^.channel.number + 40(16) + 100(16);
    = cmc$port_b =
      counters_p^ [1] := pp_number + 40(16);
      counters_p^ [2] := disk_log_data_p^.channel.number + 40(16) + 80(16);
    ELSE
      IF channel.concurrent THEN
        counters_p^ [1] := pp_number + 40(16);
        counters_p^ [2] := disk_log_data_p^.channel.number + 40(16);
      ELSE
        counters_p^ [1] := pp_number;
        counters_p^ [2] := disk_log_data_p^.channel.number;
      IFEND;
    CASEND;
    counters_p^ [1] := counters_p^ [1] + iou_number * 1000(16);
    counters_p^ [2] := counters_p^ [2] + iou_number * 1000(16);

    CASE disk_log_data_p^.disk_type OF
    = ioc$dt_ms895_2 =
      counters_p^ [3] := disk_log_data_p^.equipment * 2;
      counters_p^ [4] := disk_log_data_p^.physical_unit;
      IF disk_log_data_p^.physical_unit > 15 THEN
        counters_p^ [3] := counters_p^ [3] + 1;
        counters_p^ [4] := counters_p^ [4] - 16;
      IFEND;
    ELSE
      counters_p^ [3] := disk_log_data_p^.equipment;
      counters_p^ [4] := disk_log_data_p^.physical_unit;
    CASEND;

    counters_p^ [5] := disk_log_data_p^.disk_type MOD 100(16);
    IF counters_p^ [5] < 2 THEN
      counters_p^ [5] := counters_p^ [5] + 1;
    IFEND;

    counters_p^ [6] := disk_log_data_p^.logical_operation;

    counters_p^ [7] := disk_log_data_p^.failure_severity;
    IF (counters_p^[7] = 1) AND (statistic_code = cml$9836_1_failure_data) THEN
      counters_p^ [7] := disk_log_data_p^.isolation_code * 10000(16) + counters_p^ [7];
    IFEND;
    IF (statistic_code = cml$9836_1_failure_data) AND (disk_log_data_p^.isolation_code = 4) THEN
      counters_p^ [7] := 40001(16);
    IFEND;

    counters_p^ [8] := disk_log_data_p^.symptom_code;

    counters_p^ [9] := disk_log_data_p^.detailed_status.general_status.
          request_retry;
    CASE statistic_code OF
    = cml$7154_failure_data, cml$7155_1x_failure_data =
      counters_p^ [10] := disk_log_data_p^.detailed_status.general_status.
            sector_retry_count;
    = cml$10395_11_failure_data, cml$fa7b4_d_failure_data, cml$887_failure_data,
      cml$7165_2x_failure_data =
      counters_p^ [10] := 0;
    = cml$9836_1_failure_data =
      IF (disk_log_data_p^.diagnostic_code = 0) OR (counters_p^ [8] = ioc$9836_1_cont_diag_passed_2)
          OR (disk_log_data_p^.diagnostic_code DIV 10000(16) = 80(16)) THEN
        counters_p^ [10] := ioc$no_value;
      ELSE
        counters_p^ [10] := disk_log_data_p^.diagnostic_code;
      IFEND;
    ELSE
      counters_p^ [10] := ioc$no_value;
    CASEND;
    counters_p^ [11] := disk_log_data_p^.detailed_status.general_status.
          starting_cylinder;
    counters_p^ [12] := disk_log_data_p^.detailed_status.general_status.
          starting_track;
    counters_p^ [13] := disk_log_data_p^.detailed_status.general_status.
          starting_sector;
    counters_p^ [14] := disk_log_data_p^.detailed_status.general_status.
          starting_cylinder;
    counters_p^ [15] := disk_log_data_p^.detailed_status.general_status.
          failing_track;
    counters_p^ [16] := disk_log_data_p^.detailed_status.general_status.
          failing_sector;
    IF statistic_code = cml$9836_1_failure_data THEN
      counters_p^ [17] := disk_9836_status_p^.residual_word_count;
    ELSE
      IF disk_log_data_p^.detailed_status.general_status.
            incomplete_sector_transfer THEN
        counters_p^ [17] := disk_log_data_p^.detailed_status.general_status.
            function_timeout;
      ELSE
        counters_p^ [17] := ioc$no_value;
      IFEND;
    IFEND;
    IF statistic_code = cml$9836_1_failure_data THEN
      counters_p^ [18] := disk_9836_status_p^.failing_function;
    ELSE
      IF disk_log_data_p^.pp_response.abnormal_status.function_timeout THEN
        counters_p^ [18] := disk_log_data_p^.detailed_status.general_status.
            function_timeout;
      ELSEIF statistic_code <> cml$887_failure_data THEN
        IF disk_log_data_p^.detailed_status.general_status.
            detailed_status_present THEN
          counters_p^ [18] := disk_885_status_p^.part1.pp_command;
        ELSE
          counters_p^ [18] := ioc$no_value;
        IFEND;
      ELSE
        counters_p^ [18] := ioc$no_value;
      IFEND;
    IFEND;

{Log general and detailed status.

    CASE statistic_code OF
    = cml$7154_failure_data, cml$7155_1x_failure_data, cml$10395_11_failure_data,
      cml$fa7b4_d_failure_data =
      counters_p^ [19] := disk_log_data_p^.detailed_status.general_status.
            first_general_status;
      IF disk_log_data_p^.failure_severity <> 0 THEN
        counters_p^ [40] := disk_log_data_p^.detailed_status.general_status.
              last_general_status;
      IFEND;

      FOR i := 1 TO 20 DO
        counters_p^ [19 + i] := status_bytes_p^ [16 + i];
        IF disk_log_data_p^.failure_severity <> 0 THEN
          counters_p^ [40 + i] := status_bytes_p^ [36 + i];
        IFEND;
      FOREND;
    = cml$7165_2x_failure_data =
      counters_p^ [19] := disk_log_data_p^.detailed_status.general_status.
            first_general_status;
      IF disk_log_data_p^.channel.concurrent THEN
        counters_p^ [40] := disk_895_status_p^.op_status * 10000(16) +
              disk_895_status_p^.first_error_register;
      ELSE
        counters_p^ [40] := ioc$no_value;
      IFEND;

      FOR i := 1 TO 20 DO
        counters_p^ [19 + i] := status_bytes_p^ [20 + i];
      FOREND;

      IF disk_log_data_p^.failure_severity <> 0 THEN
        FOR i := 1 TO 22 DO
          counters_p^ [40 + i] := counters_p^ [18+i];
        FOREND;
      IFEND;
    = cml$887_failure_data =
      RESET seq_p;
      NEXT hydra_status_p IN seq_p;

      counters_p^ [19] := status_bytes_p^ [9];
      counters_p^ [20] := status_bytes_p^ [10];
      counters_p^ [21] := status_bytes_p^ [11];
      counters_p^ [22] := status_bytes_p^ [16];
      counters_p^ [23] := status_bytes_p^ [13];
      counters_p^ [24] := hydra_status_p^.operational_status;
      counters_p^ [25] := hydra_status_p^.t_register;
      counters_p^ [26] := hydra_status_p^.control_register;
      counters_p^ [27] := hydra_status_p^.flag_mask_register;
      counters_p^ [28] := hydra_status_p^.idle_status;
      counters_p^ [29] := hydra_status_p^.bit_significant_response;
      counters_p^ [30] := (((((status_bytes_p^ [25] * 10000(16)) + status_bytes_p^ [26]) * 10000(16))
                          + status_bytes_p^ [27]) * 10000(16)) + status_bytes_p^ [28];
      counters_p^ [31] := ((status_bytes_p^ [29] * 10000(16)) + status_bytes_p^ [30]) * 100000000(16);
      counters_p^ [32] := (((((status_bytes_p^ [31] * 10000(16)) + status_bytes_p^ [32]) * 10000(16))
                          + status_bytes_p^ [33]) * 10000(16)) + status_bytes_p^ [34];
      counters_p^ [33] := (((((status_bytes_p^ [35] * 10000(16)) + status_bytes_p^ [36]) * 10000(16))
                          + status_bytes_p^ [37]) * 10000(16)) + status_bytes_p^ [38];
      counters_p^ [34] := ((status_bytes_p^ [39] * 10000(16)) + status_bytes_p^ [40]) * 100000000(16);
      counters_p^ [35] := (((((status_bytes_p^ [41] * 10000(16)) + status_bytes_p^ [42]) * 10000(16))
                          + status_bytes_p^ [43]) * 10000(16)) + status_bytes_p^ [44];
      FOR i := 1 TO 12 DO
        counters_p^ [35+i] := hydra_status_p^.error_register_image [i];
      FOREND;
      FOR i := 1 TO 12 DO
        counters_p^ [47+i] := hydra_status_p^.error_log [i];
      FOREND;
    = cml$9836_1_failure_data =
      counters_p^ [19] := disk_9836_status_p^.ipi_channel_status_register;
      counters_p^ [20] := disk_9836_status_p^.ipi_channel_error_register;
      IF disk_log_data_p^.channel.concurrent THEN
        counters_p^ [21] := disk_9836_status_p^.ipi_dma_error_register;
        counters_p^ [22] := disk_9836_status_p^.operational_status_register;
        counters_p^ [23] := disk_9836_status_p^.control_register;
      ELSE
        counters_p^ [21] := ioc$no_value;
        counters_p^ [22] := ioc$no_value;
        counters_p^ [23] := ioc$no_value;
      IFEND;
      IF disk_log_data_p^.controller_type = 8 THEN
        counters_p^ [24] := disk_9836_status_p^.microcode_revision * 10000(16) +
                            disk_9836_status_p^.lower_code_part_number;
      ELSE
        counters_p^ [24] := disk_9836_status_p^.microcode_revision;
      IFEND;
      cell_p := ^disk_9836_status_p^.response_packets;
      packets_p := cell_p;
      FOR i := 0 TO 25 DO
        counters_p^ [25 + i] := packets_p^ [i];
      FOREND;
    ELSE
    CASEND;

    iop$emit_statistic (statistic_code, counters_p, descriptor_data,
          disk_log_data_p, status);

  PROCEND iop$log_disk_data;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] IOP$LOG_USAGE_STATISTICS', EJECT ??

  PROCEDURE [XDCL] iop$log_usage_statistics;

    CONST
      emit_usage_interval = 30*60000000, { 30 minutes in micro-seconds}
      number_of_statistics = 3;

    VAR
      countu: array [1 .. 3] of integer,
      countc: array [1 .. 2] of integer,
      unit: integer,
      channel: cmt$physical_channel,
      usage_log_enabled: [STATIC] boolean := FALSE,
      statistics: array [1 .. number_of_statistics] of sft$statistic_code,
      status: ost$status,
      descriptor_data: ost$string,
      mainframe_data: ost$string,
      path_data: ost$string,
      unit_data: ost$string,
      size1: integer,
      size2: integer,
      channel_msg_p: ^string (*),
      unit_msg_p: ^string (*),
      end_msg_p: ^string(*),
      path_count: integer,
      path_index: integer,
      field_count: integer,
      i: integer,
      pp_number: 0 .. 0ff(16),
      pp: 1 .. ioc$pp_count,
      port_index: 0 .. 1,
      iou_number: dst$iou_number,
      active_pp: ^iot$disk_pp_usage,
      active_unit: ^iot$disk_unit_usage,
      equipment: 0 .. 7;

    IF not usage_log_enabled THEN
      statistics [1] := cml$disk_device_usage_data;
      statistics [2] := cml$disk_path_usage_data;
      statistics [3] := cml$end_disk_usage_interval;
      FOR i:= 1 TO number_of_statistics DO
        sfp$activate_system_statistic (statistics [i], $sft$binary_logset [pmc$engineering_log], status);
        IF not status.normal THEN
          RETURN;
        IFEND;
      FOREND;
      usage_log_enabled := TRUE;
      iov$time_to_log_usage_stats := #free_running_clock (0) +
          emit_usage_interval;
      RETURN;
    IFEND;
    iov$time_to_log_usage_stats := iov$time_to_log_usage_stats +
          emit_usage_interval;
    IF (iov$disk_unit_usage_p = NIL) OR (iov$disk_pp_usage_p = NIL) THEN
      RETURN;
    IFEND;
    FOR pp := LOWERBOUND (iov$disk_pp_usage_p^) TO UPPERBOUND (iov$disk_pp_usage_p^) DO
      active_pp := iov$disk_pp_usage_p^ [pp];
      IF active_pp <> NIL THEN
        iou_number := active_pp^.iou_number;
        channel := active_pp^.channel;
        FOR port_index := 0 TO 1 Do
          FOR equipment := 0 TO 7 DO
            IF active_pp^.path_usage [port_index] [equipment].path_used THEN
              unit := active_pp^.path_usage [port_index] [equipment].logical_unit;
              countc [1] := active_pp^.path_usage [port_index] [equipment].read_maus +
                  active_pp^.path_usage [port_index] [equipment].written_and_preset_maus;
              countc [2] := active_pp^.path_usage [port_index] [equipment].read_requests +
                  active_pp^.path_usage [port_index] [equipment].write_requests;
              cmp$return_descriptor_data (channel, iou_number, equipment, unit,
                  descriptor_data, pp_number);
              get_mainframe_string (descriptor_data, mainframe_data);
              get_path_string (descriptor_data, 4, path_data);
              size1  := mainframe_data.size;
              size2 := path_data.size;
              PUSH channel_msg_p:[size1 + size2 + 1];
              channel_msg_p^ (1, size1) := mainframe_data.value (1, size1);
              channel_msg_p^ (size1+1, 1) := '.';
              channel_msg_p^ (size1+2, size2) := path_data.value (1, size2);
              sfp$emit_statistic (cml$disk_path_usage_data, channel_msg_p^, ^countc, status);
            IFEND;
          FOREND;
        FOREND;
      IFEND;
    FOREND;
    FOR unit := 1 TO UPPERBOUND (iov$disk_unit_usage_p^) DO
      active_unit := iov$disk_unit_usage_p^ [unit];
      IF active_unit <> NIL THEN
        IF active_unit^.unit_used THEN
          countu [1] := active_unit^.read_mau_count + active_unit^.swap_in_mau_count;
          countu [2] := active_unit^.write_data_mau_count + active_unit^.write_data_and_preset_maus +
                        active_unit^.swap_out_data_mau_count + active_unit^.swap_out_data_and_preset_maus;
          countu [3] := active_unit^.read_requests + active_unit^.write_requests +
              active_unit^.swap_in_requests + active_unit^.swap_out_requests;
          iou_number := active_unit^.iou_number;
          channel := active_unit^.channel;
          equipment := active_unit^.equipment;
          IF active_unit^.unit_type = ioc$dt_mshydra THEN
            field_count := 3;
          ELSE
            field_count := 4;
          IFEND;
          cmp$return_descriptor_data (channel, iou_number, equipment, unit,
              descriptor_data, pp_number);
          get_mainframe_string (descriptor_data, mainframe_data);
          get_unit_string (descriptor_data, field_count, unit_data);
          size1  := mainframe_data.size;
          size2 := unit_data.size;
          PUSH unit_msg_p:[size1 + size2 + 1];
          unit_msg_p^ (1, size1) := mainframe_data.value (1, size1);
          unit_msg_p^ (size1+1, 1) := '.';
          unit_msg_p^ (size1+2, size2) := unit_data.value (1, size2);
          sfp$emit_statistic (cml$disk_device_usage_data, unit_msg_p^, ^countu, status);
        IFEND;
      IFEND;
    FOREND;
    size1 := mainframe_data.size;
    push end_msg_p: [size1 + 24];
    end_msg_p^(1,size1) := mainframe_data.value(1,size1);
    end_msg_p^(size1+1,24) := '*END DISK USAGE INTERVAL';
    sfp$emit_statistic (cml$end_disk_usage_interval, end_msg_p^, NIL, status);
  PROCEND iop$log_usage_statistics;
?? OLDTITLE ??
?? NEWTITLE := 'GET_MAINFRAME_STRING', EJECT ??

  PROCEDURE get_mainframe_string
    (    descriptor_data: ost$string;
     VAR mainframe_data: ost$string);

    VAR
      i: integer,
      period_found: boolean,
      size: integer;

    i := 0;
    period_found := FALSE;
    size := descriptor_data.size;
    IF size < 0 THEN
      size := 0;
    IFEND;
    IF size > 1 THEN
   /first_period/
      FOR i := 1 TO size DO
        IF descriptor_data.value (i, 1) = '.' THEN
          period_found := TRUE;
          EXIT /first_period/; {----->
        IFEND;
      FOREND /first_period/;
    IFEND;
    IF period_found AND (i > 1) THEN
      mainframe_data.value (1, i - 1) := descriptor_data.value (1, i - 1);
      mainframe_data.size := i - 1;
    ELSEIF size > 0 THEN
      mainframe_data.value (1, size) := descriptor_data.value (1, size);
      mainframe_data.size := size;
    ELSE
      mainframe_data.value (1, 17) := 'UNKNOWN_MAINFRAME';
      mainframe_data.size := 17;
    IFEND;
  PROCEND get_mainframe_string;
?? OLDTITLE ??
?? NEWTITLE := 'GET_UNIT_STRING', EJECT ??

  PROCEDURE get_unit_string
    (    descriptor_data: ost$string;
         field_count: integer;
     VAR unit_data: ost$string);

    VAR
      i: integer,
      j: integer,
      unit_found: boolean,
      size: integer,
      new_size: integer;

    i := 0;
    size := descriptor_data.size;
    IF size < 0 THEN
      size := 0;
    IFEND;
    unit_found := FALSE;
    IF size > field_count+2 THEN
      j := 0;

    /skip_path_fields/
      FOR i := 1 TO size DO
        IF descriptor_data.value(i, 1) = '.' THEN
          j := j + 1;
          IF j = field_count + 1 THEN
            unit_found := TRUE;
            EXIT /skip_path_fields/; {----->
          IFEND;
        IFEND;
      FOREND /skip_path_fields/;
    IFEND;
    new_size := size - i;
    IF unit_found AND (new_size > 0) AND (i > 0) THEN
      unit_data.value (1, new_size) := descriptor_data.value (i + 1, new_size);
      unit_data.size := new_size;
    ELSEIF size > 0 THEN
      unit_data.value (1, size) := descriptor_data.value (1, size);
      unit_data.size := size;
    ELSE
      unit_data.value (1, 19) := 'UNKNOWN_UNIT*UUUUUU';
      unit_data.size := 19;
    IFEND;
  PROCEND get_unit_string;
?? OLDTITLE ??
?? NEWTITLE := 'GET_PATH_STRING', EJECT ??

  PROCEDURE get_path_string
    (    descriptor_data: ost$string;
         field_count: integer;
     VAR path_data: ost$string);

    VAR
      length: integer,
      i: integer,
      j: integer,
      path_found: boolean,
      size: integer,
      start: integer;

    size := descriptor_data.size;
    start := 0;
    i := 0;
    IF size < 0 THEN
      size := 0;
    IFEND;
    path_found := FALSE;
    IF size > field_count+2 THEN
    /find_first_period/
      FOR i := 1 TO size DO
        IF descriptor_data.value (i, 1) = '.' THEN
          EXIT /find_first_period/; {----->
        IFEND;
      FOREND /find_first_period/;
      start := i + 1;
      IF start < size THEN
        j := 0;

      /find_path_fields/
        FOR i := start TO size DO
          IF (descriptor_data.value (i, 1) = '.') OR
             (descriptor_data.value (i, 1) = '*') THEN
            j := j + 1;
            IF j = field_count THEN
              path_found := TRUE;
              EXIT /find_path_fields/; {----->
            IFEND;
          IFEND;
        FOREND /find_path_fields/;
      IFEND;
    IFEND;
    length := i - start;
    IF path_found AND (length > 0) AND (start > 0) AND (i <= size) THEN
      path_data.value (1, length) := descriptor_data.value (start, length);
      path_data.size := length;
    ELSEIF size > 0 THEN
      path_data.value (1, size) := descriptor_data.value (1,size);
      path_data.size := size;
    ELSE
      path_data.value (1, 46) := 'UNKNOWN_IOU.UNKNOWN_PP.UNKNOWN_CH.UNKNOWN_CONT';
      path_data.size := 46;
    IFEND;
  PROCEND get_path_string;
?? OLDTITLE ??
?? NEWTITLE := 'IOP$EMIT_STATISTIC', EJECT ??

  PROCEDURE iop$emit_statistic
    (    statistic_code: sft$statistic_code;
         counters_p: ^array [1 .. * ] of sft$counter;
         descriptor_data: ost$string;
         disk_log_data_p: ^iot$disk_log_data;
     VAR status: ost$status);

    CONST
      symptom_length = 56;

    VAR
      msg: string (symptom_length),
      size: integer,
      m_length: integer,
      message_p: ^string ( * ),
      i: integer,
      j: integer,
      k: integer;


    status.normal := TRUE;

{Create symptom message.

    CASE statistic_code OF
    = cml$887_failure_data =
      CASE counters_p^ [8] OF
      = ioc$hydra_indeterminate =
        msg := 'INDETERMINATE';
      = ioc$h_exec_level_i_diagnostics =
        msg := 'EXECUTING LEVEL I DIAGNOSTICS';
      = ioc$h_lev_i_diagnostics_passed =
        msg := 'LEVEL I DIAGNOSTICS PASSED';
      = ioc$h_exec_level_ii_diagnostics =
        msg := 'EXECUTING LEVEL II DIAGNOSTICS';
      = ioc$h_lev_ii_diagnostics_passed =
        msg := 'LEVEL II DIAGNOSTICS PASSED';
      = ioc$h_spindle_powered_up =
        msg := 'SPINDLE POWERED UP';
      = ioc$h_sector_size_not_4096 =
        msg := 'SECTOR SIZE IS NOT 4096';
      = ioc$h_not_same_host_id =
        msg := 'HOST IDS ARE DIFFERENT';
      = ioc$h_function_timeout =
        msg := 'FUNCTION TIMEOUT';
      = ioc$h_channel_doesnt_go_empty =
        msg := 'CHANNEL DOESNT GO EMPTY';
      = ioc$h_incomplete_i4_transfer =
        msg := 'INCOMPLETE I4 TRANSFER';
      = ioc$h_pp_timed_out_a_command =
        msg := 'PP TIMED OUT A COMMAND';
      = ioc$h_cannot_select_controller =
        msg := 'CANNOT SELECT THE CONTROLLER';
      = ioc$h_incorrect_controller =
        msg := 'INCORRECT CONTROLLER WAS SELECTED';
      = ioc$h_channel_init_error =
        msg := 'CHANNEL INITIALIZATION ERROR';
      = ioc$h_controller_reserved =
        msg := 'CONTROLLER RESERVED';
      = ioc$h_software_failure =
        msg := 'SOFTWARE FAILURE';
      = ioc$h_drive_not_ready =
        msg := 'DRIVE NOT READY - MIC1';
      = ioc$h_media_failure =
        msg := 'MEDIA FAILURE - C    T   S  ';
        iop$ascii_decimal (^msg (18, * ), 3, counters_p^ [14]);
        iop$ascii_decimal (^msg (23, * ), 2, counters_p^ [15]);
        iop$ascii_decimal (^msg (27, * ), 2, counters_p^ [16]);
      = ioc$h_uncorrected_cm_error =
        msg := 'UNCORRECTED CM ERROR';
      = ioc$h_cm_reject =
        msg := 'CM REJECT';
      = ioc$h_invalid_response_code =
        msg := 'INVALID CM RESPONSE CODE';
      = ioc$h_cm_response_code_pe =
        msg := 'CM RESPONSE CODE PARITY ERROR';
      = ioc$h_cmi_read_data_pe =
        msg := 'CMI READ DATA PARITY ERROR';
      = ioc$h_input_buffer_overflow =
        msg := 'INPUT BUFFER OVERFLOW';
      = ioc$h_isi_input_error =
        msg := 'ISI INPUT ERROR';
      = ioc$h_isi_timeout =
        msg := 'ISI TIMEOUT';
      = ioc$h_jp_jy_data_parity_error =
        msg := 'JP/JY DATA PARITY ERROR';
      = ioc$h_bas_parity_error =
        msg := 'BAS PARITY ERROR';
      = ioc$h_output_isi_parity =
        msg := 'OUTPUT ISI PARITY ERROR';
      = ioc$h_jz_error =
        msg := 'JZ ERROR';
      = ioc$h_jp_jy_error =
        msg := 'JP/JY ERROR';
      = ioc$h_jn_jx_error =
        msg := 'JN/JX ERROR';
      = ioc$h_incomplete_dma_transfer =
        msg := 'INCOMPLETE DMA TRANSFER';
      = ioc$h_t_register_byte_count =
        msg := 'T REGISTER BYTE COUNT NONZERO';
      = ioc$h_invalid_controller_status =
        msg := 'INVALID CONTROLLER STATUS';
      = ioc$h_controller_interface_err =
        msg := 'CONTROLLER INTERFACE ERROR';
      = ioc$h_seek_error =
        msg := 'SEEK ERROR - SI21';
      = ioc$h_unable_to_read_header =
        msg := 'UNABLE TO READ HEADER - SI41';
      = ioc$h_header_miscompare =
        msg := 'HEADER MISCOMPARE - SI42';
      = ioc$h_unable_to_read_data =
        msg := 'UNABLE TO READ DATA - SI43';
      = ioc$h_transfer_count_error =
        msg := 'TRANSFER COUNT ERROR - SI68';
      = ioc$h_disk_not_formatted =
        msg := 'DISK NOT FORMATTED - SI82';
      = ioc$h_diagnostic_fault_detected =
        msg := 'DIAGNOSTIC FAULT DETECTED';
      = ioc$h_command_block_negated =
        msg := 'COMMAND BLOCK NEGATED - SIC1';
      = ioc$h_command_block_overwrite =
        msg := 'COMMAND BLOCK OVERWRITE - MI21';
      = ioc$h_illegal_command_byte =
        msg := 'ILLEGAL COMMAND BYTE - MI22';
      = ioc$h_illegal_sec_seek_address =
        msg := 'ILLEGAL SECONDARY SEEK ADDRESS - MI23';
      = ioc$h_illegal_pri_seek_address =
        msg := 'ILLEGAL PRIMARY SEEK ADDRESS - MI24';
      = ioc$h_illegal_command_parameter =
        msg := 'ILLEGAL COMMAND PARAMETER - MI25';
      = ioc$h_io_illegal_write_error =
        msg := 'I/O ILLEGAL WRITE ERROR - MI27';
      = ioc$h_end_of_disk_reached =
        msg := 'END OF DISK REACHED - MI28';
      = ioc$h_illegal_device_number =
        msg := 'ILLEGAL DEVICE NUMBER - MI29';
      = ioc$h_illegal_control_field =
        msg := 'ILLEGAL CONTROL FIELD - MI2A';
      = ioc$h_io_illegal_disconnect =
        msg := 'I/O ILLEGAL DISCONNECT - MI41';
      = ioc$h_isi_io_parity_error =
        msg := 'ISI I/O PARITY ERROR - MI63';
      = ioc$h_rw_sequencer_ram_parity =
        msg := 'R/W SEQUENCER RAM PARITY ERROR - MI64';
      = ioc$h_mpu_parity_error =
        msg := 'MPU PARITY ERROR - MI65';
      = ioc$h_ecc_fault =
        msg := 'ECC FAULT - MI66';
      = ioc$h_voltage_fault =
        msg := 'VOLTAGE FAULT - MI67';
      = ioc$h_write_transfer_count =
        msg := 'WRITE TRANSFER COUNT ERROR - MI68';
      = ioc$h_over_temperature_fault =
        msg := 'OVER TEMPERATURE FAULT - MI6B';
      = ioc$h_no_rw_sequencer_response =
        msg := 'NO READ/WRITE SEQUENCER RESPONSE - MI6C';
      = ioc$h_invalid_rw_sequencer_rsp =
        msg := 'INVALID READ/WRITE SEQUENCER RESPONSE - MI6D';
      = ioc$h_rw_sequencer_status_overw =
        msg := 'READ/WRITE SEQUENCER STATUS OVERWRITE - MI6E';
      = ioc$h_hydra_hardware_fault =
        msg := 'HYDRA HARDWARE FAULT - MI6F';
      = ioc$h_rw_sequencer_fault =
        msg := 'READ/WRITE SEQUENCER FAULT - MI70';
      = ioc$h_zerofill_timeout =
        msg := 'ZEROFILL TIMEOUT - MI71';
      = ioc$h_function_buffer_pe =
        msg := 'FUNCTION BUFFER PARITY ERROR - MI72';
      = ioc$h_partial_sector_error =
        msg := 'PARTIAL SECTOR ERROR - MI73';
      = ioc$h_disk_fault =
        msg := 'DISK FAULT - MI81';
      = ioc$h_no_sector_pulse =
        msg := 'NO SECTOR PULSE - MI90';
      = ioc$h_no_index_pulse =
        msg := 'NO INDEX PULSE - MI91';
      = ioc$h_cyl_head_sec_wrap_error =
        msg := 'CYLINDER/HEAD/SECTOR WRAP ERROR - MI92';
      = ioc$h_no_disk_response =
        msg := 'NO DISK RESPONSE - MIC3';
      = ioc$h_pause_timeout =
        msg := 'PAUSE TIME OUT';
      = ioc$h_tip_didnt_clear =
        msg := 'TRANSFER IN PROGRESS DID NOT CLEAR';
      = ioc$h_incomplete_cb_xfer =
        msg := 'INCOMPLETE COMMAND BLOCK TRANSFER';
      = ioc$h_incomplete_status_xfer =
        msg := 'INCOMPLETE STATUS TRANSFER';
      = ioc$h_sa_dropped_hydra_status =
        msg := 'SELECT ACTIVE DROPPED WHEN READING CONTROLLER STATUS';
      = ioc$h_incomplete_device_st_xfer =
        msg := 'INCOMPLETE DEVICE STATUS TRANSFER';
      = ioc$h_sa_dropped_device_status =
        msg := 'SELECT ACTIVE DROPPED WHEN READING DEVICE STATUS';
      = ioc$h_incomplete_eri_xfer =
        msg := 'INCOMPLETE ERROR REGISTER IMAGE TRANSFER';
      = ioc$h_sa_dropped_err_reg_image =
        msg := 'SELECT ACTIVE DROPPED WHEN READING ERROR REGISTER IMAGE';
      = ioc$h_incomplete_error_log_xfer =
        msg := 'INCOMPLETE ERROR LOG TRANSFER';
      = ioc$h_sa_dropped_error_log =
        msg := 'SELECT ACTIVE DROPPED WHEN READING ERROR LOG';
      = ioc$h_sa_dropped_data =
        msg := 'SELECT ACTIVE DROPPED WHEN TRANSFERRING DATA';
      = ioc$h_host_if_integrity_error =
        msg := 'HOST I/F INTEGRITY ERROR';
      = ioc$h_drive_if_integrity_error =
        msg := 'DRIVE I/F INTEGRITY ERROR';
      = ioc$h_seek_error_retried =
        msg := 'SEEK ERROR - DS22';
      = ioc$h_power_up_complete =
        msg := 'POWER-UP INITIALIZATION COMPLETE - DS81';
      = ioc$h_reset_complete =
        msg := 'HOST-GENERATED RESET COMPLETE - DS83';
      = ioc$h_priority_override =
        msg := 'PRIORITY OVERRIDE COMPLETE - DS84';
      = ioc$h_hydra_on_line =
        msg := 'HYDRA ON LINE - DS85';
      ELSE
        msg := ' ';
      CASEND;

    = cml$7165_2x_failure_data =
      CASE counters_p^ [8] OF
      = ioc$895_storage_director_retry =
        msg := 'STORAGE DIRECTOR RETRY';
      = ioc$895_undocumented_format_msg =
        msg := 'UNDOCUMENTED FORMAT x MESSAGE';
        iop$ascii_hex (^msg (21), 1, disk_log_data_p^.diagnostic_code);
      = ioc$895_invalid_command =
        msg := 'INVALID COMMAND';
      = ioc$895_invalid_command_to_7165 =
        msg := 'INVALID COMMAND ISSUED TO 7165';
      = ioc$895_ccw_count_too_small =
        msg := 'CCW COUNT TOO SMALL';
      = ioc$895_invalid_data_argument =
        msg := 'INVALID DATA ARGUMENT';
      = ioc$895_chaining_not_indicated =
        msg := 'CHAINING NOT INDICATED';
      = ioc$895_command_mismatch =
        msg := 'COMMAND MISMATCH';
      = ioc$895_defective_track_pointer =
        msg := 'DEFECTIVE TRACK POINTER';
      = ioc$895_device_status_1_not_exp =
        msg := 'DEVICE STATUS 1 NOT EXPECTED';
      = ioc$895_index_missing =
        msg := 'INDEX MISSING';
      = ioc$895_unresettable_interrupt =
        msg := 'UNRESETTABLE INTERRUPT';
      = ioc$895_device_does_not_respond =
        msg := 'DEVICE DOES NOT RESPOND';
      = ioc$895_incomplete_set_sector =
        msg := 'INCOMPLETE SET SECTOR';
      = ioc$895_head_address_miscompare =
        msg := 'HEAD ADDRESS MISCOMPARE';
      = ioc$895_invalid_device_status_1 =
        msg := 'INVALID DEVICE STATUS 1';
      = ioc$895_device_not_ready =
        msg := 'DEVICE NOT READY';
      = ioc$895_track_addr_miscompare =
        msg := 'TRACK ADDRESS MISCOMPARE';
      = ioc$895_drive_motor_off =
        msg := 'DRIVE MOTOR OFF';
      = ioc$895_seek_incomplete =
        msg := 'SEEK INCOMPLETE';
      = ioc$895_cyl_addr_miscompare =
        msg := 'CYLINDER_ADDRESS_MISCOMPARE';
      = ioc$895_unresettable_offset =
        msg := 'UNRESETTABLE OFFSET ACTIVE';
      = ioc$895_selective_reset =
        msg := 'SELECTIVE RESET WHILE SELECTED';
      = ioc$895_sync_latch_failure =
        msg := 'SYNC LATCH FAILURE';
      = ioc$895_micro_detected_check =
        msg := 'MICROCODE DETECTED CHECK';
      = ioc$895_clock_stopped_check_1 =
        msg := 'CLOCK STOPPED CHECK 1';
      = ioc$895_alternate_sd_failure =
        msg := 'ALTERNATE STORAGE DIRECTOR FAILURE';
      = ioc$895_error_uncorr_by_ecc =
        msg := 'ERROR UNCORRECTABLE BY ECC';
      = ioc$895_data_sync_unsuccessful =
        msg := 'DATA SYNCRONIZATION UNSUCCESSFUL';
      = ioc$895_error_corrected_by_ecc =
        msg := 'ERROR CORRECTABLE BY ECC';
      = ioc$895_rcc_initiated_by_cca =
        msg := 'RCC INITIATED BY CCA';
      = ioc$895_rcc1_not_successful =
        msg := 'RCC1 NOT SUCCESSFUL';
      = ioc$895_rcc1_rcc2_unsuccessful =
        msg := 'RCC1 AND RCC2 NOT SUCCESSFUL';
      = ioc$895_invalid_ddc_tag_seq =
        msg := 'INVALID DDC TAG SEQUENCE';
      = ioc$895_extra_rcc_required =
        msg := 'EXTRA RCC REQUIRED';
      = ioc$895_invalid_ddc_selection =
        msg := 'INVALID DDC SELECTION';
      = ioc$895_missing_end_op =
        msg := 'MISSING END OP';
      = ioc$895_invalid_tag =
        msg := 'INVALID TAG';
      = ioc$895_deselection =
        msg := 'DESELECTION';
      = ioc$895_no_controller_response =
        msg := 'NO CONTROLLER RESPONSE';
      = ioc$895_controller_unavailable =
        msg := 'CONTROLLER NOT AVAILABLE';
      = ioc$895_ecc_hardware_failure =
        msg := 'ECC HARDWARE FAILURE';
      = ioc$895_unexpected_end_op =
        msg := 'UNEXPECTED END OP';
      = ioc$895_end_op_active =
        msg := 'END OP ACTIVE';
      = ioc$895_command_reject =
        msg := 'COMMAND REJECT';
      = ioc$895_intervention_req =
        msg := 'INTERVENTION REQUIRED';
      = ioc$895_bus_out_parity =
        msg := 'BUS OUT PARITY';
      = ioc$895_equipment_check =
        msg := 'EQUIPMENT CHECK';
      = ioc$895_data_check =
        msg := 'DATA CHECK';
      = ioc$895_overrun =
        msg := 'OVERRUN';
      = ioc$895_permanent_device_error =
        msg := 'PERMANENT DEVICE ERROR';
      = ioc$895_end_of_cylinder =
        msg := 'END OF CYLINDER';
      = ioc$895_message_to_operator =
        msg := 'MESSAGE TO OPERATOR';
      = ioc$895_no_record_found =
        msg := 'NO RECORD FOUND';
      = ioc$895_file_protected =
        msg := 'FILE PROTECTED';
      = ioc$895_first_logged_error =
        msg := 'FIRST LOGGED ERROR';
      = ioc$895_environmental_data =
        msg := 'ENVIRONMENTAL DATA';
      = ioc$895_path_error =
        msg := 'PATH ERROR';
      = ioc$895_invalid_track_format =
        msg := 'INVALID TRACK FORMAT';
      = ioc$895_undocumented_sd_resp =
        msg := 'UNDOCUMENTED STORAGE DIRECTOR RESPONSE';
      = ioc$895_no_request_in_cmd =
        msg := 'REQUEST IN NOT RECEIVED DURING COMMAND RETRY';
      = ioc$895_illegal_write =
        msg := 'ILLEGAL WRITE';
      = ioc$895_fips_error =
        msg := 'CCC-STORAGE DIRECTOR INTERFACE ERROR';
      = ioc$895_full_empty_count =
        msg := 'FULL/EMPTY COUNT INCORRECT';
      = ioc$895_address_miscompare =
        msg := 'ADDRESS MISCOMPARE ON SELECT SEQUENCE';
      = ioc$895_no_request_in_poll =
        msg := 'NO REQUEST IN ON POLLING SEQUENCE';
      = ioc$895_select_in_received =
        msg := 'SELECT IN RECEIVED ON SELECT SEQUENCE';
      = ioc$895_bus_in_parity =
        msg := 'BUS IN PARITY ERROR';
      = ioc$895_read_path_parity =
        msg := 'READ PATH PARITY ERROR';
      = ioc$895_write_path_parity =
        msg := 'WRITE PATH PARITY ERROR';
      = ioc$895_incomplete_transfer =
        msg := 'INCOMPLETE DATA TRANSFER';
      = ioc$895_output_chan_parity =
        msg := 'CHANNEL PARITY DURING PP OUTPUT';
      = ioc$895_parity_err_on_input =
        msg := 'COUPLER MEMORY PARITY ERROR DURING PP INPUT';
      = ioc$895_deadman_timeout =
        msg := 'DEADMAN TIMEOUT STATUS';
      = ioc$895_memory_parity =
        msg := 'COUPLER MEMORY PARITY ERROR';
      = ioc$895_excess_data_xfered =
        msg := 'EXCESS DATA TRANSFERED';
      = ioc$895_data_packing_wrong =
        msg := 'DATA PACKING FOR CHANNEL DID NOT COME OUT EVEN';
      = ioc$895_normal_end_not_set =
        msg := 'NORMAL END NOT SET';
      = ioc$895_function_timeout =
        msg := 'FUNCTION TIMEOUT';
      = ioc$895_soft_sectoring =
        msg := 'SOFT SECTORING UNIT';
      = ioc$895_unit_soft_sectored =
        msg := 'UNIT SOFT SECTORED';
      = ioc$895_interface_error =
        msg := 'INTERFACE ERROR';
      = ioc$895_kz_board_error =
        msg := 'KZ BOARD ERROR';
      = ioc$895_kx_board_error =
        msg := 'KX BOARD ERROR';
      = ioc$895_channel_error =
        msg := 'CHANNEL ERROR';
      = ioc$895_media_failure =
        msg := 'MEDIA FAILURE';
      = ioc$895_incomplete_chan_xfer =
        msg := 'INCOMPLETE CHANNEL TRANSFER';
      = ioc$895_ccc_failure =
        msg := 'CCC FAILURE';
      = ioc$895_pp_ccc_data_integrity =
        msg := 'PP-CCC DATA INTEGRITY';
      = ioc$895_pp_drive_data_integrity =
        msg := 'PP-DRIVE DATA INTEGRITY';
      = ioc$895_seek_command_timeout =
        msg := 'SEEK COMMAND TIMEOUT';
      = ioc$895_indeterminate =
        msg := 'INDETERMINATE 895 ERROR';
      = ioc$895_uncorrected_cm_error =
        msg := 'UNCORRECTED CM ERROR';
      = ioc$895_cm_reject =
        msg := 'CM REJECT';
      = ioc$895_invalid_cm_response =
        msg := 'INVALID CM RESPONSE';
      = ioc$895_cm_response_pe =
        msg := 'CM RESPONSE CODE PARITY ERROR';
      = ioc$895_cmi_read_pe =
        msg := 'CMI READ DATA PARITY ERROR';
      = ioc$895_overflow_error =
        msg := 'OVERFLOW ERROR';
      = ioc$895_jy_board_error =
        msg := 'JY BOARD ERROR';
      = ioc$895_iou_failure_st_err =
        msg := 'IOU FAILURE - OPERATIONAL STATUS WRONG';
      = ioc$895_iou_failure_data_err =
        msg := 'IOU FAILURE - TEST MODE DATA MISCOMPARE';
      = ioc$895_tip_not_clear =
        msg := 'TRANSFER IN PROGRESS DID NOT CLEAR';
      = ioc$895_t_reg_not_empty =
        msg := 'T PRIME REGISTER NOT EMPTY';
      ELSE
        msg := ' ';
      CASEND;

    = cml$10395_11_failure_data, cml$fa7b4_d_failure_data =
      CASE counters_p^ [8] OF
      = ioc$pp_timed_out_a_command =
        msg := 'PP TIMED OUT A COMMAND';
      = ioc$isd_indeterminate =
        msg := 'INDETERMINATE';
      = ioc$adapter_failure =
        msg := 'ADAPTER FAILURE      ';
        IF disk_log_data_p^.diagnostic_code > 0 THEN
          iop$ascii_hex (^msg (19, * ), 3, disk_log_data_p^.diagnostic_code);
        IFEND;
      = ioc$isd_controller_failure =
        msg := 'CONTROL MODULE FAILURE     ';
        IF disk_log_data_p^.diagnostic_code > 0 THEN
          iop$ascii_hex (^msg (26, * ), 2, disk_log_data_p^.diagnostic_code);
        IFEND;
      = ioc$drive_failure =
        msg := 'DRIVE FAILURE     ';
        IF disk_log_data_p^.diagnostic_code > 0 THEN
          iop$ascii_hex (^msg (17, * ), 2, disk_log_data_p^.diagnostic_code);
        IFEND;
      = ioc$drive_not_present =
        msg := 'DRIVE NOT PRESENT';
      = ioc$drive_not_ready =
        msg := 'DRIVE NOT READY';
      = ioc$media_failure =
        msg := 'MEDIA FAILURE - C    T   S  ';
        iop$ascii_decimal (^msg (18, * ), 3, counters_p^ [14]);
        iop$ascii_decimal (^msg (23, * ), 2, counters_p^ [15]);
        iop$ascii_decimal (^msg (27, * ), 2, counters_p^ [16]);
      = ioc$function_failure_class_2 =
        msg := 'FUNCTION FAILURE CLASS 2';
      = ioc$function_failure_class_3 =
        msg := 'FUNCTION FAILURE CLASS 3';
      = ioc$input_ici_parity =
        msg := 'INPUT ICI PARITY';
      = ioc$output_ici_parity_class_1 =
        msg := 'OUTPUT ICI PARITY CLASS 1';
      = ioc$output_ici_parity_class_3 =
        msg := 'OUTPUT ICI PARITY CLASS 3';
      = ioc$adapter_ram_parity =
        msg := 'ADAPTER RAM PARITY';
      = ioc$adapter_buffer_parity =
        msg := 'ADAPTER BUFFER PARITY';
      = ioc$adapter_rom_parity =
        msg := 'ADAPTER ROM PARITY';
      = ioc$isi_parity =
        msg := 'ISI PARITY';
      = ioc$output_isi_parity_class_1 =
        msg := 'OUTPUT ISI PARITY CLASS 1';
      = ioc$output_isi_parity_class_3 =
        msg := 'OUTPUT ISI PARITY CLASS 3';
      = ioc$seek_error =
        msg := 'SEEK ERROR';
      = ioc$unable_to_read_header =
        msg := 'UNABLE TO READ HEADER';
      = ioc$unable_to_read_data =
        msg := 'UNABLE TO READ DATA';
      = ioc$incomplete_ici_transfer =
        msg := 'INCOMPLETE ICI TRANSFER';
      = ioc$isi_deadman_time_out =
        msg := 'ISI DEADMAN TIME-OUT';
      = ioc$loopback_compare_error =
        msg := 'LOOPBACK COMPARE ERROR';
      = ioc$loopback_select_active =
        msg := 'LOOPBACK SELECT ACTIVE';
      = ioc$loopback_attention =
        msg := 'LOOPBACK ATTENTION';
      = ioc$loopback_check_failure =
        msg := 'LOOPBACK CHECK FAILURE';
      = ioc$cm_scheduler_parity =
        msg := 'CM SCHEDULER PARITY';
      = ioc$cm_mpu_parity =
        msg := 'CM MPU PARITY';
      = ioc$cm_rw_hardware_fault =
        msg := 'CM R/W HARDWARE FAULT';
      = ioc$drive_voltage_fault =
        msg := 'DRIVE VOLTAGE FAULT';
      = ioc$over_temperature_fault =
        msg := 'OVER TEMPERATURE FAULT';
      = ioc$drive_write_protected =
        msg := 'DRIVE WRITE PROTECTED';
      = ioc$control_module_reserved =
        msg := 'CONTROL MODULE RESERVED';
      = ioc$isd_software_failure =
        msg := 'SOFTWARE FAILURE';
      = ioc$invalid_bootstrap_error =
        msg := 'INVALID BOOTSTRAP ERROR';
      = ioc$start_switch_not_depressed =
        msg := 'START SWITCH NOT DEPRESSED';
      = ioc$reloading_control_module =
        msg := 'RELOADING CONTROL MODULE';
      = ioc$control_module_reloaded =
        msg := 'CONTROL MODULE RELOADED';
      = ioc$executing_level_ii =
        msg := 'EXECUTING LEVEL II DIAGNOSTICS';
      = ioc$level_ii_passed =
        msg := 'LEVEL II DIAGNOSTICS PASSED';
      = ioc$adapter_controlware_error =
        msg := 'ADAPTER CONTROLWARE ERROR';
      = ioc$i_host_if_integrity_error =
        msg := 'PP - ADAPTER DATA INTEGRITY';
      = ioc$i_drive_if_integrity_error =
        msg := 'PP - DRIVE DATA INTEGRITY';
      ELSE
        msg := ' ';
      CASEND;

    = cml$7154_failure_data, cml$7155_1x_failure_data =
      CASE counters_p^ [8] OF
      = ioc$indeterminate =
        msg := 'INDETERMINATE';
      = ioc$input_channel_parity =
        msg := 'INPUT CHANNEL PARITY';
      = ioc$output_channel_parity =
        msg := 'OUTPUT CHANNEL PARITY';
      = ioc$controller_failure =
        msg := 'CONTROLLER FAILURE';
      = ioc$unit_failure =
        msg := 'UNIT FAILURE';
      = ioc$function_timeout =
        msg := 'FUNCTION TIMEOUT';
      = ioc$unit_is_reserved =
        msg := 'UNIT RESERVED';
      = ioc$controller_is_reserved =
        msg := 'CONTROLLER RESERVED';
      = ioc$seek_failure =
        msg := 'SEEK FAILURE';
      = ioc$checkword_error =
        msg := 'ERROR IN CHECKWORD - C    T   S  ';
        iop$ascii_decimal (^msg (23, * ), 3, counters_p^ [14]);
        iop$ascii_decimal (^msg (28, * ), 2, counters_p^ [15]);
        iop$ascii_decimal (^msg (32, * ), 2, counters_p^ [16]);
      = ioc$ram_parity =
        msg := 'CONTROLLER RAM PARITY';
      = ioc$incomplete_sector_transfer =
        msg := 'INCOMPLETE SECTOR TRANSFER';
      = ioc$unit_not_ready =
        msg := 'UNIT NOT READY';
      = ioc$unit_off_line_or_not_cabled =
        msg := 'UNIT OFF LINE OR NOT CABLED';
      = ioc$read_only_switch_on =
        msg := 'UNIT READ ONLY SWITCH ON';
      = ioc$ch_enable_off_or_not_cabled =
        msg := 'CHAN ENABLE SWITCH OFF OR UNIT NOT CABLED';
      = ioc$flawed_track =
        msg := 'FLAWED TRACK';
      = ioc$flawed_sector =
        msg := 'FLAWED SECTOR';
      = ioc$sector_address_miscompare =
        msg := 'SECTOR ADDRESS MISCOMPARE';
      = ioc$cylinder_address_miscompare =
        msg := 'CYLINDER ADDRESS MISCOMPARE';
      = ioc$lost_control_word =
        msg := 'LOST CONTROL WORD';
      = ioc$iou_output_parity =
        msg := 'IOU OUTPUT PARITY';
      = ioc$indeterminate_output_parity =
        msg := 'INDETERMINATE OUTPUT PARITY';
      = ioc$7155_software_failure =
        msg := 'SOFTWARE FAILURE';
      = ioc$address_error =
        msg := 'ADDRESS ERROR';
      = ioc$track_address_miscompare =
        msg := 'TRACK ADDRESS MISCOMPARE';
      = ioc$drive_not_selected =
        msg := 'DRIVE NOT SELECTED';
      = ioc$controller_drive_interface =
        msg := 'CONTROLLER - DRIVE INTERFACE ERROR';
      = ioc$host_if_integrity_error =
        msg := 'PP - CONTROLLER DATA INTEGRITY';
      = ioc$drive_if_integrity_error =
        msg := 'PP - DRIVE DATA INTEGRITY';
      = ioc$write_buffer_to_disk_error =
        msg := 'WRITE BUFFER TO DISK ERROR';
      = ioc$processor_instruction_timeo =
        msg := 'PROCESSOR INSTRUCTION TIMEOUT';
      = ioc$bm_register_parity_error =
        msg := 'BM REGISTER PARITY ERROR';
      = ioc$write_verify_error =
        msg := 'WRITE VERIFY ERROR';
      = ioc$7155_media_error =
        msg := 'MEDIA FAILURE';
      = ioc$conf_cylinder_is_flawed =
        msg := 'CONFIDENCE CYLINDER IS FLAWED';
      = ioc$loading_controlware =
        msg := 'LOADING CONTROLWARE';
      ELSE
        msg := ' ';
      CASEND;
    = cml$9836_1_failure_data =
      CASE counters_p^ [8] OF
      = ioc$9836_1_function_timeout =
        msg := 'FUNCTION TIMEOUT';
      = ioc$9836_1_ch_empty_when_act =
        msg := 'CHANNEL EMPTY WHEN ACTIVATED';
      = ioc$9836_1_period_c_error =
        msg := 'PERIOD COUNTER ERROR';
      = ioc$9836_1_upper_ici_parity =
        msg := 'PP-IPI PARITY ERROR';
      = ioc$9836_1_iou_error =
        msg := 'IOU ERROR';
      = ioc$9836_1_incomplete_i4_xfer =
        msg := 'INCOMPLETE I4 TRANSFER';
      = ioc$9836_1_channel_not_empty =
        msg := 'CHANNEL NOT EMPTY';
      = ioc$9836_1_central_memory_error =
        msg := 'CENTRAL MEMORY ERROR';
      = ioc$9836_1_invalid_cm_response =
        msg := 'INVALID CM RESPONSE CODE';
      = ioc$9836_1_cm_response_error =
        msg := 'CM RESPONSE CODE ERROR';
      = ioc$9836_1_cmi_read_parity =
        msg := 'CMI READ DATA PARITY ERROR';
      = ioc$9836_1_jy_data_error =
        msg := 'Y BOARD DATA ERROR';
      = ioc$9836_1_bas_parity_error =
        msg := 'BAS PARITY ERROR';
      = ioc$9836_1_lz_error =
        msg := 'Z BOARD ERROR';
      = ioc$9836_1_jy_error =
        msg := 'Y BOARD ERROR';
      = ioc$9836_1_lx_error =
        msg := 'X BOARD ERROR';
      = ioc$9836_1_dma_test_failure =
        msg := 'DMA TEST MODE FAILURE';
      = ioc$9836_1_count_overflow =
        msg := 'DMA COUNT OVERFLOW';
      = ioc$9836_1_cant_select_cont =
        msg := 'CAN NOT SELECT CONTROLLER';
      = ioc$9836_1_bit_sig_response_err =
        msg := 'BIT SIGNIFICANT RESPONSE ERROR';
      = ioc$9836_1_no_sync_in =
        msg := 'NO SYNC IN';
      = ioc$9836_1_sync_in_did_not_drop =
        msg := 'SYNC IN DID NOT DROP';
      = ioc$9836_1_ipi_sequence_error =
        msg := 'IPI SEQUENCE ERROR';
      = ioc$9836_1_upper_ipi_ch_parity =
        msg := 'IPI CHANNEL PARITY ERROR';
      = ioc$9836_1_slave_in_not_set =
        msg := 'SLAVE IN NOT SET';
      = ioc$9836_1_slave_in_not_drop =
        msg := 'SLAVE IN DID NOT DROP';
      = ioc$9836_1_incomplete_transfer =
        msg := 'INCOMPLETE TRANSFER';
      = ioc$9836_1_ch_stayed_active =
        msg := 'CHANNEL STAYED ACTIVE';
      = ioc$9836_1_buffer_counter_e =
        msg := 'BUFFER COUNTER_ERROR';
      = ioc$9836_1_sync_counter_error =
        msg := 'SYNC COUNTER ERROR';
      = ioc$9836_1_lost_data =
        msg := 'LOST DATA';
      = ioc$9836_1_bus_parity =
        msg := 'BUS PARITY';
      = ioc$9836_1_command_reject =
        msg := 'COMMAND REJECT';
      = ioc$9836_1_sync_out_not_sync_in =
        msg := 'SYNC OUTS NOT EQUAL SYNC INS';
      = ioc$9836_1_bus_b_ack_incorrect =
        msg := 'BUS B ACKNOWLEGE INCORRECT';
      = ioc$9836_1_no_cont_response =
        msg := 'NO CONTROLLER RESPONSE';
      = ioc$9836_1_ending_status_wrong =
        msg := 'ENDING STATUS WRONG';
      = ioc$9836_1_executing_cont_diag =
        msg := 'EXECUTING CONTROLLER DIAGNOSTICS - IOU   CH    C ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (41,1) := 'C';      { CIO Channel }
          msg (46,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (41,1) := 'C';      { CIO Channel }
          msg (46,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (41,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (39, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (44, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (49, *), 1, disk_log_data_p^.equipment);
      = ioc$9836_1_cont_diag_passed =
        msg := 'CONTROLLER DIAGNOSTICS PASSED - IOU   CH    C ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (38,1) := 'C';      { CIO Channel }
          msg (53,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (38,1) := 'C';      { CIO Channel }
          msg (53,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (38,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (41, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (46, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (51, *), 1, disk_log_data_p^.equipment);
      = ioc$9836_1_cont_diag_passed_2 =
        msg := 'CONTROLLER DIAGS PASSED - IOU   CH    C  LAST EC IS     ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (32,1) := 'C';      { CIO Channel }
          msg (37,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (32,1) := 'C';      { CIO Channel }
          msg (37,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (32,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (30, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (35, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (40, *), 1, disk_log_data_p^.equipment);
        iop$ascii_hex (^msg (53, *), 4, disk_log_data_p^.diagnostic_code);
      = ioc$9836_1_cont_alt_port_event =
        msg := 'CONTROLLER ALTERNATE PORT EVENT';
      = ioc$9836_1_dr_alt_port_event =
        msg := 'DRIVE ALTERNATE PORT EVENT';
      = ioc$9836_1_restoring_drive =
        msg := 'RESTORING DRIVE - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (24,1) := 'C';      { CIO Channel }
          msg (29,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (24,1) := 'C';      { CIO Channel }
          msg (29,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (24,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (22, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (27, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (32, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (35, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_restore_complete =
        msg := 'DRIVE RESTORATION COMPLETE - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (35,1) := 'C';      { CIO Channel }
          msg (40,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (35,1) := 'C';      { CIO Channel }
          msg (40,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (35,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (33, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (38, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (43, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (46, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_formatting_drive =
        msg := 'FORMATTING DRIVE - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (25,1) := 'C';      { CIO Channel }
          msg (30,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (25,1) := 'C';      { CIO Channel }
          msg (30,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (25,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (23, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (28, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (33, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (36, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_format_complete =
        msg := 'FORMAT COMPLETE - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (24,1) := 'C';      { CIO Channel }
          msg (29,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (24,1) := 'C';      { CIO Channel }
          msg (29,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (24,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (22, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (27, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (32, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (35, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_par_prot_disabled =
        CASE counters_p^ [5] OF
        = 12 =
          msg := '5833_1P PARITY PROTECTION DISABLED';
        = 14 =
          msg := '5833_3P PARITY PROTECTION DISABLED';
        = 17 =
          msg := '5838_1P PARITY PROTECTION DISABLED';
        = 19 =
          msg := '5838_3P PARITY PROTECTION DISABLED';
        = 22 =
          msg := '47444_1P PARITY PROTECTION DISABLED';
        = 24 =
          msg := '47444_3P PARITY PROTECTION DISABLED';
        = 27 =
          msg := '5837_1P PARITY PROTECTION DISABLED';
        = 29 =
          msg := '5837_3P PARITY PROTECTION DISABLED';
        ELSE
          msg := '??????? PARITY PROTECTION DISABLED';
        CASEND;
      = ioc$9836_1_drive_failure =
        msg := 'DRIVE FAILURE';
      = ioc$9836_1_media_failure =
        msg := 'MEDIA FAILURE';
      = ioc$9836_1_lrc_error =
        msg := 'LRC ERROR';
      = ioc$9836_1_cont_intervention =
        msg := 'CONTROLLER INTERVENTION REQUIRED';
      = ioc$9836_1_cont_machine_exc =
        msg := 'CONTROLLER MACHINE EXCEPTION';
      = ioc$9836_1_command_exception =
        msg := 'COMMAND EXCEPTION';
      = ioc$9836_1_controller_failure, ioc$9836_1_microcode_exec_error =
        msg := 'MICROCODE EXECUTION ERROR';
      = ioc$9836_1_unexpected_response =
        msg := 'UNEXPECTED RESPONSE';
      = ioc$9836_1_drive_rsvd_other_p =
        msg := 'DRIVE RESERVED TO OTHER CONTROLLER PORT';
      = ioc$9836_1_controller_over_temp =
        msg := 'CONTROLLER OVER TEMPERATURE';
      = ioc$9836_1_drive_not_operable =
        msg := 'DRIVE NOT OPERATIONAL';
      = ioc$9836_1_drive_not_ready =
        msg := 'DRIVE NOT READY';
      = ioc$9836_1_drive_intervention =
        msg := 'DRIVE INTERVENTION REQUIRED';
      = ioc$9836_1_uncorr_data_ck =
        msg := 'UNCORRECTABLE DATA CHECK';
      = ioc$9836_1_drive_fatal_error =
        msg := 'DRIVE FATAL ERROR';
      = ioc$9836_1_hw_write_protect =
        msg := 'HARDWARE WRITE PROTECTED';
      = ioc$9836_1_drive_rsvd_other_c =
        msg := 'DRIVE RESERVED TO OTHER CONTROLLER';
      = ioc$9836_1_drive_ecc_error=
        msg := 'DRIVE ECC ERROR';
      = ioc$9836_1_missing_sync =
        msg := 'MISSING SYNC OCTET ON DRIVE';
      = ioc$9836_1_sector_not_found =
        msg := 'SECTOR NOT FOUND';
      = ioc$9836_1_drive_exception =
        msg := 'DRIVE MACHINE EXCEPTION';
      = ioc$9836_1_no_unit_oper_resp =
        msg := 'NO UNIT OPERATIONAL RESPONSE';
      = ioc$9836_1_das_head_shift =
        msg := 'DAS DRIVE HEAD SHIFT DETECTED - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (38,1) := 'C';      { CIO Channel }
          msg (43,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (38,1) := 'C';      { CIO Channel }
          msg (43,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (38,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (36, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (41, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (46, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (49, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_ssd_battery_to_low =
        msg := 'SSD BATTERY TOO LOW FOR BACKUP - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (39,1) := 'C';      { CIO Channel }
          msg (44,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (39,1) := 'C';      { CIO Channel }
          msg (44,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (39,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (37, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (42, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (47, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (50, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_ssd_battery_test =
        msg := 'SSD BATTERY TEST FAILED - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (32,1) := 'C';      { CIO Channel }
          msg (37,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (32,1) := 'C';      { CIO Channel }
          msg (37,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (32,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (30, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (35, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (40, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (43, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_ssd_battery_old =
        msg := 'SSD BATTERY OLD - REPLACE - IOU   CH    C  U  ';
        CASE disk_log_data_p^.channel.port OF
        = cmc$port_a =
          msg (34,1) := 'C';      { CIO Channel }
          msg (39,1) := 'A';      { Change to CIO channel PORT A }
        = cmc$port_b =
          msg (34,1) := 'C';      { CIO Channel }
          msg (39,1) := 'B';      { Change to CIO channel PORT B }
        ELSE
          IF disk_log_data_p^.channel.concurrent THEN
            msg (34,1) := 'C'        { CIO Channel }
          IFEND;
        CASEND;
        iop$ascii_decimal (^msg (32, *), 1, disk_log_data_p^.iou_number);
        iop$ascii_decimal (^msg (37, *), 2, disk_log_data_p^.channel.number);
        iop$ascii_decimal (^msg (42, *), 1, disk_log_data_p^.equipment);
        iop$ascii_decimal (^msg (45, *), 2, disk_log_data_p^.physical_unit);
      = ioc$9836_1_error_retry =
        msg := 'ERROR RETRY';
      = ioc$9836_1_data_retry =
        msg := 'DATA RETRY';
      = ioc$9836_1_motion_retry =
        msg := 'MOTION RETRY';
      = ioc$9836_1_data_correction =
        msg := 'DATA CORRECTION';
      = ioc$9836_1_soft_error =
        msg := 'SOFT ERROR';
      = ioc$9836_1_parity_dr_corr =
        msg := 'PARITY DRIVE CORRECTION';
      = ioc$9836_1_pp_cont_data_integ =
        msg := 'PP-CONTROLLER DATA INTEGRITY';
      = ioc$9836_1_cm_drive_data_integ =
        msg := 'CM-DRIVE DATA INTEGRITY';
      = ioc$9836_1_software_failure =
        msg := 'SOFTWARE FAILURE';
      = ioc$9836_1_wrong_drive_config =
        msg := 'WRONG DRIVE TYPE';
      = ioc$9836_1_defect_mgmt_failure =
        msg := 'DEFECT MANAGEMENT TASK FAILED';
      = ioc$9836_1_wrong_drive_type =
        msg := '         CONFIGURED -          FOUND';
        j := disk_log_data_p^.actual_drive_type * 8;
        k := (counters_p^[5] - 9) * 8;
        FOR i := 1 TO 8 DO
          msg(i) := das_type(i+k);
          msg(i+22) := das_type(i+j);
        FOREND;
      = ioc$9836_1_drive_init_required =
        msg := 'DRIVE INITIALIZATON REQUIRED';
      = ioc$9836_1_no_parallel_support =
        msg := 'CONTROLLER DOES NOT SUPPORT PARALLEL';
      = ioc$9836_1_indeterminate =
        msg := 'INDETERMINATE';
      ELSE
      msg := ' ';
      CASEND;
    ELSE
      msg := ' ';
    CASEND;

{Combine descriptor data with symptom message.

    IF (descriptor_data.size <= (252 - 4 - symptom_length)) THEN
      size := descriptor_data.size;
    ELSE
      size := 252 - 4 - symptom_length;
    IFEND;
    m_length := size + 4 + symptom_length;
    PUSH message_p: [m_length];
    message_p^ (1, size) := descriptor_data.value;
    k := size + 1;
    CASE counters_p^ [7] MOD 8 OF
    = 0 =
      message_p^ (k, 4) := '*RF*';
    = 1 =
      message_p^ (k, 4) := '*UF*';
    = 2 =
      message_p^ (k, 4) := '*IF*';
    = 3 =
      message_p^ (k, 4) := '*IM*';
    ELSE
    CASEND;
    k := k + 4;
    message_p^ (k, * ) := msg;

    sfp$emit_statistic (statistic_code, message_p^, counters_p, status);

  PROCEND iop$emit_statistic;
?? OLDTITLE ??
?? NEWTITLE := 'IOP$ASCII_DECIMAL', EJECT ??

  PROCEDURE iop$ascii_decimal
    (    msg: ^string ( * );
         number_of_characters: 1 .. 4;
         word: 0 .. 0ffff(16));

    VAR
      i: integer,
      k: integer,
      divisor: [STATIC, READ, oss$job_paged_literal] array [1 .. 4] of integer := [1, 10, 100, 1000];


    k := 1;
    FOR i := number_of_characters DOWNTO 1 DO
      msg^ (i) := CHR (((word DIV divisor [k]) MOD 10) + ORD ('0'));
      k := k + 1;
    FOREND;

  PROCEND iop$ascii_decimal;
?? OLDTITLE ??
?? NEWTITLE := 'IOP$ASCII_HEX', EJECT ??

  PROCEDURE iop$ascii_hex
    (    msg: ^string ( * );
         number_of_characters: 1 .. 4;
         word: 0 .. 0ffff(16));

    VAR
      i: integer,
      k: integer,
      value: integer,
      divisor: [STATIC, READ, oss$job_paged_literal] array [1 .. 4] of integer := [1, 16, 256, 4096];


    k := 1;
    FOR i := number_of_characters DOWNTO 1 DO
      value := (word DIV divisor [k]) MOD 16;
      IF value > 9 THEN
        value := value + 7;
      IFEND;
      msg^ (i) := CHR (value + ORD ('0'));
      k := k + 1;
    FOREND;

  PROCEND iop$ascii_hex;
?? OLDTITLE ??

  PROCEDURE [XDCL, #GATE] osp$set_debug
    (    number: 0 .. 15;
         value: integer);

  PROCEDURE [XREF] osp$set_debug_sc
    (    number: 0 .. 15;
         value: integer);

    osp$set_debug_sc (number, value);

  PROCEND osp$set_debug;
MODEND iom$log_disk_data;
