
  PROCEDURE {INLINE} bai$process_request_status
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
         request_status: ost$status;
         tape_failure_modes: amt$tape_failure_modes;
     VAR error_action: bat$error_actions;
     VAR status: ost$status);

?? PUSH (LISTEXT := ON) ??
?? RIGHT := 110 ??

{ The purpose of this request is to take a request status and failure modes
{ returned by the tape_block_manager and do the following:
{
{   1) Store the tape_failure_modes in the tape_descriptor,
{   2) Change any internal errors into either appropriate external errors, or
{   3) Take an appropriate action to allow processing to continue.

*copy bah$inline_proc_documentation

    status.normal := TRUE;
    error_action := bac$continue;
    tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
    tape_descriptor^.failure_isolation.failed_at_current_position := TRUE;
    IF request_status.normal THEN
      RETURN; {----->
    IFEND;

{ Process abnormal request_status.

    process_abnormal_request_status (file_identifier, operation, request_status, tape_failure_modes,
          error_action, status);

  PROCEND bai$process_request_status;

  PROCEDURE process_abnormal_request_status
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
         request_status: ost$status;
         tape_failure_modes: amt$tape_failure_modes;
     VAR error_action: bat$error_actions;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      maxbl_string: ost$string,
      volume_descriptor: rmt$volume_descriptor,
      volume_position: amt$volume_position;

    IF request_status.condition =

{******} bae$block_larger_than_maxbl {******} THEN

      CASE operation OF
*copy bac$write_requests
        amp$set_file_instance_abnormal (file_identifier, ame$record_exceeds_mbl, operation, '', status);
      ELSE
        clp$convert_integer_to_string (gfi^.max_data_size, 10, FALSE, maxbl_string, status);
        amp$set_file_instance_abnormal (file_identifier, ame$input_block_exceeds_maxbl, operation,
              maxbl_string.value, status);
      CASEND;
    ELSEIF request_status.condition =

{******} bae$block_truncated {******} THEN

      ;
    ELSEIF request_status.condition =

{******} bae$cannot_lock_tape_pages {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$cannot_lock_tape_pages, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$improper_access_attempt {******} THEN

      CASE operation OF
*copy bac$write_requests
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, operation, 'WRITE',
              status);
      = amc$put_label_req =
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, operation, 'WRITE',
              status);
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, operation, 'READ',
              status);
      CASEND;
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$improper_file_id {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$improper_file_id, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$improper_input_attempt {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$improper_input_attempt, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$input_after_output {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$input_after_output, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$maxbl_exceeds_ws_limit {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$maxbl_exceeds_ws_limit, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$multiple_open_of_tape {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$multiple_open_of_tape, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$no_tape_write_ring {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$no_write_ring, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$ring_validation_error {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$skip_encountered_bov {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$skip_encountered_bov, operation, '', status);
    ELSEIF request_status.condition =

{******} bae$tape_block_mgr_malfunction {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$tape_block_mgr_malfunction, operation,
            request_status.text.value (2, request_status.text.size - 1), status);
      error_action := bac$exit_procedure;
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
    ELSEIF request_status.condition =

{******} bae$tape_driver_not_capable {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$tape_driver_not_capable, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$too_many_reserved_buffers {******} THEN

      status := request_status;
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$uncertain_tape_position {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$uncertain_tape_position, operation, '', status);
      error_action := bac$exit_procedure;
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
    ELSEIF request_status.condition =

{******} bae$unimplemented_request {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$unimplemented_request, operation,
            ' for tape files', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$unreserved_buffer_used {******} THEN

      status := request_status;
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$vol_end_operation_completed {******} THEN

      IF operation <> amc$close_volume_req THEN
        IF (bai$label_type () = amc$unlabelled) OR (bai$label_type () = amc$labelled) THEN
          ;
        ELSE { label_type = amc$non_standard_labelled       }
          amp$set_file_instance_abnormal (file_identifier, ame$end_of_tape_op_completed, operation, '',
                status);
        IFEND;
      ELSE
{ Ignore error if close_volume.
{ The volume advance will be initiated from the close_volume_req procedure.
        ;
      IFEND;

    ELSEIF request_status.condition =

{******} bae$vol_end_operation_inhibited {******} THEN

{ This error occurs only when writing.
{ For unlabelled and labelled tapes, dme$volume_list_exhausted will never
{ occur here since a scratch volume will always be requested.  Therefore,
{ there is no need for logic to call the process_volume_list_exhausted
{ procedure.
{ IF end of tape occurs during a user initiated close volume request, it
{ is a result of the flush that was issued prior to the volume advance.
{ The error will be ignored and the volume advance will be initiated from
{ the close_volume_req procedure.

      IF operation <> amc$close_volume_req THEN
        IF bai$label_type () = amc$unlabelled THEN
          bai$advance_volume (file_identifier, volume_position, status);
          tape_descriptor^.volume_position := volume_position;
          IF NOT status.normal THEN
            error_action := bac$exit_procedure;
          ELSE
            error_action := bac$retry_last_request;
          IFEND;
        ELSEIF bai$label_type () = amc$labelled THEN
          sl_close_label_volume (file_identifier, status);
          IF NOT status.normal THEN
            error_action := bac$exit_procedure;
          ELSE
            error_action := bac$retry_last_request;
          IFEND;
        ELSE { label_type = amc$non_standard_labelled       }
          amp$set_file_instance_abnormal (file_identifier, ame$end_of_tape_op_inhibited, operation, '',
                status);
          error_action := bac$exit_procedure;
        IFEND;
      ELSE
{ Ignore error if close_volume.  Buffered data will be retained and written on the next reel.
{ The volume advance will be initiated from the close_volume_req procedure.
        ;
      IFEND;
    ELSEIF request_status.condition =

{******} bae$write_error_previous_block {******} THEN

      tape_descriptor^.failure_isolation.failed_at_current_position := FALSE;
      amp$set_file_instance_abnormal (file_identifier, ame$unrecovered_write_error, operation, '', status);
      error_action := bac$exit_procedure;
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
    ELSEIF request_status.condition =

{******} bae$read_error_this_block {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$unrecovered_read_error, operation, '', status);
      error_action := bac$exit_procedure;
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
    ELSEIF request_status.condition =

{******} bae$density_mismatch {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$tape_density_mismatch, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$cartridge_tape_erase_limit {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$cartridge_tape_erase_limit, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$motion_past_phys_eot {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$motion_past_phys_eot, operation, '', status);
      error_action := bac$exit_procedure;
    ELSEIF request_status.condition =

{******} bae$write_error_this_block {******} THEN

      amp$set_file_instance_abnormal (file_identifier, ame$unrecovered_write_error, operation, '', status);
      error_action := bac$exit_procedure;
      bai$append_tape_error (file_identifier, tape_failure_modes, status);
    ELSEIF request_status.condition =

{******} dme$volume_list_exhausted {******} THEN

      process_volume_list_exhausted (file_identifier, operation, error_action, status);
    ELSE
      status := request_status;
      error_action := bac$exit_procedure;
    IFEND;

  PROCEND process_abnormal_request_status;

{
{ The purpose of this request is to take appropriate actions when an operation
{ is performed that can not complete on the current volume set.
{
{ When reading an unlabelled tape, end_of_volume is defined when two
{ consecutive tapemarks are encountered.  When this occurs, the tape drive is
{ logically positioned between the two tapemarks. By convention, the tape drive
{ should be repositioned in front of the tapemarks.  The appropriate action is
{ then to skip one tapemark backwards.
{
*copy bah$inline_proc_documentation

  PROCEDURE process_volume_list_exhausted
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
     VAR error_action: bat$error_actions;
     VAR status: ost$status);

    VAR
      tape_failure_modes: amt$tape_failure_modes,
      request_status: ost$status;

    IF bai$label_type () = amc$labelled THEN
      tape_descriptor^.labeled_volume_position := bac$lvp_end_of_volume_list;
      file_instance^.previous_get_at_eoi := TRUE;
      gfi^.positioning_info.record_info.file_position := amc$eoi;
      amp$set_file_instance_abnormal (file_identifier, ame$tape_end_of_volume_list, operation, '', status);

    ELSE { label_type <> amc$labelled  }

      CASE operation OF
      = amc$open_req =
        bap$tape_bm_skip_tapemark (file_identifier, amc$backward, tape_failure_modes, request_status);
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
*copy bac$read_requests
        bap$tape_bm_skip_tapemark (file_identifier, amc$backward, tape_failure_modes, request_status);
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$tape_end_of_volume_list, operation, '', status);
      CASEND;

    IFEND;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: End of Volume List - Setting AT_EOI to TRUE');
    tape_descriptor^.at_eoi := TRUE;

  PROCEND process_volume_list_exhausted;

  TYPE
    bat$error_actions = (bac$continue, bac$exit_procedure, bac$retry_last_request);

*copyc ame$get_program_actions
*copyc ame$get_validation_errors
*copyc ame$improper_file_id
*copyc ame$open_validation_errors
*copyc ame$put_program_actions
*copyc ame$put_validation_errors
*copyc ame$ring_validation_errors
*copyc ame$skip_program_actions
*copyc ame$skip_validation_errors
*copyc ame$tape_program_actions
*copyc ame$unimplemented_request
*copyc ame$wtmk_validation_errors
*copyc bae$tape_bm_error_codes
*copyc dme$tape_errors
*copyc bat$task_file_table
*copyc ost$status
*copyc amp$set_file_instance_abnormal
*copyc clp$convert_integer_to_string
*copyc osp$append_status_integer
*copyc bai$advance_volume
*copyc bai$gfi
?? POP ??
