?? RIGHT := 110 ??
MODULE dmm$create_tape_file;
?? NEWTITLE := 'Global variables declared by this module', EJECT ??

  CONST
    default_terminate_reason = 'the requested tape volume is not available',
    one_second = 1000 {milliseconds} ,
    four_seconds = 4 * one_second;

  VAR
    dmv$tape_job_lun_table_p: [XDCL, oss$job_pageable] ^dmt$tape_job_lun_table := NIL;

?? OLDTITLE ??
?? NEWTITLE := 'Global Variables Referenced by This Module', EJECT ??
*copyc dmv$initialize_tape_volume
*copyc fmv$default_detachment_options
*copyc rmv$job_tape_table_lock
*copyc rmv$job_tape_table_p
*copyc rmv$requested_volume_attributes
*copyc iov$number_of_tape_units
*copyc iov$tusl_p
*copyc oss$job_pageable
*copyc oss$job_paged_literal
*copyc osv$job_pageable_heap
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
{
{ Type definitions.
{
*copyc amt$label_type
*copyc avc$system_defined_limit_names
*copyc clt$value
*copyc clt$when_conditions
*copyc cyd$run_time_error_condition
*copyc ame$tape_program_actions
*copyc dme$tape_errors
*copyc dmt$file_type
*copyc dmt$job_tape_table
*copyc dmt$message_element
*copyc dmt$tape_job_lun_table
*copyc fmt$detachment_options
*copyc fmt$removable_media_req_info
*copyc gft$system_file_identifier
*copyc ife$error_codes
*copyc ioe$tape_io_conditions
*copyc iot$io_id
*copyc iot$tape_io_status
*copyc jmt$system_supplied_name
*copyc jmt$user_supplied_name
*copyc ofe$error_codes
*copyc ost$name
*copyc ost$wait
*copyc pft$usage_selections
*copyc pmd$system_log_interface
*copyc pmt$established_handler
*copyc rmc$robotic_write_disabled
*copyc rmd$tape_declarations
*copyc rme$condition_codes
?? POP ??
*copyc avp$security_option_active
*copyc clp$trimmed_string_size
*copyc cmp$get_element_name_via_lun
*copyc rmp$set_explicit_reserve
*copyc dmp$validate_tape_density
*copyc ifp$invoke_pause_utility
*copyc iop$access_tusl_entry
*copyc iop$delete_rvl_entry
*copyc iop$initialize_tape_ud
*copyc iop$rewind_tape
*copyc iop$tape_initialize_unit
*copyc iop$tape_request_status
*copyc iop$unload_tape
*copyc jmp$system_job
*copyc ofp$clear_operator_message
*copyc ofp$format_operator_menu
*copyc osp$append_status_parameter
*copyc osp$begin_subsystem_activity
*copyc osp$clear_job_signature_lock
*copyc osp$clear_wait_message
*copyc osp$copy_local_status_to_status
*copyc osp$disestablish_cond_handler
*copyc osp$end_subsystem_activity
*copyc osp$establish_condition_handler
*copyc osp$generate_log_message
*copyc osp$get_current_display_message
*copyc osp$set_status_condition
*copyc osp$set_status_from_condition
*copyc osp$set_job_signature_lock
*copyc osp$test_signature_lock
*copyc osp$set_status_abnormal
*copyc osp$translate_bytes
*copyc pmp$continue_to_cause
*copyc pmp$get_executing_task_gtid
*copyc pmp$long_term_wait
*copyc pmp$wait
*copyc rmp$activate_volume
*copyc rmp$clear_implicit_reserve
*copyc rmp$deactivate_volume
*copyc rmp$emit_operator_message
*copyc rmp$extend_volume_list
*copyc rmp$log_debug_message
*copyc rmp$log_debug_status
*copyc rmp$set_implicit_reserve
*copyc rmv$densities
*copyc rmv$write_ring
*copyc sfp$emit_audit_statistic
?? OLDTITLE ??
?? NEWTITLE := 'dmp$advance_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$advance_tape_volume
    (    sfid: gft$system_file_identifier;
         extend: boolean;
         label_type: amt$label_type;
         access_mode: pft$usage_selections;
     VAR status: ost$status);

*copy rmi$block_exit_handler
?? EJECT ??

    VAR
      ignore_status: ost$status,
      ioid: iot$io_id,
      iostatus: iot$tape_io_status,
      last_choice_element: cmt$element_name,
      local_status: ost$status,
      lun_table_entry: ^dmt$tape_lun_table_entry;

    rmp$log_debug_message (' Entering dmp$advance_tape_volume');
    status.normal := TRUE;

    osp$establish_condition_handler (^rmp$block_exit_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    lun_table_entry := ^dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index];

{ Verify that volume list extension is allowed
{ (extend is true only when writing and the volume list is exhausted).

    IF (extend AND lun_table_entry^.volume_overflow_allowed) OR
          ((NOT extend) AND (lun_table_entry^.current_vsn_index < lun_table_entry^.number_of_vsns)) THEN
      IF (lun_table_entry^.current_vsn_index = lun_table_entry^.number_of_vsns) THEN
        rmp$log_debug_message (' Extending volume list');
        rmp$extend_volume_list (lun_table_entry, status);
      IFEND;
      IF status.normal THEN
        lun_table_entry^.current_vsn_index := lun_table_entry^.current_vsn_index + 1;
      IFEND;
    ELSE
      osp$set_status_condition (dme$volume_list_exhausted, status);
    IFEND;

    osp$clear_job_signature_lock (rmv$job_tape_table_lock);
    osp$end_subsystem_activity;
    osp$disestablish_cond_handler;

    IF status.normal THEN
{ Activate subsequent volume.
      last_choice_element := osc$null_name;
      REPEAT
        rmp$activate_volume (sfid, {acceptable_states} $cmt$element_states [cmc$on], last_choice_element,
              {Required_element} osc$null_name, status);
        IF status.normal THEN
          initialize_unit (sfid, label_type, access_mode, {recovery_remount} FALSE, last_choice_element,
                status);
        IFEND;
      UNTIL status.normal OR (status.condition <> dme$operator_reassign);
    IFEND;
    rmp$log_debug_message (' Exiting dmp$advance_tape_volume');

    IF NOT status.normal THEN
      rmp$clear_implicit_reserve (lun_table_entry^.density, ignore_status);
    IFEND;

  PROCEND dmp$advance_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$assign_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$assign_tape_volume
    (    sfid: gft$system_file_identifier;
         path_handle_name: fst$path_handle_name;
         label_type: amt$label_type;
         access_mode: pft$usage_selections;
     VAR status: ost$status);

?? NEWTITLE := '  assign_tape_volume_handler', EJECT ??

    PROCEDURE assign_tape_volume_handler
      (    condition: pmt$condition;
           p_condition_info: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        ignore_status: ost$status,
        lock_status: ost$signature_lock_status;

      CASE condition.selector OF
      = pmc$block_exit_processing =
        osp$test_signature_lock (rmv$job_tape_table_lock, lock_status);
        IF lock_status = osc$sls_locked_by_current_task THEN
          osp$clear_job_signature_lock (rmv$job_tape_table_lock);
          osp$end_subsystem_activity;
        IFEND;
        IF implicit_reserve_set THEN
          rmp$clear_implicit_reserve (density, ignore_status);
        IFEND;
      = ifc$interactive_condition =
        CASE condition.interactive_condition OF
        = ifc$pause_break, ifc$job_reconnect =
          ifp$invoke_pause_utility (ignore_status);
        = ifc$terminate_break =
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          osp$set_status_from_condition (rmc$resource_management_id, condition, save_area, status,
                ignore_status);
          EXIT dmp$assign_tape_volume;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        CASEND;
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      CASEND;

    PROCEND assign_tape_volume_handler;

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

    PROCEDURE establish_reservation
      (    sfid: gft$system_file_identifier;
           density: rmt$density;
       VAR implicit_reserve_set: boolean;
       VAR status: ost$status);

      VAR
        counter: rmt$supported_tape_densities,
        reservation: rmt$tape_reservation;

      IF (rmv$job_tape_table_p = NIL) THEN
        rmp$set_implicit_reserve (sfid, density, status);
        implicit_reserve_set := status.normal;
      ELSE
        implicit_reserve_set := FALSE;
        osp$begin_subsystem_activity;
        osp$set_job_signature_lock (rmv$job_tape_table_lock);
        IF rmv$job_tape_table_p^.job_recovery_active THEN
          { must regain explicit reserve
          FOR counter := rmc$800 TO rmc$maximum_density DO
            reservation [counter] := rmv$job_tape_table_p^.reserved_unit_count [counter];
          FOREND;
          osp$clear_job_signature_lock (rmv$job_tape_table_lock);
          osp$end_subsystem_activity;
          rmp$set_explicit_reserve (reservation, status);
          osp$begin_subsystem_activity;
          osp$set_job_signature_lock (rmv$job_tape_table_lock);
          rmv$job_tape_table_p^.job_recovery_active := FALSE;
        IFEND;
        IF status.normal THEN
          IF NOT rmv$job_tape_table_p^.explicit_reservation THEN
            osp$set_status_condition (dme$request_exceeds_reserve, status);
          ELSE
            IF (rmv$job_tape_table_p^.reserved_unit_count [density] -
                  rmv$job_tape_table_p^.assigned_unit_count [density] <= 0) THEN
              FOR counter := rmc$800 TO rmc$maximum_density DO
                IF (rmv$job_tape_table_p^.reserved_unit_count [counter] > 0) AND
                      (rmv$job_tape_table_p^.reserved_unit_count [counter] -
                      rmv$job_tape_table_p^.assigned_unit_count [counter] > 0) THEN
                  osp$set_status_condition (dme$request_reserve_mismatch, status);
                IFEND;
              FOREND;
              IF status.normal THEN
                osp$set_status_condition (dme$request_exceeds_reserve, status);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        osp$clear_job_signature_lock (rmv$job_tape_table_lock);
        osp$end_subsystem_activity;
      IFEND;

    PROCEND establish_reservation;
?? OLDTITLE ??
?? EJECT ??

    VAR
      debug_message_logged: boolean,
      density: rmt$density,
      ignore_status: ost$status,
      implicit_reserve_set: boolean,
      last_choice_element: cmt$element_name,
      lun_table_entry: ^dmt$tape_lun_table_entry;

    rmp$log_debug_message (' Entering dmp$assign_tape_volume');
    status.normal := TRUE;
    implicit_reserve_set := FALSE;
    #SPOIL (implicit_reserve_set);

    osp$establish_condition_handler (^assign_tape_volume_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    lun_table_entry := ^dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index];

    IF lun_table_entry^.lun = 0 THEN
      lun_table_entry^.label_type := label_type;
      CASE label_type OF
      = amc$labelled =
        rmp$log_debug_message (' Label Type is LABELED');
      = amc$unlabelled =
        rmp$log_debug_message (' Label Type is UNLABELED');
      = amc$non_standard_labelled =
        rmp$log_debug_message (' Label Type is NON_STANDARD_LABELED');
      ELSE
      CASEND;
      density := lun_table_entry^.density;
      #SPOIL (density);

      debug_message_logged := FALSE;
      REPEAT
        IF NOT debug_message_logged THEN
          rmp$log_debug_message (' Calling dmp$validate_tape_density');
        IFEND;
        dmp$validate_tape_density (density, status);
        IF NOT status.normal AND (status.condition = dme$unable_to_lock_tape_table) THEN
          IF NOT debug_message_logged THEN
            rmp$log_debug_message (' Waiting for tape table lock');
            debug_message_logged := TRUE;
          IFEND;
          osp$clear_job_signature_lock (rmv$job_tape_table_lock);
          osp$end_subsystem_activity;
          pmp$long_term_wait (one_second, one_second);
          osp$begin_subsystem_activity;
          osp$set_job_signature_lock (rmv$job_tape_table_lock);
        IFEND;
      UNTIL status.normal OR (status.condition <> dme$unable_to_lock_tape_table);
    ELSE
      osp$set_status_condition (dme$active_tape_volume, status);
    IFEND;
    osp$clear_job_signature_lock (rmv$job_tape_table_lock);
    osp$end_subsystem_activity;

    IF status.normal AND (NOT dmv$initialize_tape_volume.in_progress) THEN
      establish_reservation (sfid, density, implicit_reserve_set, status);
      #SPOIL (implicit_reserve_set);
    IFEND;
    IF status.normal THEN
{ Select initial volume for processing.

      osp$begin_subsystem_activity;
      osp$set_job_signature_lock (rmv$job_tape_table_lock);

      lun_table_entry^.current_vsn_index := 1;

      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;

      last_choice_element := osc$null_name;
      REPEAT
        rmp$activate_volume (sfid, {acceptable_states} $cmt$element_states [cmc$on], last_choice_element,
              {Required_element} osc$null_name, status);
        IF status.normal THEN
          initialize_unit (sfid, label_type, access_mode, {recovery_remount} FALSE, last_choice_element,
                status);
        IFEND;
      UNTIL status.normal OR (status.condition <> dme$operator_reassign);
    IFEND;

    IF (NOT status.normal) AND implicit_reserve_set THEN
      rmp$clear_implicit_reserve (density, ignore_status);
    IFEND;

    osp$disestablish_cond_handler;
    rmp$log_debug_message (' Exiting dmp$assign_tape_volume');

  PROCEND dmp$assign_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$close_current_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$close_current_tape_volume
    (    sfid: gft$system_file_identifier;
         detachment_options: fmt$detachment_options;
     VAR status: ost$status);

*copy rmi$block_exit_handler
?? EJECT ??

    VAR
      ignore_iostatus: iot$tape_io_status,
      ioid: iot$io_id,
      local_status: ost$status,
      lun_active: boolean;

    rmp$log_debug_message (' Entering dmp$close_current_tape_volume');
    status.normal := TRUE;

    osp$establish_condition_handler (^rmp$block_exit_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    IF (dmv$tape_job_lun_table_p = NIL) OR (NOT dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
          slot_in_use) THEN
      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
      osp$disestablish_cond_handler;
    ELSE
      lun_active := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].lun <> 0;
      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
      osp$disestablish_cond_handler;
      IF lun_active THEN
        iop$unload_tape (sfid, detachment_options, ioid, status);
        IF status.normal THEN
          get_tape_status (sfid, ioid, ignore_iostatus, status);
        IFEND;

        rmp$deactivate_volume (sfid, {delete_request_from_vsn_queue} TRUE, local_status);
        osp$copy_local_status_to_status (local_status, status);
      IFEND;
    IFEND;
    rmp$log_debug_message (' Exiting dmp$close_current_tape_volume');

  PROCEND dmp$close_current_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$close_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$close_tape_volume
    (    sfid: gft$system_file_identifier;
         detachment_options: fmt$detachment_options;
     VAR status: ost$status);

*copy rmi$block_exit_handler

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

    PROCEDURE close_tape_volume_handler
      (    condition: pmt$condition;
           p_condition_info: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        ignore_status: ost$status,
        lock_status: ost$signature_lock_status;

      CASE condition.selector OF
      = pmc$block_exit_processing =
        osp$test_signature_lock (rmv$job_tape_table_lock, lock_status);
        IF lock_status = osc$sls_locked_by_current_task THEN
          osp$clear_job_signature_lock (rmv$job_tape_table_lock);
          osp$end_subsystem_activity;
        IFEND;
      = ifc$interactive_condition =
        CASE condition.interactive_condition OF
        = ifc$pause_break, ifc$job_reconnect =
          ifp$invoke_pause_utility (ignore_status);
        = ifc$terminate_break =
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          osp$set_status_from_condition (rmc$resource_management_id, condition, save_area, status,
                ignore_status);
          EXIT dmp$close_tape_volume;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        CASEND;
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      CASEND;

    PROCEND close_tape_volume_handler;

    VAR
      clear_implicit_reserve: boolean,
      debug_message_logged: boolean,
      density: rmt$density,
      ioid: iot$io_id,
      ignore_iostatus: iot$tape_io_status,
      job_recovery_active: boolean,
      local_status: ost$status,
      lun_active: boolean,
      lun_table_entry: ^dmt$tape_lun_table_entry,
      reservation: rmt$tape_reservation;

    local_status.normal := TRUE;
    status.normal := TRUE;

    rmp$log_debug_message (' Entering dmp$close_tape_volume');
    osp$establish_condition_handler (^close_tape_volume_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    IF (dmv$tape_job_lun_table_p = NIL) OR (NOT dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
          slot_in_use) THEN
      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
      osp$disestablish_cond_handler;
    ELSE
      density := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].density;
      clear_implicit_reserve := (NOT dmv$initialize_tape_volume.in_progress) AND
            (rmv$job_tape_table_p <> NIL) AND (NOT rmv$job_tape_table_p^.explicit_reservation) AND
            (rmv$job_tape_table_p^.reserved_unit_count [density] > 0);
      job_recovery_active := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].job_recovery_active;
      lun_active := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].lun <> 0;
      lun_table_entry := ^dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index];

      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;

      IF lun_active THEN
        rmp$log_debug_message (' Calling iop$unload_tape');
        iop$unload_tape (sfid, detachment_options, ioid, status);
        IF status.normal THEN
          get_tape_status (sfid, ioid, ignore_iostatus, status);
          rmp$log_debug_message (' Exiting get_tape_status for iop$unload_tape');
        IFEND;
        IF dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
              robotic_mount_info.volume_robotically_mounted THEN
          IF detachment_options.device_class = rmc$magnetic_tape_device THEN
            dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
                  robotic_mount_info.volume_robotically_mounted := detachment_options.physical_unload;
          IFEND;
        IFEND;
        rmp$log_debug_message (' Calling rmp$deactivate_volume');
        rmp$deactivate_volume (sfid, {delete_request_from_vsn_queue} TRUE, local_status);
        osp$copy_local_status_to_status (local_status, status);
      ELSEIF job_recovery_active THEN
        osp$begin_subsystem_activity;
        osp$set_job_signature_lock (rmv$job_tape_table_lock);
        rmv$job_tape_table_p^.assigned_unit_count [density] :=
              rmv$job_tape_table_p^.assigned_unit_count [density] - 1;
        osp$clear_job_signature_lock (rmv$job_tape_table_lock);
        osp$end_subsystem_activity;
      IFEND;

{ Release unit reserve

      IF clear_implicit_reserve THEN
        rmp$clear_implicit_reserve (density, local_status);
        osp$copy_local_status_to_status (local_status, status);
      IFEND;

{ Free dmv$tape_job_lun_table if this is the only tape file assigned.
{ If there are more tapes assigned to the job, decrement the count of tapes
{ assigned.

      osp$begin_subsystem_activity;
      osp$set_job_signature_lock (rmv$job_tape_table_lock);

      dmv$tape_job_lun_table_p^.count := dmv$tape_job_lun_table_p^.count - 1;
      lun_table_entry^.lun := 0;
      lun_table_entry^.slot_in_use := FALSE;
      FREE lun_table_entry^.volume_list IN osv$job_pageable_heap^;
      IF dmv$tape_job_lun_table_p^.count = 0 THEN
        FREE dmv$tape_job_lun_table_p^.tape_file IN osv$job_pageable_heap^;
        FREE dmv$tape_job_lun_table_p IN osv$job_pageable_heap^;
      IFEND;

      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
      osp$disestablish_cond_handler;
    IFEND;
{ Remove any traces of the rvl entry.

    debug_message_logged := FALSE;
    REPEAT
      IF NOT debug_message_logged THEN
        rmp$log_debug_message (' Calling iop$delete_rvl_entry');
      IFEND;
      iop$delete_rvl_entry (sfid, local_status);
      IF NOT local_status.normal AND (local_status.condition = dme$unable_to_lock_tape_table) THEN
        IF NOT debug_message_logged THEN
          rmp$log_debug_message (' Waiting for tape table lock');
          debug_message_logged := TRUE;
        IFEND;
        pmp$long_term_wait (one_second, one_second);
      IFEND;
    UNTIL local_status.normal OR (local_status.condition <> dme$unable_to_lock_tape_table);
    rmp$log_debug_message (' Exiting dmp$close_tape_volume');
    rmp$log_debug_status (local_status);

  PROCEND dmp$close_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$create_tape_file_sfid', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$create_tape_file_sfid
    (    p_removable_media_req_info: {input} ^fmt$removable_media_req_info;
         p_volume_list: {input} ^rmt$volume_list;
     VAR sfid: gft$system_file_identifier;
     VAR status: ost$status);

*copy rmi$block_exit_handler
?? EJECT ??

    VAR
      found: boolean,
      lun_table_index: integer;

    rmp$log_debug_message (' Entering dmp$create_tape_file_sfid');
    status.normal := TRUE;

    osp$establish_condition_handler (^rmp$block_exit_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    IF dmv$tape_job_lun_table_p = NIL THEN
      ALLOCATE dmv$tape_job_lun_table_p IN osv$job_pageable_heap^;
      ALLOCATE dmv$tape_job_lun_table_p^.tape_file: [1 .. (iov$number_of_tape_units +
            dmc$extra_lun_table_entries)] IN osv$job_pageable_heap^;
      FOR lun_table_index := 1 TO UPPERBOUND (dmv$tape_job_lun_table_p^.tape_file^) DO
        dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].slot_in_use := FALSE;
      FOREND;
      dmv$tape_job_lun_table_p^.count := 0;
    IFEND;

    found := FALSE;

  /search_for_empty_slot/
    FOR lun_table_index := 1 TO UPPERBOUND (dmv$tape_job_lun_table_p^.tape_file^) DO
      IF NOT dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].slot_in_use THEN
        found := TRUE;
        EXIT /search_for_empty_slot/;
      IFEND;
    FOREND /search_for_empty_slot/;

    IF NOT found THEN
      osp$set_status_condition (dme$tape_attach_limit_exceeded, status);
    IFEND;

    IF status.normal THEN
      dmv$tape_job_lun_table_p^.count := dmv$tape_job_lun_table_p^.count + 1;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].slot_in_use := TRUE;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].lun := 0;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].label_type := amc$labeled;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].density := p_removable_media_req_info^.density;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].requested_volume_attributes :=
            rmv$requested_volume_attributes;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].requested_volume_attributes.
            removable_media_group := p_removable_media_req_info^.removable_media_group;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].source_pool := osc$null_name;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].source_pool_location := osc$null_name;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].robotic_mount_info.volume_robotically_mounted :=
            FALSE;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].volume_overflow_allowed :=
            p_removable_media_req_info^.volume_overflow_allowed;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].write_ring :=
            p_removable_media_req_info^.write_ring;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].current_vsn_index := 1;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].number_of_vsns := UPPERBOUND (p_volume_list^);
      ALLOCATE dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].volume_list:
            [1 .. UPPERBOUND (p_volume_list^)] IN osv$job_pageable_heap^;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].volume_list^ := p_volume_list^;
      dmv$tape_job_lun_table_p^.tape_file^ [lun_table_index].job_recovery_active := FALSE;
      sfid.file_entry_index := lun_table_index;
      sfid.residence := gfc$tr_job;
      sfid.file_hash := 0;
    IFEND;

    osp$clear_job_signature_lock (rmv$job_tape_table_lock);
    osp$end_subsystem_activity;
    osp$disestablish_cond_handler;
    rmp$log_debug_message (' Exiting dmp$create_tape_file_sfid');

  PROCEND dmp$create_tape_file_sfid;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$reset_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$reset_tape_volume
    (    sfid: gft$system_file_identifier;
         label_type: amt$label_type;
         access_mode: pft$usage_selections;
     VAR status: ost$status);

*copy rmi$block_exit_handler
?? EJECT ??

    VAR
      ioid: iot$io_id,
      iostatus: iot$tape_io_status,
      last_choice_element: cmt$element_name,
      local_status: ost$status,
      lun_table_entry: ^dmt$tape_lun_table_entry;

  /main_program/
    BEGIN

      rmp$log_debug_message (' Entering dmp$reset_tape_volume');
      status.normal := TRUE;

      osp$establish_condition_handler (^rmp$block_exit_handler, {handle block exit} TRUE);
      osp$begin_subsystem_activity;
      osp$set_job_signature_lock (rmv$job_tape_table_lock);

      lun_table_entry := ^dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index];

{
{        select initial volume for activation
{
      lun_table_entry^.current_vsn_index := 1;

      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
      last_choice_element := osc$null_name;
      REPEAT
        rmp$activate_volume (sfid, {acceptable_states} $cmt$element_states [cmc$on], last_choice_element,
              {Required_element} osc$null_name, status);
        IF status.normal THEN
          initialize_unit (sfid, label_type, access_mode, {recovery_remount} FALSE, last_choice_element,
                status);
        IFEND;
      UNTIL status.normal OR (status.condition <> dme$operator_reassign);

    END /main_program/;
    osp$disestablish_cond_handler;
    rmp$log_debug_message (' Exiting dmp$reset_tape_volume');

  PROCEND dmp$reset_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'dmp$unload_remount_tape_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$unload_remount_tape_volume
    (    sfid: gft$system_file_identifier;
         access_mode: pft$usage_selections;
         recovery_remount: boolean;
     VAR status: ost$status);

*copy rmi$block_exit_handler
?? EJECT ??

    VAR
      density: rmt$supported_tape_densities,
      detachment_options: fmt$detachment_options,
      ioid: iot$io_id,
      ignore_iostatus: iot$tape_io_status,
      job_recovery_active: boolean,
      label_type: amt$label_type,
      last_choice_element: cmt$element_name,
      local_status: ost$status,
      lun_active: boolean,
      lun_table_entry: ^dmt$tape_lun_table_entry,
      reservation: rmt$tape_reservation;

    rmp$log_debug_message (' Entering dmp$unload_remount_tape_volume');
    status.normal := TRUE;

    osp$establish_condition_handler (^rmp$block_exit_handler, {handle block exit} TRUE);
    osp$begin_subsystem_activity;
    osp$set_job_signature_lock (rmv$job_tape_table_lock);

    lun_active := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].lun <> 0;
    lun_table_entry := ^dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index];
    label_type := lun_table_entry^.label_type;

    job_recovery_active := rmv$job_tape_table_p^.job_recovery_active;
    IF job_recovery_active THEN
      { Must reclaim explicit reserves
      FOR density := rmc$800 TO rmc$maximum_density DO
        reservation [density] := rmv$job_tape_table_p^.reserved_unit_count [density];
      FOREND;
    IFEND;
    osp$clear_job_signature_lock (rmv$job_tape_table_lock);
    osp$end_subsystem_activity;

{ Deactivate currently active volume.

    IF lun_active THEN
      detachment_options := fmv$default_detachment_options;
      detachment_options.device_class := rmc$magnetic_tape_device;
      detachment_options.physical_unload := TRUE;

      iop$unload_tape (sfid, detachment_options, ioid, status);
      IF status.normal THEN
        get_tape_status (sfid, ioid, ignore_iostatus, status);
      IFEND;

      rmp$deactivate_volume (sfid, {delete_request_from_vsn_queue} FALSE, local_status);
      osp$copy_local_status_to_status (local_status, status);
    ELSEIF job_recovery_active THEN
      rmp$set_explicit_reserve (reservation, status);

      osp$begin_subsystem_activity;
      osp$set_job_signature_lock (rmv$job_tape_table_lock);

      rmv$job_tape_table_p^.job_recovery_active := FALSE;

      IF status.normal THEN
        density := lun_table_entry^.density;
        rmv$job_tape_table_p^.assigned_unit_count [density] :=
              rmv$job_tape_table_p^.assigned_unit_count [density] - 1;
        lun_table_entry^.job_recovery_active := FALSE;
      IFEND;

      osp$clear_job_signature_lock (rmv$job_tape_table_lock);
      osp$end_subsystem_activity;
    IFEND;

    IF status.normal THEN
      last_choice_element := osc$null_name;
      REPEAT
        rmp$activate_volume (sfid, {acceptable_states} $cmt$element_states [cmc$on], last_choice_element,
              {Required_element} osc$null_name, status);
        IF status.normal THEN
          initialize_unit (sfid, label_type, access_mode, recovery_remount, last_choice_element, status);
        IFEND;
      UNTIL status.normal OR (status.condition <> dme$operator_reassign);
    IFEND;

    osp$disestablish_cond_handler;
    rmp$log_debug_message (' Exiting dmp$unload_remount_tape_volume');

  PROCEND dmp$unload_remount_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := 'get_tape_status', EJECT ??

  PROCEDURE get_tape_status
    (    sfid: gft$system_file_identifier;
         ioid: iot$io_id;
     VAR iostatus: iot$tape_io_status;
     VAR status: ost$status);

    status.normal := TRUE;
    iostatus.io_complete := FALSE;

    iop$tape_request_status (sfid, ioid, {wait=} TRUE, iostatus, status);

  PROCEND get_tape_status;
?? OLDTITLE ??
?? NEWTITLE := 'initialize_unit', EJECT ??

  PROCEDURE initialize_unit
    (    sfid: gft$system_file_identifier;
         label_type: amt$label_type;
         access_mode: pft$usage_selections;
         recovery_remount: boolean;
     VAR last_choice_element: cmt$element_name;
     VAR status: ost$status);

    VAR
      message_parameters: array [1 .. 4] of ^ost$message_parameter,
      original_message: oft$display_message;

?? NEWTITLE := '  abnormal_cleanup', EJECT ??

    PROCEDURE abnormal_cleanup
      (    retain_volume_and_reservation: boolean);

      VAR
        delete_request_from_vsn_queue: boolean,
        detachment_options: fmt$detachment_options,
        ignore_status: ost$status,
        ignore_iostatus: iot$tape_io_status,
        ioid: iot$io_id,
        local_status: ost$status,
        wait_message_displayed: boolean;

      rmp$log_debug_message (' Calling iop$unload_tape from initialize_unit');

      detachment_options := fmv$default_detachment_options;
      detachment_options.device_class := rmc$magnetic_tape_device;
      detachment_options.physical_unload := TRUE;

      iop$unload_tape (sfid, detachment_options, ioid, local_status);
      IF local_status.normal THEN
        get_tape_status (sfid, ioid, ignore_iostatus, ignore_status);
        rmp$log_debug_status (ignore_status);
      IFEND;

      delete_request_from_vsn_queue := NOT retain_volume_and_reservation;
      rmp$log_debug_message (' Calling rmp$deactivate_volume from initialize_unit');
      rmp$deactivate_volume (sfid, delete_request_from_vsn_queue, ignore_status);

      IF (NOT retain_volume_and_reservation) AND (NOT dmv$initialize_tape_volume.in_progress) AND
            (NOT rmv$job_tape_table_p^.explicit_reservation) THEN
        rmp$log_debug_message (' Calling rmp$clear_implicit_reserve from initialize_unit');
        rmp$clear_implicit_reserve (dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].density,
              ignore_status);
      IFEND;

      ofp$clear_operator_message (ofc$removable_media_operator, ignore_status);
      wait_message_displayed := TRUE;
      osp$clear_wait_message (original_message, wait_message_displayed);
    PROCEND abnormal_cleanup;

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

    PROCEDURE check_for_operator_reassign
      (    tusl_ordinal: iot$tusl_ordinal;
           log_debug_message: boolean;
       VAR status: ost$status);

      VAR
        tusl_entry_access: iot$tusl_entry_access;

      REPEAT
        IF log_debug_message THEN
          rmp$log_debug_message (' Calling iop$access_tusl_entry');
        IFEND;
        tusl_entry_access.operation := ioc$fetch_operator_reassign;
        iop$access_tusl_entry (tusl_ordinal, tusl_entry_access, status);
        IF NOT status.normal THEN
          IF status.condition = dme$unable_to_lock_tape_table THEN
            IF log_debug_message THEN
              rmp$log_debug_message (' Waiting for tape table lock');
            IFEND;
            osp$establish_condition_handler (^initialize_unit_lock_handler, {handle block exit} FALSE);
            pmp$long_term_wait (one_second, one_second);
            osp$disestablish_cond_handler;
          ELSE
            RETURN;
          IFEND;
        IFEND;
      UNTIL status.normal;

      IF tusl_entry_access.fetch_operator_reassign THEN
        osp$set_status_condition (dme$operator_reassign, status);
      IFEND;

    PROCEND check_for_operator_reassign;

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

    PROCEDURE disable_operator_reassign
      (    tusl_ordinal: iot$tusl_ordinal);

      VAR
        local_status: ost$status,
        tusl_entry_access: iot$tusl_entry_access;

      ofp$clear_operator_message (ofc$removable_media_operator, ignore_status);

      debug_message_logged := FALSE;
      REPEAT
        IF NOT debug_message_logged THEN
          rmp$log_debug_message (' Calling iop$access_tusl_entry');
        IFEND;
        tusl_entry_access.operation := ioc$disable_operator_reassign;
        iop$access_tusl_entry (tusl_ordinal, tusl_entry_access, local_status);
        IF NOT local_status.normal THEN
          IF local_status.condition = dme$unable_to_lock_tape_table THEN
            IF NOT debug_message_logged THEN
              rmp$log_debug_message (' Waiting for tape table lock');
              debug_message_logged := TRUE;
            IFEND;
            osp$establish_condition_handler (^initialize_unit_lock_handler, {handle block exit} FALSE);
            pmp$long_term_wait (one_second, one_second);
            osp$disestablish_cond_handler;
          ELSE
            RETURN;
          IFEND;
        IFEND;
      UNTIL local_status.normal;

    PROCEND disable_operator_reassign;

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

    PROCEDURE dismount_volume
      (    initialization_record: dmt$tape_initialization_record;
           sfid: gft$system_file_identifier;
       VAR status: ost$status);

      VAR
        detachment_options: fmt$detachment_options,
        ioid: iot$io_id;

      detachment_options := fmv$default_detachment_options;
      detachment_options.device_class := rmc$magnetic_tape_device;
      detachment_options.physical_unload := TRUE;

      iop$unload_tape (sfid, detachment_options, ioid, status);
      IF status.normal THEN
        get_tape_status (sfid, ioid, iostatus, status);
        IF status.normal THEN
          iop$initialize_tape_ud (initialization_record, {multiple_requests_possible} TRUE, status);
        IFEND;
      IFEND;
    PROCEND dismount_volume;
?? OLDTITLE ??
?? NEWTITLE := '  emit_job_log_message', EJECT ??

    PROCEDURE emit_job_log_message
      (    sfid: gft$system_file_identifier;
           element_name: cmt$element_name;
           recovery_remount: boolean;
           requested_ring: rmt$write_ring);

      VAR
        ignore_status: ost$status,
        logset: pmt$ascii_logset,
        log_message_status: ost$status;

      IF NOT recovery_remount THEN
        osp$set_status_condition (dme$volume, log_message_status);
      ELSE
        osp$set_status_condition (dme$recovery_remount, log_message_status);
      IFEND;
      osp$append_status_parameter (osc$status_parameter_delimiter, dmv$tape_job_lun_table_p^.
            tape_file^ [sfid.file_entry_index].volume_list^ [dmv$tape_job_lun_table_p^.
            tape_file^ [sfid.file_entry_index].current_vsn_index].external_vsn, log_message_status);
      osp$append_status_parameter (osc$status_parameter_delimiter, element_name, log_message_status);
      IF (requested_ring = rmc$write_ring) THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'write', log_message_status);
      ELSE
        osp$append_status_parameter (osc$status_parameter_delimiter, 'read', log_message_status);
      IFEND;

      logset := $pmt$ascii_logset [pmc$job_log];
      osp$generate_log_message (logset, log_message_status, ignore_status);
    PROCEND emit_job_log_message;
?? OLDTITLE ??
?? NEWTITLE := '  emit_security_statistic', EJECT ??

    PROCEDURE emit_security_statistic
      (    element_name: cmt$element_name);

      VAR
        audit_information: sft$audit_information;

      IF avp$security_option_active (avc$vso_security_audit) THEN
        audit_information.audited_operation := sfc$ao_fs_magnetic_tape_mount;
        audit_information.mount_magnetic_tape.external_vsn_p := ^dmv$tape_job_lun_table_p^.
              tape_file^ [sfid.file_entry_index].volume_list^ [dmv$tape_job_lun_table_p^.
              tape_file^ [sfid.file_entry_index].current_vsn_index].external_vsn;
        audit_information.mount_magnetic_tape.recorded_vsn_p := ^dmv$tape_job_lun_table_p^.
              tape_file^ [sfid.file_entry_index].volume_list^ [dmv$tape_job_lun_table_p^.
              tape_file^ [sfid.file_entry_index].current_vsn_index].recorded_vsn;
        audit_information.mount_magnetic_tape.write_ring := (requested_ring = rmc$write_ring);
        audit_information.mount_magnetic_tape.element_name_p := ^element_name;
        sfp$emit_audit_statistic (audit_information, status);
      IFEND;

    PROCEND emit_security_statistic;
?? OLDTITLE ??
?? NEWTITLE := '  enable_operator_reassign', EJECT ??

    PROCEDURE enable_operator_reassign
      (    tusl_ordinal: iot$tusl_ordinal);

      VAR
        local_status: ost$status,
        tusl_entry_access: iot$tusl_entry_access;

      debug_message_logged := FALSE;
      REPEAT
        IF NOT debug_message_logged THEN
          rmp$log_debug_message (' Calling iop$access_tusl_entry');
        IFEND;
        tusl_entry_access.operation := ioc$enable_operator_reassign;
        iop$access_tusl_entry (tusl_ordinal, tusl_entry_access, local_status);
        IF NOT local_status.normal THEN
          IF local_status.condition = dme$unable_to_lock_tape_table THEN
            IF NOT debug_message_logged THEN
              rmp$log_debug_message (' Waiting for tape table lock');
              debug_message_logged := TRUE;
            IFEND;
            osp$establish_condition_handler (^initialize_unit_lock_handler, {handle block exit} FALSE);
            pmp$long_term_wait (one_second, one_second);
            osp$disestablish_cond_handler;
          ELSE
            RETURN;
          IFEND;
        IFEND;
      UNTIL local_status.normal;

    PROCEND enable_operator_reassign;

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

    PROCEDURE ensure_unit_operational
      (    sfid: gft$system_file_identifier;
           message_parameters: array [1 .. * ] of ^ost$message_parameter;
           tusl_ordinal: iot$tusl_ordinal;
       VAR status: ost$status);

      VAR
        ignore_status: ost$status,
        ioid: iot$io_id,
        iostatus: iot$tape_io_status,
        log_debug_message: boolean,
        message_name: clt$parameter_name;

      enable_operator_reassign (tusl_ordinal);

      message_name := 'UNIT_NOT_OPERATIONAL';
      rmp$emit_operator_message (message_name, ^message_parameters, {acknowledgement_allowed} FALSE,
            ignore_status);

      log_debug_message := TRUE;
    /not_ready/
      REPEAT
        iop$tape_initialize_unit (sfid, ioid, status);
        IF status.normal THEN
          get_tape_status (sfid, ioid, iostatus, status);
          IF status.normal THEN
            IF NOT iostatus.normal_completion THEN
              pmp$long_term_wait (four_seconds, four_seconds);
              check_for_operator_reassign (tusl_ordinal, log_debug_message, status);
              log_debug_message := FALSE;
            IFEND;
          IFEND;
        IFEND;
      UNTIL NOT status.normal OR (iostatus.normal_completion AND iostatus.unit_ready);

      disable_operator_reassign (tusl_ordinal);

    PROCEND ensure_unit_operational;
?? OLDTITLE ??
?? NEWTITLE := '  ensure_unit_ready', EJECT ??

    PROCEDURE ensure_unit_ready
      (    sfid: gft$system_file_identifier;
           message_parameters: array [1 .. * ] of ^ost$message_parameter;
           tusl_ordinal: iot$tusl_ordinal;
       VAR status: ost$status);

      VAR
        ignore_status: ost$status,
        ioid: iot$io_id,
        iostatus: iot$tape_io_status,
        log_debug_message: boolean,
        message_name: clt$parameter_name;

      enable_operator_reassign (tusl_ordinal);

      message_name := 'UNIT_NOT_READY';
      rmp$emit_operator_message (message_name, ^message_parameters, {acknowledgement_allowed} FALSE,
            ignore_status);

      log_debug_message := TRUE;
    /not_ready/
      REPEAT
        iop$tape_initialize_unit (sfid, ioid, status);
        IF status.normal THEN
          get_tape_status (sfid, ioid, iostatus, status);
          IF status.normal THEN
            IF iostatus.normal_completion AND NOT iostatus.unit_ready THEN
              pmp$long_term_wait (one_second, one_second);
              check_for_operator_reassign (tusl_ordinal, log_debug_message, status);
              log_debug_message := FALSE;
            IFEND;
          IFEND;
        IFEND;
      UNTIL NOT status.normal OR (iostatus.normal_completion AND iostatus.unit_ready);

      disable_operator_reassign (tusl_ordinal);

    PROCEND ensure_unit_ready;
?? OLDTITLE ??
?? NEWTITLE := '  ensure_unit_write_enabled', EJECT ??

    PROCEDURE ensure_unit_write_enabled
      (    sfid: gft$system_file_identifier;
           message_parameters: array [1 .. * ] of ^ost$message_parameter;
           tusl_ordinal: iot$tusl_ordinal;
       VAR status: ost$status);

      VAR
        ignore_status: ost$status,
        ioid: iot$io_id,
        iostatus: iot$tape_io_status,
        log_debug_message: boolean,
        message_name: clt$parameter_name;

      enable_operator_reassign (tusl_ordinal);

      message_name := 'UNIT_NOT_WRITE_ENABLED';
      rmp$emit_operator_message (message_name, ^message_parameters, {acknowledgement_allowed} FALSE,
            ignore_status);

      dismount_volume (initialization_record, sfid, status);
      IF status.normal THEN

        log_debug_message := TRUE;
      /mandate_ring/
        REPEAT
          iop$tape_initialize_unit (sfid, ioid, status);
          IF status.normal THEN
            get_tape_status (sfid, ioid, iostatus, status);
            IF status.normal AND iostatus.normal_completion THEN
              IF iostatus.unit_ready THEN
                IF iostatus.unit_busy THEN
                  pmp$long_term_wait (one_second, one_second);
                  check_for_operator_reassign (tusl_ordinal, log_debug_message, status);
                  log_debug_message := FALSE;
                ELSEIF NOT iostatus.write_ring THEN
                  dismount_volume (initialization_record, sfid, status);
                IFEND;
              ELSE {not ready}
                pmp$long_term_wait (one_second, one_second);
                check_for_operator_reassign (tusl_ordinal, log_debug_message, status);
                log_debug_message := FALSE;
              IFEND;
            ELSE {unit not operational}
              pmp$long_term_wait (four_seconds, four_seconds);
              check_for_operator_reassign (tusl_ordinal, log_debug_message, status);
              log_debug_message := FALSE;
            IFEND;
          IFEND;
        UNTIL NOT status.normal OR (iostatus.normal_completion AND (NOT iostatus.unit_busy) AND
              iostatus.unit_ready AND iostatus.write_ring);

      IFEND;
      disable_operator_reassign (tusl_ordinal);

    PROCEND ensure_unit_write_enabled;

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

    PROCEDURE initialize_unit_handler
      (    condition: pmt$condition;
           p_condition_info: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        ignore_status: ost$status,
        ioid: iot$io_id,
        local_status: ost$status;

      CASE condition.selector OF
      = pmc$block_exit_processing =
        abnormal_cleanup ({retain_volume_and_reservation} FALSE);
      = ifc$interactive_condition =
        CASE condition.interactive_condition OF
        = ifc$pause_break, ifc$job_reconnect =
          ifp$invoke_pause_utility (ignore_status);
        = ifc$terminate_break =
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          osp$set_status_from_condition (rmc$resource_management_id, condition, save_area, status,
                ignore_status);
          EXIT initialize_unit;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        CASEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = osc$job_recovery_condition_name THEN
          dmp$unload_remount_tape_volume (sfid, access_mode, {recovery_remount} FALSE, ignore_status);
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          EXIT initialize_unit;
        IFEND;
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      CASEND;

    PROCEND initialize_unit_handler;

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

    PROCEDURE initialize_unit_lock_handler
      (    condition: pmt$condition;
           p_condition_info: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        ignore_status: ost$status;

      CASE condition.selector OF
      = ifc$interactive_condition =
        CASE condition.interactive_condition OF
        = ifc$pause_break, ifc$job_reconnect =
          ifp$invoke_pause_utility (ignore_status);
        = ifc$terminate_break =
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          osp$set_status_from_condition (rmc$resource_management_id, condition, save_area, status,
                ignore_status);
          EXIT initialize_unit;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        CASEND;
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      CASEND;

    PROCEND initialize_unit_lock_handler;

?? OLDTITLE ??

*copy rmi$block_exit_handler
?? NEWTITLE := '  robotic_write_disabled_menu', EJECT ??

    PROCEDURE robotic_write_disabled_menu
      (    message_parameters: array [1 .. * ] of ^ost$message_parameter;
       VAR status: ost$status);

      CONST
        default_terminate_reason = 'the operator refused to write-enable a robotic volume',
        number_of_choices = 2;

      VAR
        parameter_names: ^ost$parameter_help_names,
        response_string: ost$string,
        response: oft$number_of_choices,
        string_size: ost$name_size,
        terminate_reason: string (osc$max_string_size);

      PUSH parameter_names: [1 .. number_of_choices];
      parameter_names^ [1] := 'ALLOW_WRITE_ACCESS';
      parameter_names^ [2] := 'TERMINATE_REQUEST';

      ofp$format_operator_menu (rmc$robotic_write_disabled, parameter_names, ^message_parameters,
            number_of_choices, ofc$removable_media_operator, response, response_string, status);
      IF status.normal THEN
        CASE response OF
        = 1 = { remount the volume and retry }
          osp$set_status_condition (dme$operator_reassign, status);
        = 2 = { terminate the assignment. }
          IF response_string.size > 0 THEN
            terminate_reason := response_string.value (1, response_string.size);
          ELSE
            terminate_reason := default_terminate_reason;
          IFEND;
          osp$set_status_abnormal (rmc$resource_management_id, dme$operator_stop, terminate_reason, status);
        ELSE
        CASEND;
      IFEND;

    PROCEND robotic_write_disabled_menu;
?? OLDTITLE ??
?? EJECT ??

    VAR
      debug_message_logged: boolean,
      element_name: cmt$element_name,
      ignore_status: ost$status,
      initialization_record: dmt$tape_initialization_record,
      ioid: iot$io_id,
      iostatus: iot$tape_io_status,
      local_status: ost$status,
      lun: iot$logical_unit,
      requested_evsn: rmt$external_vsn,
      requested_ring: rmt$write_ring,
      requested_rvsn: rmt$recorded_vsn,
      tusl_entry_access: iot$tusl_entry_access,
      tusl_ordinal: iot$tusl_ordinal,
      volume_robotically_mounted: boolean;

    rmp$log_debug_message (' Entering Initialize_unit');
    status.normal := TRUE;

    last_choice_element := osc$null_name;

    osp$get_current_display_message (original_message);

  /table_locked/
    BEGIN

      osp$establish_condition_handler (^rmp$block_exit_handler, {handle_block_exit} TRUE);
      osp$begin_subsystem_activity;
      osp$set_job_signature_lock (rmv$job_tape_table_lock);

      IF dmv$tape_job_lun_table_p <> NIL THEN
        lun := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].lun;

        cmp$get_element_name_via_lun (lun, element_name, status);
        IF status.normal THEN

{ Scan the tusl for the element being processed.

        /scan_tusl/
          BEGIN
            FOR tusl_ordinal := LOWERBOUND (iov$tusl_p^) TO UPPERBOUND (iov$tusl_p^) DO
              IF (iov$tusl_p^ [tusl_ordinal].element_name = element_name) THEN
                EXIT /scan_tusl/;
              IFEND;
            FOREND;

            osp$set_status_abnormal (rmc$resource_management_id, rme$undefined_element_name, element_name,
                  status);
            EXIT /table_locked/;
          END /scan_tusl/;


          requested_evsn := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
                volume_list^ [dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].current_vsn_index].
                external_vsn;

          requested_ring := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].write_ring;

          requested_rvsn := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
                volume_list^ [dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].current_vsn_index].
                recorded_vsn;

          volume_robotically_mounted := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
                robotic_mount_info.volume_robotically_mounted;

{ Create initialization record.

          initialization_record.logical_unit_number := lun;
          initialization_record.density := dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].
                density;

{ Initialize unit descriptor.

          iop$initialize_tape_ud (initialization_record, {multiple_requests_possible} TRUE, status);
        IFEND;
      IFEND;
    END /table_locked/;
    osp$clear_job_signature_lock (rmv$job_tape_table_lock);
    osp$end_subsystem_activity;
    osp$disestablish_cond_handler;

    IF status.normal THEN
      message_parameters [1] := ^element_name;
      message_parameters [2] := ^requested_evsn;
      message_parameters [3] := ^rmv$densities [initialization_record.density];
      message_parameters [4] := ^rmv$write_ring [requested_ring];
    ELSE
      RETURN;
    IFEND;

    osp$establish_condition_handler (^initialize_unit_handler, TRUE);

  /ensure_accessible_unit/
    REPEAT
      iop$tape_initialize_unit (sfid, ioid, status);
      IF status.normal THEN
        get_tape_status (sfid, ioid, iostatus, status);
        IF status.normal THEN
          IF iostatus.normal_completion THEN
            IF iostatus.unit_ready THEN
              IF iostatus.unit_busy THEN
                pmp$long_term_wait (one_second, one_second);
              ELSE
                IF (requested_ring = rmc$write_ring) AND NOT iostatus.write_ring THEN
                  IF volume_robotically_mounted THEN
                    rmp$log_debug_message (' Initialize unit found robotic unit not write enabled');
                    osp$set_status_condition (rme$robotic_write_disabled, status);
                  ELSE
                    ensure_unit_write_enabled (sfid, message_parameters, tusl_ordinal, status);
                  IFEND;
                IFEND;
                IF status.normal THEN

                /store_tape_characteristics/
                  BEGIN
                    debug_message_logged := FALSE;
                    REPEAT
                      IF NOT debug_message_logged THEN
                        rmp$log_debug_message (' Calling iop$access_tusl_entry');
                      IFEND;
                      tusl_entry_access.operation := ioc$store_tape_characteristics;
                      tusl_entry_access.store_write_ring := iostatus.write_ring;
                      tusl_entry_access.store_density :=
                            dmv$tape_job_lun_table_p^.tape_file^ [sfid.file_entry_index].density;
                      iop$access_tusl_entry (tusl_ordinal, tusl_entry_access, local_status);
                      IF NOT local_status.normal THEN
                        IF local_status.condition = dme$unable_to_lock_tape_table THEN
                          IF NOT debug_message_logged THEN
                            rmp$log_debug_message (' Waiting for tape table lock');
                            debug_message_logged := TRUE;
                          IFEND;
                          pmp$long_term_wait (one_second, one_second);
                        ELSE
                          EXIT /store_tape_characteristics/;
                        IFEND;
                      IFEND;
                    UNTIL local_status.normal;
                  END /store_tape_characteristics/;

                  emit_job_log_message (sfid, element_name, recovery_remount, requested_ring);
                  EXIT /ensure_accessible_unit/;
                IFEND;
              IFEND;
            ELSE {unit not ready}
              IF volume_robotically_mounted THEN
                rmp$log_debug_message (' Initialize unit found robotic unit not ready');
                osp$set_status_condition (dme$operator_reassign, status);
                last_choice_element := element_name;
              ELSE
                ensure_unit_ready (sfid, message_parameters, tusl_ordinal, status);
              IFEND;
            IFEND;
          ELSE {unit inoperable}
            IF volume_robotically_mounted THEN
              rmp$log_debug_message (' Initialize unit found robotic unit not operational');
              osp$set_status_condition (dme$operator_reassign, status);
              last_choice_element := element_name;
            ELSE
              ensure_unit_operational (sfid, message_parameters, tusl_ordinal, status);
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    UNTIL NOT status.normal;

    osp$disestablish_cond_handler;

    emit_security_statistic (element_name);

    IF (NOT status.normal) THEN
      CASE status.condition OF
      = ame$improper_file_label_type =
        IF dmv$initialize_tape_volume.in_progress THEN
          rmp$log_debug_message ('Ignoring ame$improper_file_label_type due to INITV');
          rmp$log_debug_status (status);
          status.normal := TRUE;
        ELSE
          abnormal_cleanup ({retain_volume_and_reservation} FALSE);
        IFEND;
      = dme$operator_reassign =
        abnormal_cleanup ({retain_volume_and_reservation} TRUE);
      = rme$robotic_write_disabled =
        abnormal_cleanup ({retain_volume_and_reservation} TRUE);
        {Allow operator the choice of ejecting cartridge & write-enabling it.}
        robotic_write_disabled_menu (message_parameters, status);
      ELSE
        abnormal_cleanup ({retain_volume_and_reservation} FALSE);
      CASEND;
    IFEND;
    rmp$log_debug_message (' Exiting Initialize_unit');
    rmp$log_debug_status (status);

  PROCEND initialize_unit;
?? OLDTITLE ??

MODEND dmm$create_tape_file;
