
?? RIGHT := 110 ??
?? NEWTITLE := ' IOM$LOG_TAPE_DATA ' ??
MODULE iom$log_tape_data;
{
{  This module contains the processes which construct the Engineering log entry
{  for IPI or Cartridge tape errors logged from monitor.
{  If the error is a microcode load error for Cartridge tape, an attempt is made
{  to DOWN the controller.
{
?? TITLE := '    Type Declarations ', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc iot$ipi_tape_log_data
*copyc iot$tape_failure_statistic_data
*copyc ost$status
?? POP ??
?? TITLE := '    Xref Declarations ', EJECT ??
*copyc cmp$convert_channel_number
*copyc cmp$convert_iou_number
*copyc cmp$get_element_name
*copyc cmp$process_state_change
*copyc cmp$state_change_pending
*copyc iop$issue_ccc_cart_log_entry
*copyc iop$issue_ipi_log_entry
?? TITLE := '    [XDCL] iop$log_tape_data', EJECT ??
  PROCEDURE [XDCL] iop$log_tape_data (p_data: ^SEQ ( * );
    VAR status: ost$status);

    VAR
      data_p: ^SEQ ( * ),
      i: integer,
      p_major_status: ^array [1 .. ioc$ipi_max_status_size] of 0 .. 0ff(16),
      tape_log_data: iot$ipi_tape_log_data,
      seq_p: ^SEQ ( * ),
      status_length: 0 .. ioc$ipi_max_status_size,
      tape_failure_data: iot$ipi_tape_failure_data;

    status.normal := TRUE;

    seq_p := #SEQ (tape_log_data);
    RESET seq_p;
    NEXT data_p: [[REP #SIZE (p_data^) of cell]] IN seq_p;
    RESET data_p;
    data_p^ := p_data^;

    IF tape_log_data.unit_type = ioc$ccc_cart THEN
      process_ccc_cart_log (tape_log_data, status);
      RETURN;
    IFEND;

    tape_failure_data.package.pp_number.initial_error_status_register := 0;
    tape_failure_data.package.pp_number.final_error_status_register := 0;
    tape_failure_data.package.pp_number.fill1 := 0;
    tape_failure_data.package.pp_number.iou := tape_log_data.iou_number;
    tape_failure_data.package.pp_number.fill2 := 0;
    tape_failure_data.package.pp_number.i4_port_a := 0;
    tape_failure_data.package.pp_number.i4_port_b := 0;

    IF tape_log_data.channel.concurrent THEN
      tape_failure_data.package.pp_number.concurrent := 1;
    ELSE
      tape_failure_data.package.pp_number.concurrent := 0;
    IFEND;

    tape_failure_data.package.channel_number.initial_error_status_register := 0;
    tape_failure_data.package.channel_number.final_error_status_register := 0;
    tape_failure_data.package.channel_number.fill1 := 0;
    tape_failure_data.package.channel_number.iou := tape_log_data.iou_number;
    tape_failure_data.package.channel_number.fill2 := 0;

    IF tape_log_data.channel.concurrent THEN
      tape_failure_data.package.channel_number.concurrent := 1;
      IF tape_log_data.channel.port = cmc$port_a THEN
        tape_failure_data.package.channel_number.i4_port_a := 1;
        tape_failure_data.package.channel_number.i4_port_b := 0;
      ELSE
        tape_failure_data.package.channel_number.i4_port_a := 0;
        tape_failure_data.package.channel_number.i4_port_b := 1;
      IFEND;
    ELSE
      tape_failure_data.package.channel_number.i4_port_a := 0;
      tape_failure_data.package.channel_number.i4_port_b := 0;
      tape_failure_data.package.channel_number.concurrent := 0;
    IFEND;

    tape_failure_data.package.channel_number.resource_number := tape_log_data.channel.number;
    tape_failure_data.package.equipment_number := tape_log_data.controller_number;
    tape_failure_data.package.physical_unit_number := tape_log_data.unit_number;
    tape_failure_data.package.unit_type := 9;
    tape_failure_data.package.operation_code := 0;

    IF (tape_log_data.ipi_status.error_id = ioc$executing_controller_diag) OR
          (tape_log_data.ipi_status.error_id = ioc$controller_diag_passed)  THEN
      tape_failure_data.package.failure_severity := 3;  { informative
    ELSEIF tape_log_data.logical_unit <> 0 THEN  { set intermediate
      tape_failure_data.package.failure_severity := 2;
    ELSEIF (tape_log_data.ipi_status.error_id = ioc$ipi_controller_failure) OR
          (tape_log_data.ipi_status.error_id = ioc$drive_failure) OR
          (tape_log_data.ipi_status.error_id = ioc$internal_controller_error) OR
          (tape_log_data.ipi_status.error_id = ioc$controller_intervention_req) OR
          (tape_log_data.ipi_status.error_id = ioc$command_exception) OR
          (tape_log_data.ipi_status.error_id = ioc$microcode_execution_error) OR
          (tape_log_data.ipi_status.error_id = ioc$master_slave_data_integrity) OR
          (tape_log_data.ipi_status.error_id = ioc$slave_fac_data_integrity) THEN
      tape_failure_data.package.failure_severity := 1;       { set to unrecovered
    ELSE  { set to informative
      tape_failure_data.package.failure_severity := 3;
    IFEND;

    tape_failure_data.package.failure_symptom_code := tape_log_data.ipi_status.error_id;
    tape_failure_data.package.blocks_written := 0;
    tape_failure_data.package.blocks_read := 0;
    tape_failure_data.package.single_double_track_corrections := 0;
    tape_failure_data.package.unused_fill1 := 0;
    tape_failure_data.package.block_count := 0;
    tape_failure_data.package.tapemark_count := 0;
    tape_failure_data.package.tape_format_parameters := 0;
    tape_failure_data.package.density := 0;
    tape_failure_data.package.unused_fill2 := 0;
    tape_failure_data.package.recovery_retry_count := 0;
    tape_failure_data.package.last_requested_function := tape_log_data.ipi_status.
          function_with_timeout;
    tape_failure_data.package.ipi_status_register := tape_log_data.ipi_status.ipi_status_register;
    tape_failure_data.package.ipi_error_register := tape_log_data.ipi_status.ipi_error_register;
    tape_failure_data.package.i4_error_register := tape_log_data.ipi_status.i4_dma_error_register;
    tape_failure_data.package.i4_operation_register := tape_log_data.ipi_status.
          i4_dma_operational_status_reg;
    tape_failure_data.package.i4_control_register := tape_log_data.ipi_status.
          i4_dma_control_register;
    tape_failure_data.package.interface_error_code := tape_log_data.interface_error_code;
    tape_failure_data.package.unused_fill3 := 0;
    tape_failure_data.package.unused_fill4 := 0;
    tape_failure_data.package.unused_fill5 := 0;
    tape_failure_data.package.unused_fill6 := 0;
    tape_failure_data.package.unused_fill7 := 0;
    p_major_status := #LOC (tape_log_data.ipi_status.major_status_header);

    IF (tape_log_data.response_length <= ioc$min_ipi_total_resp_size) THEN
      FOR i := 1 to 8 DO
        tape_failure_data.package.ipi_status [i] := 0;
      FOREND;
    ELSE
      status_length := tape_log_data.ipi_status.major_status_header.length + 2;
      FOR i := 1 TO status_length DO
        tape_failure_data.package.ipi_status [i] := p_major_status^ [i];
      FOREND;
    IFEND;

    iop$issue_ipi_log_entry (^tape_failure_data, tape_log_data.logical_unit,
          status);

  PROCEND iop$log_tape_data;
?? OLDTITLE ??
?? NEWTITLE := '    process_ccc_cart_log', EJECT ??
  PROCEDURE process_ccc_cart_log (
        tape_log_data: iot$ipi_tape_log_data;
    VAR status: ost$status);

    VAR
      channel_name: cmt$element_name,
      channel_ordinal: cmt$channel_ordinal,
      element_descriptor: cmt$element_descriptor,
      i: integer,
      ignore_status: ost$status,
      iou_name: cmt$element_name,
      p_status: ^array [1 .. 8] of 0 .. 0ff(16),
      physical_id: cmt$physical_identification ,
      tape_failure_data: iot$ccc_cart_tape_failure_data,
      valid_channel: boolean;

    status.normal := TRUE;

    tape_failure_data.package.pp_number.initial_error_status_register := 0;
    tape_failure_data.package.pp_number.final_error_status_register := 0;
    tape_failure_data.package.pp_number.fill1 := 0;
    tape_failure_data.package.pp_number.iou := tape_log_data.iou_number;
    tape_failure_data.package.pp_number.fill2 := 0;
    tape_failure_data.package.pp_number.i4_port_a := 0;
    tape_failure_data.package.pp_number.i4_port_b := 0;

    IF tape_log_data.channel.concurrent THEN
      tape_failure_data.package.pp_number.concurrent := 1;
    ELSE
      tape_failure_data.package.pp_number.concurrent := 0;
    IFEND;

    tape_failure_data.package.channel_number.initial_error_status_register := 0;
    tape_failure_data.package.channel_number.final_error_status_register := 0;
    tape_failure_data.package.channel_number.fill1 := 0;
    tape_failure_data.package.channel_number.iou := tape_log_data.iou_number;
    tape_failure_data.package.channel_number.fill2 := 0;

    IF tape_log_data.channel.concurrent THEN
      tape_failure_data.package.channel_number.concurrent := 1;
    ELSE
      tape_failure_data.package.channel_number.concurrent := 0;
    IFEND;
    tape_failure_data.package.channel_number.i4_port_a := 0;
    tape_failure_data.package.channel_number.i4_port_b := 0;

    tape_failure_data.package.channel_number.resource_number := tape_log_data.channel.number;
    tape_failure_data.package.equipment_number := tape_log_data.controller_number;
    tape_failure_data.package.physical_unit_number := tape_log_data.unit_number;
    tape_failure_data.package.unit_type := 10;
    tape_failure_data.package.operation_code := 0;
    tape_failure_data.package.failure_severity := 1;       { set to unrecovered
    tape_failure_data.package.failure_symptom_code := tape_log_data.ccc_cart_status.error_id;
    tape_failure_data.package.blocks_written := 0;
    tape_failure_data.package.blocks_read := 0;
    tape_failure_data.package.on_the_fly_read_corrections := 0;
    tape_failure_data.package.on_the_fly_write_corrections := 0;
    tape_failure_data.package.block_count := 0;
    tape_failure_data.package.tapemark_count := 0;
    tape_failure_data.package.read_recovery_count := 0;
    tape_failure_data.package.write_recovery_count := 0;
    tape_failure_data.package.last_function.last_not_status := tape_log_data.ccc_cart_status.
          last_non_status_function;
    tape_failure_data.package.last_function.last := tape_log_data.ccc_cart_status.last_function;
    tape_failure_data.package.last_function.fill := 0;
    tape_failure_data.package.recovery_retry_count := 0;
    tape_failure_data.package.first_error_status_register := tape_log_data.ccc_cart_status.
          channel_error_register;
    tape_failure_data.package.final_error_status_register := tape_log_data.ccc_cart_status.
          channel_error_register;
    p_status := #LOC(tape_log_data.ccc_cart_status);
    FOR i := 1 TO 8 DO
      tape_failure_data.package.initial_status [i] := p_status^ [i];
      tape_failure_data.package.final_status [i] := p_status^ [i];
    FOREND;
    FOR i := 1 TO 40 DO
      tape_failure_data.package.initial_sense_bytes [i] := 0;
      tape_failure_data.package.final_sense_bytes [i] := 0;
    FOREND;
    tape_failure_data.package.density := 0;
    tape_failure_data.package.buffer_underruns := 0;
    tape_failure_data.package.res2 := 0;
    tape_failure_data.package.last_failure_info.fill := 0;
    tape_failure_data.package.last_failure_info.error_id := 0;
    tape_failure_data.package.last_failure_info.last_non_status_function := 0;
    tape_failure_data.package.last_failure_info.last_function := 0;

    iop$issue_ccc_cart_log_entry (^tape_failure_data, tape_log_data.logical_unit,
          status);

    IF tape_log_data.ccc_cart_status.error_id = ioc$ccc_cart_microcode_load THEN

{ Attempt to DOWN the controller.

      cmp$convert_channel_number (tape_log_data.channel.number, tape_log_data.channel.concurrent,
            tape_log_data.channel.port, channel_ordinal, channel_name, valid_channel);

      cmp$convert_iou_number (tape_log_data.iou_number, iou_name, status);

      IF status.normal AND valid_channel THEN
        physical_id.product_identification.product_number := '     ';
        physical_id.product_identification.underscore := ' ';
        physical_id.product_identification.model_number := '   ';
        physical_id.serial_number := '   ';
        physical_id.hardware_address.physical_address_specifier :=
              $cmt$physical_address_specifier [cmc$iou, cmc$channel, cmc$channel_address];
        physical_id.hardware_address.iou := iou_name;
        physical_id.hardware_address.channel.ordinal := channel_ordinal;
        physical_id.hardware_address.channel.iou := iou_name;
        physical_id.hardware_address.channel_address :=
              tape_log_data.controller_number;
        cmp$get_element_name (physical_id, element_descriptor, ignore_status);
        IF ignore_status.normal AND NOT (cmp$state_change_pending (element_descriptor)) THEN
          cmp$process_state_change ({tape=} TRUE, {system_call=} TRUE, element_descriptor,
              {system_critical} FALSE, cmc$on, cmc$down, ignore_status);
        IFEND;
      IFEND;
    IFEND;

  PROCEND process_ccc_cart_log;

MODEND iom$log_tape_data;

