?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE CM : Job Template Configuration' ??
MODULE cmm$configure_in_job_template;

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$job_paged_literal
*copyc oss$task_private
*copyc clc$standard_file_names
*copyc cmc$logical_unit_constants
*copyc rmc$mass_storage_class
*copyc cme$job_template_deadstart
*copyc cme$logical_configuration_mgr
*copyc cme$logical_configuration_utl
*copyc cme$manage_interface_tables
*copyc cme$physical_configuration_utl
*copyc mme$condition_codes
*copyc ste$error_condition_codes
*copyc clt$file
*copyc cmt$element_definition
*copyc cmt$mass_storage_volume
*copyc cmt$physical_configuration
*copyc dmt$error_condition_codes
*copyc dmt$initialize_status_info
*copyc dpt$critical_window_date_time
*copyc dst$iou_number
?? POP ??
*copyc amp$close
*copyc amp$fetch_access_information
*copyc amp$file
*copyc amp$get_next
*copyc amp$get_segment_pointer
*copyc amp$open
*copyc amp$put_next
*copyc amp$return
*copyc amp$rewind
*copyc amp$set_segment_eoi
*copyc amp$set_segment_position
*copyc clp$begin_utility
*copyc clp$convert_integer_to_string
*copyc clp$convert_to_clt$status
*copyc clp$create_variable
*copyc clp$end_scan_command_file
*copyc clp$end_utility
*copyc clp$evaluate_parameters
*copyc clp$include_line
*copyc clp$put_job_output
*copyc clp$read_variable
*copyc clp$scan_command_line
*copyc clp$trimmed_string_size
*copyc clp$write_variable
*copyc cmp$acquire_all_peripherals_r1
*copyc cmp$assign_logical_unit_numbers
*copyc cmp$build_pct
*copyc cmp$build_state_table
*copyc cmp$close_utility_files
*copyc cmp$convert_channel_number
*copyc cmp$convert_iou_number
*copyc cmp$define_element
*copyc cmp$define_working_mainframe
*copyc cmp$edit_pc
*copyc cmp$find_state_element
*copyc cmp$get_channel_definition
*copyc cmp$get_conf_file
*copyc cmp$get_controller_type
*copyc cmp$get_element_state
*copyc cmp$get_element_state_via_lun
*copyc cmp$get_mass_storage_info
*copyc cmp$get_ms_status_via_lun
*copyc cmp$get_system_device_path
*copyc cmp$get_unit_type
*copyc cmp$install_conf_file
*copyc cmp$install_phys_configuration
*copyc cmp$known_controller_id
*copyc cmp$open_utility_files
*copyc cmp$pc_get_logical_unit
*copyc cmp$process_state_change
*copyc cmp$prompt_for_answer
*copyc cmp$return_configuration_limits
*copyc cmp$set_default_mainframe_name
*copyc cmp$valid_channel_name
*copyc cmp$verify_active_path
*copyc cmp$verify_phys_configuration
*copyc dmp$get_volumes_active
*copyc dsp$retrieve_iou_information
*copyc jmp$system_job
*copyc ofp$receive_operator_response
*copyc ofp$send_operator_message
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$generate_error_message
*copyc osp$get_status_condition_name
*copyc osp$set_status_abnormal
*copyc pfp$define
*copyc pfp$define_catalog
*copyc pfp$log_error
*copyc pfp$purge
*copyc pmp$generate_unique_name
*copyc pmp$get_date
*copyc pmp$get_job_mode
*copyc pmp$get_mainframe_id
*copyc pmp$get_time
*copyc pmp$get_unique_name
*copyc pmp$log_ascii
*copyc stp$get_active_set_list
*copyc stp$get_volumes_in_set
*copyc stp$get_volumes_set_name
*copyc stp$is_volume_in_set
*copyc stp$r2_remove_inactive_member
*copyc stp$remove_inactive_members
*copyc stp$remove_member_vol_from_set
*copyc stp$search_ast_by_set
*copyc stp$verify_all_volumes_active
*copyc syp$display_deadstart_message
*copyc syp$process_deadstart_status
*copyc syp$trace_deadstart_message
?? EJECT ??
*copyc cmv$new_logical_unit_table
*copyc cmv$post_deadstart
*copyc cmv$system_device_data
*copyc dmv$active_volume_table
*copyc osv$deadstart_phase
*copyc osv$recover_system_set_phase
*copyc syv$detailed_critical_displays
*copyc stv$system_set_name
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

{ table pcu_command_list t=c s=local sn=oss$job_paged_literal
{ command (define_working_mainframe       ,defwm) cmp$define_working_mainframe  cm=local
{ command (define_element                 ,defe)  cmp$define_element cm=local
{ command (verify_physical_configuration  ,verpc) cmp$verify_phys_configuration  cm=local
{ command (install_physical_configuration ,inspc) cmp$install_phys_configuration cm=local
{ command (edit_physical_configuration    ,edipc) cmp$edit_pc cm=local
{ command (quit                           ,qui)   quit cm=local
{ tablend

?? PUSH (LISTEXT := ON) ??
VAR
  pcu_command_list: [STATIC, READ, oss$job_paged_literal] ^clt$command_table := ^pcu_command_list_entries,
  pcu_command_list_entries: [STATIC, READ, oss$job_paged_literal] array [1 .. 12] of
      clt$command_table_entry := [
  {} ['DEFE                           ', clc$abbreviation_entry, clc$normal_usage_entry, 2,
        clc$automatically_log, clc$linked_call, ^cmp$define_element],
  {} ['DEFINE_ELEMENT                 ', clc$nominal_entry, clc$normal_usage_entry, 2,
        clc$automatically_log, clc$linked_call, ^cmp$define_element],
  {} ['DEFINE_WORKING_MAINFRAME       ', clc$nominal_entry, clc$normal_usage_entry, 1,
        clc$automatically_log, clc$linked_call, ^cmp$define_working_mainframe],
  {} ['DEFWM                          ', clc$abbreviation_entry, clc$normal_usage_entry, 1,
        clc$automatically_log, clc$linked_call, ^cmp$define_working_mainframe],
  {} ['EDIPC                          ', clc$abbreviation_entry, clc$normal_usage_entry, 5,
        clc$automatically_log, clc$linked_call, ^cmp$edit_pc],
  {} ['EDIT_PHYSICAL_CONFIGURATION    ', clc$nominal_entry, clc$normal_usage_entry, 5,
        clc$automatically_log, clc$linked_call, ^cmp$edit_pc],
  {} ['INSPC                          ', clc$abbreviation_entry, clc$normal_usage_entry, 4,
        clc$automatically_log, clc$linked_call, ^cmp$install_phys_configuration],
  {} ['INSTALL_PHYSICAL_CONFIGURATION ', clc$nominal_entry, clc$normal_usage_entry, 4,
        clc$automatically_log, clc$linked_call, ^cmp$install_phys_configuration],
  {} ['QUI                            ', clc$abbreviation_entry, clc$normal_usage_entry, 6,
        clc$automatically_log, clc$linked_call, ^quit],
  {} ['QUIT                           ', clc$nominal_entry, clc$normal_usage_entry, 6,
        clc$automatically_log, clc$linked_call, ^quit],
  {} ['VERIFY_PHYSICAL_CONFIGURATION  ', clc$nominal_entry, clc$normal_usage_entry, 3,
        clc$automatically_log, clc$linked_call, ^cmp$verify_phys_configuration],
  {} ['VERPC                          ', clc$abbreviation_entry, clc$normal_usage_entry, 3,
        clc$automatically_log, clc$linked_call, ^cmp$verify_phys_configuration]];
?? POP ??

  VAR
    cmv$create_state_info_df: [XDCL, oss$task_private] boolean := FALSE,
    cmv$installed_mainframe: [XREF] cmt$element_name,
    cmv$use_installed_configuration: [XREF] boolean,
    osv$configuration_prolog_name: [XREF] ost$string,
    osv$verify_missing_volumes: [XREF] boolean,

    v$low_cycle: [READ, oss$job_paged_literal] pft$cycle_selector := [pfc$lowest_cycle],
    v$pf_cycle: [READ, oss$job_paged_literal] pft$cycle_selector := [pfc$highest_cycle];

?? OLDTITLE ??
?? NEWTITLE := 'GET_VOLUME_MS_CLASS', EJECT ??
{ PURPOSE:
{   This procedure locates the specifed recorded vsn in the active volume table
{   and returns the the mass storage class information if the volume is active.
{   If the volume does not exist or is unavailable an empty set will be returned.

  PROCEDURE get_volume_ms_class
    (    recorded_vsn: rmt$recorded_vsn;
     VAR volume_ms_class: dmt$class);

    VAR
      avt_index: integer,
      entry_p: ^dmt$active_volume_table_entry,
      element_status: iot$unit_status,
      state: cmt$element_state;

    volume_ms_class := $dmt$class [];

  /avt_loop/
    FOR avt_index := LOWERBOUND (dmv$active_volume_table.table_p^)
          TO UPPERBOUND (dmv$active_volume_table.table_p^) DO
      entry_p := ^dmv$active_volume_table.table_p^ [avt_index];
      IF entry_p^.entry_available OR (entry_p^.mass_storage.recorded_vsn <> recorded_vsn) THEN
        CYCLE /avt_loop/; {----->
      ELSEIF NOT entry_p^.mass_storage.allocation_allowed THEN
        EXIT /avt_loop/; {----->
      IFEND;

      cmp$get_element_state_via_lun (entry_p^.logical_unit_number, state);
      IF state <> cmc$on THEN
        EXIT /avt_loop/; {----->
      IFEND;

      cmp$get_ms_status_via_lun (entry_p^.logical_unit_number, element_status);
      IF element_status.disabled THEN
        EXIT /avt_loop/; {----->
      IFEND;

      volume_ms_class := entry_p^.mass_storage.class;
      EXIT /avt_loop/; {----->
    FOREND /avt_loop/;

  PROCEND get_volume_ms_class;
?? OLDTITLE ??
?? NEWTITLE := 'initialize_cm_variables', EJECT ??

{ PURPOSE:
{   This procedure creates and initializes a certain number of SCL variables that will be referenced by the
{   SYSTEM_DEADSTART_PROLOG.

  PROCEDURE initialize_cm_variables;

    CONST
      c$warning_message = 'WARNING -- The following error was found while creating variables:';

    TYPE
      t$variable_data = RECORD
        CASE boolean OF
        = TRUE =
          size: ost$string_size,
          value: ost$name,
        = FALSE =
          data: ARRAY [1 .. (2 + osc$max_name_size)] OF cell,
        CASEND,
      RECEND;

    VAR
      local_status: ost$status,
      phase_scope: clt$variable_scope,
      variable_data: t$variable_data,
      variable_value: clt$variable_reference;

    phase_scope.kind := clc$job_variable;

    clp$create_variable ('OSV$CONFIGURATION_PROLOG_NAME', clc$string_value, osc$max_name_size, 1, 1,
          phase_scope, variable_value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;
    variable_data.size := osv$configuration_prolog_name.size;
    variable_data.value := osv$configuration_prolog_name.value;
    variable_value.value.string_value := ^variable_data.data;
    clp$write_variable ('OSV$CONFIGURATION_PROLOG_NAME', variable_value.value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('OSV$SITE_CONFIGURATION_FILE', clc$string_value, osc$max_name_size, 1, 1,
          phase_scope, variable_value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;
    variable_data.size := 18;
    variable_data.value := 'SITE_CONFIGURATION';
    variable_value.value.string_value := ^variable_data.data;
    clp$write_variable ('OSV$SITE_CONFIGURATION_FILE', variable_value.value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('CMV$CONFIGURATION_ACTIVATED', clc$boolean_value, osc$max_name_size, 1, 1,
          phase_scope, variable_value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('CMV$FORCE_INTERVENTION', clc$boolean_value, 0, 1, 1, phase_scope, variable_value,
          local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('CMV$NETWORK_ACTIVATED', clc$boolean_value, 0, 1, 1, phase_scope, variable_value,
          local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('CMV$PCU_STATUS', clc$status_value, 0, 1, 1, phase_scope, variable_value,
          local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

    clp$create_variable ('CMV$DEVICE_FILE_COPY_STATUS', clc$status_value, 0, 1, 1, phase_scope,
          variable_value, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (c$warning_message, FALSE, local_status);
    IFEND;

  PROCEND initialize_cm_variables;
?? OLDTITLE ??
?? NEWTITLE := 'prepare_configuration_file', EJECT ??

{ PURPOSE:
{   This procedure builds a text file containing the DEFINE_ELEMENT commands for the system/deadstart
{   devices. This file is used by the SYSTEM_DEADSTART_PROLOG if an unconfigured deadstart tape is used.

  PROCEDURE prepare_configuration_file
    (    file_identifier: amt$file_identifier);

    VAR
      byte_address: amt$file_byte_address,
      cm_unit_type: cmt$unit_type,
      count: 1 .. 2,
      device: cmt$system_device_types,
      found: boolean,
      index: 1 .. 4,
      integer_string: ost$string,
      io_unit_type: iot$unit_type,
      iou_name: cmt$element_name,
      line: string (osc$max_string_size),
      local_status: ost$status,
      mainframe_id: pmt$mainframe_id,
      unit_class: cmt$unit_class;

    { Prepare the file with information from the system device data variable.

    pmp$get_mainframe_id (mainframe_id, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (' ', FALSE, local_status);
      RETURN;
    IFEND;

    line := ' ';
    line (1, 25) := 'DEFINE_WORKING_MAINFRAME ';
    line (26, *) := mainframe_id;
    amp$put_next (file_identifier, ^line, #SIZE (line), byte_address, local_status);
    IF NOT local_status.normal THEN
      syp$process_deadstart_status (' ', FALSE, local_status);
      RETURN;
    IFEND;

    cmp$get_unit_type (cmv$system_device_data [cmc$sdt_disk_device].unit_id, cm_unit_type, io_unit_type,
          unit_class, found);
    IF NOT found THEN
      RETURN;
    IFEND;

    device := cmc$sdt_disk_device;
    IF cmv$system_device_data [cmc$sdt_tape_device].specified THEN
      count := 2;
    ELSE
      count := 1;
    IFEND;

    FOR index := 1 TO count DO
      line := ' ';
      line (1, 14) := 'DEFINE_ELEMENT';
      line (15, 3) := ' E=';
      line (18, 21) := cmv$system_device_data [device].unit_name;
      line (39, 4) := ' EI=';
      line (43, 6) := cmv$system_device_data [device].unit_id.product_number;
      line (49, 1) := cmv$system_device_data [device].unit_id.underscore;
      line (50, 3) := cmv$system_device_data [device].unit_id.model_number;
      line (53, 4) := ' SN=';
      clp$convert_integer_to_string (index, 10, FALSE, integer_string, local_status);
      line (57, 1) := integer_string.value;
      line (58, 8) := ' S=ON ..';
      amp$put_next (file_identifier, ^line, #SIZE (line), byte_address, local_status);
      IF NOT local_status.normal THEN
        syp$process_deadstart_status (' ', FALSE, local_status);
        RETURN;
      IFEND;

      line := ' ';
      IF (cm_unit_type = cmc$mshydra) AND (device = cmc$sdt_disk_device) THEN
        line (1, 6) := ' IC=((';
        line (7, 6) := cmv$system_device_data [device].channel_name;
        line (13, 1) := ' ';
        clp$convert_integer_to_string (cmv$system_device_data [device].unit_number, 10, FALSE,
              integer_string, local_status);
        line (14, 3) := integer_string.value (1, 3);
        line (17, 1) := ' ';
        line (18, 31) := mainframe_id;
        line (49, 1) := ' ';
        cmp$convert_iou_number (cmv$system_device_data [device].iou_number, iou_name, local_status);
        line (50, 5) := iou_name (1, 5);
        line (55, 3) := ')) ';
      ELSE
        line (1, 6) := ' PC=((';
        line (7, 21) := cmv$system_device_data [device].equipment_name;
        line (28, 1) := ' ';
        clp$convert_integer_to_string (cmv$system_device_data [device].unit_number, 10, FALSE,
              integer_string, local_status);
        line (29, 3) := integer_string.value (1, 3);
        line (32, 3) := ')) ';
      IFEND;
      amp$put_next (file_identifier, ^line, #SIZE (line), byte_address, local_status);
      IF NOT local_status.normal THEN
        syp$process_deadstart_status (' ', FALSE, local_status);
        RETURN;
      IFEND;
      device := cmc$sdt_tape_device;
    FOREND;

    device := cmc$sdt_disk_device;
    FOR index := 3 TO 4 DO

      { If ISD or 895 or HYDRA disk device, need to build channel adapter, head of string controller etc.

      line := ' ';
      IF (cm_unit_type <> cmc$mshydra) OR (device <> cmc$sdt_disk_device) THEN
        line (1, 14) := 'DEFINE_ELEMENT';
        line (15, 3) := ' E=';
        line (18, 21) := cmv$system_device_data [device].equipment_name;
        line (39, 4) := ' EI=';
        line (43, 6) := cmv$system_device_data [device].equipment_id.product_number;
        line (49, 1) := cmv$system_device_data [device].equipment_id.underscore;
        line (50, 3) := cmv$system_device_data [device].equipment_id.model_number;
        line (53, 4) := ' SN=';
        clp$convert_integer_to_string (index, 10, FALSE, integer_string, local_status);
        line (57, 1) := integer_string.value;
        line (58, 8) := ' S=ON ..';
        amp$put_next (file_identifier, ^line, #SIZE (line), byte_address, local_status);
        IF NOT local_status.normal THEN
          syp$process_deadstart_status (' ', FALSE, local_status);
          RETURN;
        IFEND;

        line := ' ';
        line (1, 6) := ' IC=((';
        line (7, 6) := cmv$system_device_data [device].channel_name;
        line (13, 1) := ' ';
        clp$convert_integer_to_string (cmv$system_device_data [device].equipment_number, 10, FALSE,
              integer_string, local_status);
        line (14, 3) := integer_string.value (1, 3);
        line (17, 1) := ' ';
        line (18, 31) := mainframe_id;
        line (49, 1) := ' ';
        cmp$convert_iou_number (cmv$system_device_data [device].iou_number, iou_name, local_status);
        line (50, 5) := iou_name (1, 5);
        line (55, 3) := ')) ';
        amp$put_next (file_identifier, ^line, #SIZE (line), byte_address, local_status);
        IF NOT local_status.normal THEN
          syp$process_deadstart_status (' ', FALSE, local_status);
          RETURN;
        IFEND;
      IFEND;
      device := cmc$sdt_tape_device;
    FOREND;

  PROCEND prepare_configuration_file;
?? OLDTITLE ??
?? NEWTITLE := 'press_next', EJECT ??

{ PURPOSE:
{   This procedure issues a message and waits for CARRIAGE RETURN to be entered.

  PROCEDURE press_next;

    VAR
      byte_address: amt$file_byte_address,
      file_position: amt$file_position,
      input_fid: amt$file_identifier,
      line: string (80),
      status: ost$status,
      transfer_count: amt$transfer_count;

    clp$put_job_output (' Press RETURN/NEXT when ready to continue', status);
    amp$open (clc$job_input, amc$record, NIL, input_fid, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    amp$get_next (input_fid, ^line, #SIZE (line), transfer_count, byte_address, file_position, status);

  PROCEND press_next;
?? OLDTITLE ??
?? NEWTITLE := 'quit', EJECT ??

{ PURPOSE:
{   Dummy procedure to quit physical_configuration_utility.

  PROCEDURE quit
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE quit_pcu_pdt (
{    )

?? PUSH (LISTEXT := ON) ??
    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
      recend := [[1, [88, 5, 13, 14, 30, 41, 383], clc$command, 0, 0, 0, 0, 0, 0, 0, 'QUIT_PCU_PDT']];
?? POP ??

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$end_scan_command_file ('PHYSICAL_CONFIGURATION_UTILITY ', status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    cmp$close_utility_files;

  PROCEND quit;
?? OLDTITLE ??
?? NEWTITLE := 'update_connectivity', EJECT ??

{ PURPOSE:
{   This procedure updates all the connections in the file: connected_lc_fid.  The file contains all of the
{   configuration information belonging to mainframe.  The file: state_info_fid is passed to allow retrieval
{   of state information about the deadstart and/or system device path(s).

  PROCEDURE update_connectivity
    (    connected_lc_fid: amt$file_identifier;
         state_info_fid: amt$file_identifier;
         mainframe: cmt$element_name;
     VAR status: ost$status);

    VAR
      channel_element_p: ^cmt$element_definition,
      channel_name: cmt$element_name,
      channel_port: cmt$channel_port,
      channel_type: cmt$channel_kind,
      char_to_check: char,
      configuration_limits: cmt$configuration_limits,
      controller_type: cmt$controller_type,
      done_checking: boolean,
      dspn: cmt$data_storage_port_number,
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      element_p: ^cmt$element_definition,
      iou_information_table: dst$iou_information_table,
      iou_name: cmt$element_name,
      last_channel_port: cmt$channel_port,
      lc_element_p: ^cmt$element_definition,
      lc_count: integer,
      lc_index: integer,
      lc_seg: amt$segment_pointer,
      local_status: ost$status,
      number_of_ious: dst$number_of_ious,
      number_of_units_defined: integer,
      pid : string (10),
      pen: cmt$physical_equipment_number,
      product_found: boolean,
      product_number: cmt$product_number,
      pun: cmt$physical_unit_number,
      starting_channel_name: cmt$element_name,
      string_index: 0 .. osc$max_name_size,
      unit_element_p: ^cmt$element_definition;

    status.normal := TRUE;

    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (connected_lc_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
      RETURN;
    IFEND;
    IF (eoi_addr [1].eoi_byte_address MOD #SIZE (cmt$element_definition)) <> 0 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_incompatible_lc, ' ', status);
      RETURN;
    IFEND;
    lc_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);

    { Get the segment pointer.

    amp$get_segment_pointer (connected_lc_fid, amc$sequence_pointer, lc_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET lc_seg.sequence_pointer;

    dsp$retrieve_iou_information (number_of_ious, iou_information_table);

   /search_element_loop/
    FOR lc_index := 1 TO lc_count DO
      NEXT lc_element_p IN lc_seg.sequence_pointer;
      IF lc_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;

      CASE lc_element_p^.element_type OF
      = cmc$data_channel_element =
        IF ((lc_element_p^.data_channel.number >= 12) AND (lc_element_p^.data_channel.number <= 15)) OR
              (lc_element_p^.data_channel.concurrent AND (lc_element_p^.data_channel.number > 25)) THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_unsupported_channel,
                lc_element_p^.element_name, status);
          RETURN;
        IFEND;
        product_number := ' ';

       /channel_forloop/
        FOR pen := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
          IF NOT lc_element_p^.data_channel.connection.equipment [pen].configured THEN
            CYCLE /channel_forloop/;
          IFEND;
          cmp$find_element (lc_element_p^.data_channel.connection.equipment [pen].element_name,
                {not used} iou_name, osc$null_name, connected_lc_fid, element_p, local_status);
          IF NOT local_status.normal THEN
            lc_element_p^.data_channel.connection.equipment [pen].configured := FALSE;
            CYCLE /channel_forloop/;
          IFEND;

          IF product_number = ' ' THEN
            product_number := element_p^.product_id.product_number;
          ELSE
            IF product_number <> element_p^.product_id.product_number THEN
              osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_mixture_of_product,
                    lc_element_p^.element_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter, product_number, status);
              osp$append_status_parameter (osc$status_parameter_delimiter,
                    element_p^.product_id.product_number, status);
              RETURN;
            IFEND;
          IFEND;

          IF NOT lc_element_p^.data_channel.concurrent THEN
            CYCLE /channel_forloop/;
          IFEND;

          { Make sure that the concurrent channel is properly defined with or without port depending on the
          { product.

          IF lc_element_p^.data_channel.port = cmc$unspecified_port THEN
            channel_type := cmc$cio_channel_no_port;
          ELSE
            channel_type := cmc$cio_channel_2_port;
          IFEND;

          IF element_p^.element_type = cmc$controller_element THEN

           /find_unit/
            FOR pun := LOWERVALUE (cmt$physical_unit_number) TO UPPERVALUE (cmt$physical_unit_number) DO
              IF NOT element_p^.controller.connection.unit [pun].configured THEN
                CYCLE /find_unit/;
              IFEND;
              cmp$find_element (element_p^.controller.connection.unit [pun].element_name,
                    {not used} iou_name, osc$null_name, connected_lc_fid, unit_element_p, local_status);
              IF NOT local_status.normal THEN
                CYCLE /find_unit/;
              IFEND;
              cmp$return_configuration_limits (unit_element_p^.product_id.product_number,
                    configuration_limits, product_found);
              IF NOT product_found THEN
                CYCLE /find_unit/;
              IFEND;
              IF mainframe = cmv$installed_mainframe THEN
                IF NOT (channel_type IN configuration_limits.allowed_channels) THEN
                  osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_improper_channel_usage,
                        unit_element_p^.element_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, lc_element_p^.element_name,
                        status);
                  RETURN;
                IFEND;
              IFEND;
              IF NOT (iou_information_table [1].model_type IN configuration_limits.allowed_ious) THEN
                osp$set_status_abnormal (cmc$configuration_management_id, cme$device_not_allowed_on_iou, '',
                      status);
                RETURN;
              IFEND;

              { Special case: Because $698_3x tape units can be connected to both 5698 and 698 tape
              { controller, check to make sure that the correct channel is used.

              IF mainframe = cmv$installed_mainframe THEN
                IF ((element_p^.product_id.product_number = '  $698') AND
                      (channel_type = cmc$cio_channel_2_port)) OR
                      ((element_p^.product_id.product_number = ' $5698') AND
                      (channel_type = cmc$cio_channel_no_port)) THEN
                  osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_improper_channel_usage,
                        unit_element_p^.element_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, lc_element_p^.element_name,
                        status);
                  RETURN;
                IFEND;
              IFEND;
              EXIT /find_unit/; { Only need to check first unit on the channel.
            FOREND /find_unit/;

          ELSEIF element_p^.element_type = cmc$storage_device_element THEN
            cmp$return_configuration_limits (element_p^.product_id.product_number, configuration_limits,
                  product_found);
            IF product_found THEN
              IF mainframe = cmv$installed_mainframe THEN
                IF NOT (channel_type IN configuration_limits.allowed_channels) THEN
                  osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_improper_channel_usage,
                        element_p^.element_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, lc_element_p^.element_name,
                        status);
                  RETURN;
                IFEND;
              IFEND;
              IF NOT (iou_information_table [1].model_type IN configuration_limits.allowed_ious) THEN
                osp$set_status_abnormal (cmc$configuration_management_id, cme$device_not_allowed_on_iou, '',
                      status);
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        FOREND /channel_forloop/;

        IF NOT lc_element_p^.data_channel.concurrent THEN
          CYCLE /search_element_loop/;
        IFEND;

        { See if there is any other CIO channel with or without port and validate subsystem configured on
        { these channels.

        channel_name := lc_element_p^.element_name;
        IF lc_element_p^.data_channel.port = cmc$unspecified_port THEN
          char_to_check := ' ';
          channel_port := cmc$port_a;
          last_channel_port := cmc$port_b;
        ELSEIF lc_element_p^.data_channel.port = cmc$port_a THEN
          char_to_check := 'A';
          channel_port := cmc$unspecified_port;
          last_channel_port := cmc$port_b;
        ELSE
          char_to_check := 'B';
          channel_port := cmc$unspecified_port;
          last_channel_port := cmc$port_a;
        IFEND;
        done_checking := FALSE;
        starting_channel_name := channel_name;

        WHILE NOT done_checking DO
          string_index := 1;
          WHILE (string_index <= osc$max_name_size) AND (channel_name (string_index, 1) <> char_to_check) DO
            string_index := string_index + 1;
          WHILEND;
          IF channel_port = cmc$port_a THEN
            channel_name (string_index, 1) := 'A';
          ELSEIF channel_port = cmc$port_b THEN
            channel_name (string_index, 1) := 'B';
          ELSE
            channel_name (string_index, 1) := ' ';
          IFEND;
          cmp$find_element (channel_name, lc_element_p^.data_channel.iou,
                lc_element_p^.data_channel.mainframe_ownership, connected_lc_fid, channel_element_p,
                local_status);
          IF local_status.normal THEN
            FOR pen := LOWERVALUE (cmt$physical_equipment_number) TO
                  UPPERVALUE (cmt$physical_equipment_number) DO
              IF channel_element_p^.data_channel.connection.equipment [pen].configured THEN
                cmp$find_element (channel_element_p^.data_channel.connection.equipment [pen].element_name,
                      {not used} iou_name, osc$null_name, connected_lc_fid, element_p, local_status);
                IF local_status.normal AND (product_number <> element_p^.product_id.product_number) THEN
                  osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_mixture_of_product,
                        lc_element_p^.element_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, product_number, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        element_p^.product_id.product_number, status);
                  RETURN;
                IFEND;
              IFEND;
            FOREND;
          IFEND;
          done_checking := (channel_port = last_channel_port);
          channel_name := starting_channel_name;
          channel_port := last_channel_port;
        WHILEND;

      = cmc$controller_element =
        number_of_units_defined := 0;

        { Upline connections of controller can have multiple mainframe references.  Check the down_line
        { connections.

        FOR pun := LOWERVALUE (cmt$physical_unit_number) TO UPPERVALUE (cmt$physical_unit_number) DO
          IF lc_element_p^.controller.connection.unit [pun].configured THEN
            number_of_units_defined := number_of_units_defined + 1;
            cmp$find_element (lc_element_p^.controller.connection.unit [pun].element_name,
                  {not used} iou_name, osc$null_name, connected_lc_fid, element_p, local_status);
            IF NOT local_status.normal THEN
              lc_element_p^.controller.connection.unit [pun].configured := FALSE;
            IFEND;
          IFEND;
        FOREND;
        IF number_of_units_defined = 0 THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_invalid_connection,
                lc_element_p^.element_name, status);
          RETURN;
        IFEND;

      = cmc$storage_device_element =
        product_number := ' ';

        { Updates the upline connection of these storage device only to show connections to controller or
        { channel of the current mainframe.

       /storage_device_forloop/
        FOR dspn := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
          IF NOT lc_element_p^.storage_device.connection.port [dspn].configured THEN
            CYCLE /storage_device_forloop/;
          IFEND;
          IF lc_element_p^.storage_device.connection.port [dspn].upline_connection_type =
                cmc$data_channel_element THEN
            iou_name := lc_element_p^.storage_device.connection.port [dspn].iou;
          IFEND;
          cmp$find_element (lc_element_p^.storage_device.connection.port [dspn].element_name, iou_name,
                mainframe, connected_lc_fid, element_p, local_status);
          IF NOT local_status.normal THEN
            lc_element_p^.storage_device.connection.port [dspn].configured := FALSE;
            CYCLE /storage_device_forloop/;
          IFEND;

          { Validates the proper type of controller is being used for this storage device element_p.

          cmp$return_configuration_limits (lc_element_p^.product_id.product_number, configuration_limits,
                product_found);
          IF NOT product_found OR (element_p^.element_type <> cmc$controller_element) THEN
            CYCLE /storage_device_forloop/;
          IFEND;

          cmp$get_controller_type (element_p^.product_id, controller_type, local_status);
          IF local_status.normal AND NOT (controller_type IN configuration_limits.allowed_controllers) THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_mixture_of_product,
                  lc_element_p^.element_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter,
                  lc_element_p^.product_id.product_number, status);
            osp$append_status_parameter (osc$status_parameter_delimiter,
                  element_p^.product_id.product_number, status);
            RETURN;
          IFEND;
          IF NOT (iou_information_table [1].model_type IN configuration_limits.allowed_ious) THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$device_not_allowed_on_iou, '',
                  status);
            RETURN;
          IFEND;

          { Validates that all products connected to the storage device are the same.

          IF product_number = ' ' THEN
            product_number := element_p^.product_id.product_number;
          ELSE
            IF (product_number <> element_p^.product_id.product_number) AND
                  NOT ((product_number = ' $7154') OR (product_number = ' $7155')) AND
                  NOT ((element_p^.product_id.product_number = ' $7154') OR
                  (element_p^.product_id.product_number = ' $7155')) THEN
              osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_mixture_of_product,
                    lc_element_p^.element_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter, product_number, status);
              osp$append_status_parameter (osc$status_parameter_delimiter,
                    element_p^.product_id.product_number, status);
              RETURN;
            IFEND;
          IFEND;
        FOREND /storage_device_forloop/;

      = cmc$channel_adapter_element, cmc$external_processor_element, cmc$communications_element =

        { These element type could have multiple mainframes on the upline connections, do nothing.

      ELSE
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_unexpected_element_type,
              lc_element_p^.element_name, status);
        pid (1, 6) := lc_element_p^.product_id.product_number;
        pid (7, 1) := lc_element_p^.product_id.underscore;
        pid (8, 3) := lc_element_p^.product_id.model_number;
        osp$append_status_parameter (osc$status_parameter_delimiter, pid, status);
      CASEND;
    FOREND /search_element_loop/;

    IF mainframe <> cmv$installed_mainframe THEN
      RETURN;
    IFEND;

    { Check for presence of system device and Deadstart device.

    validate_system_device_path (connected_lc_fid, state_info_fid, cmc$sdt_disk_device, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF cmv$system_device_data [cmc$sdt_tape_device].specified THEN
      validate_system_device_path (connected_lc_fid, state_info_fid, cmc$sdt_tape_device, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

  PROCEND update_connectivity;
?? OLDTITLE ??
?? NEWTITLE := 'validate_foreign_devices', EJECT ??

{ PURPOSE:
{   This procedure makes a pass through the configuration file and reclassifies all foreign devices
{   accordingly as Controller or Storage Device.

  PROCEDURE validate_foreign_devices
    (    connected_lc_fid: amt$file_identifier;
         state_info_fid: amt$file_identifier;
     VAR status: ost$status);

    VAR
      element_ok: boolean,
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      lc_count: integer,
      lc_element_p: ^cmt$element_definition,
      lc_index: integer,
      lc_seg: amt$segment_pointer,
      pun: cmt$physical_unit_number,
      state_element_p: ^cmt$state_information,
      state_segment_pointer: amt$segment_pointer,
      temp_element: cmt$element_definition;

    status.normal := TRUE;
    element_ok := TRUE;

    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (connected_lc_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF (eoi_addr [1].eoi_byte_address MOD #SIZE (cmt$element_definition)) <> 0 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_incompatible_lc, ' ', status);
      RETURN;
    IFEND;
    lc_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);

    amp$get_segment_pointer (connected_lc_fid, amc$sequence_pointer, lc_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    amp$get_segment_pointer (state_info_fid, amc$sequence_pointer, state_segment_pointer, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    RESET lc_seg.sequence_pointer;
    RESET state_segment_pointer.sequence_pointer;

    FOR lc_index := 1 TO lc_count DO
      NEXT lc_element_p IN lc_seg.sequence_pointer;
      IF lc_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;
      NEXT state_element_p IN state_segment_pointer.sequence_pointer;
      IF state_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;

      IF (lc_element_p^.element_type = cmc$controller_element) AND
            NOT cmp$known_controller_id (lc_element_p^.product_id) THEN
        element_ok := FALSE;

       /check_connection/
        FOR pun := LOWERVALUE (cmt$physical_unit_number) TO UPPERVALUE (cmt$physical_unit_number) DO
          IF lc_element_p^.controller.connection.unit [pun].configured THEN
            element_ok := TRUE;
            EXIT /check_connection/;
          IFEND;
        FOREND /check_connection/;

        IF NOT element_ok THEN
          temp_element.element_type := cmc$storage_device_element;
          temp_element.element_name := lc_element_p^.element_name;
          temp_element.serial_number := lc_element_p^.serial_number;
          temp_element.product_id := lc_element_p^.product_id;
          temp_element.storage_device.physical_unit_number :=
                lc_element_p^.controller.physical_equipment_number;
          temp_element.storage_device.connection.port := lc_element_p^.controller.connection.port;
          lc_element_p^ := temp_element;
          state_element_p^.element_type := cmc$storage_device_element;
        IFEND;
      IFEND;
    FOREND;

  PROCEND validate_foreign_devices;
?? OLDTITLE ??
?? NEWTITLE := 'validate_system_device_path', EJECT ??

{ PURPOSE:
{   This procedure validates the presence and the correct logical state of the system/deastart device in the
{   configuration file.

  PROCEDURE validate_system_device_path
    (    connected_list_fid: amt$file_identifier;
         state_info_fid: amt$file_identifier;
         device: cmt$system_device_types;
     VAR status: ost$status);

    VAR
      channel: cmt$physical_channel,
      channel_element_p: ^cmt$element_definition,
      channel_name: cmt$element_name,
      channel_ordinal: cmt$channel_ordinal,
      equipment_number: cmt$physical_equipment_number,
      equipment_name: cmt$element_name,
      element_p: ^cmt$element_definition,
      iou_name: cmt$element_name,
      state_element_p: ^cmt$state_information,
      text: string (255),
      unit_element_p: ^cmt$element_definition,
      unit_name: cmt$element_name,
      unit_number: cmt$physical_unit_number,
      valid: boolean;

    status.normal := TRUE;
    channel_name := ' ';
    equipment_name := ' ';
    unit_name := ' ';
    text := ' ';

    cmp$get_system_device_path (device, iou_name, channel, equipment_number, unit_number, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    cmp$convert_channel_number (channel.number, channel.concurrent, channel.port, channel_ordinal,
          channel_name, valid);
    IF NOT valid THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_channel_number,
            'Bad channel number encountered in validate_system_device_path', status);
      RETURN;
    IFEND;

   /determine_if_error/
    BEGIN
      cmp$find_element (channel_name, iou_name, cmv$installed_mainframe, connected_list_fid,
            channel_element_p, status);
      IF NOT status.normal OR (channel_element_p = NIL) THEN
        text (1, 49) := 'Unable to find system/deadstart device channel : ';
        text (50, *) := channel_name;
        EXIT /determine_if_error/;
      IFEND;

      IF channel_element_p^.data_channel.connection.equipment [equipment_number].configured THEN
        equipment_name :=
              channel_element_p^.data_channel.connection.equipment [equipment_number].element_name;
        cmp$find_element (equipment_name, {not used} iou_name, cmv$installed_mainframe, connected_list_fid,
              element_p, status);
        IF NOT status.normal OR (element_p = NIL) THEN
          text (1, 52) := 'Unable to find system/deadstart device controller: ';
          text (53, *) := equipment_name;
          EXIT /determine_if_error/;
        IFEND;
      ELSEIF channel_element_p^.data_channel.connection.equipment [unit_number].configured THEN
        unit_name := channel_element_p^.data_channel.connection.equipment [unit_number].element_name;
        cmp$find_element (unit_name, {not used} iou_name, cmv$installed_mainframe, connected_list_fid,
              element_p, status);
        IF NOT status.normal OR (element_p = NIL) THEN
          text (1, 42) := 'Unable to find system/deadstart device: ';
          text (43, *) := unit_name;
          EXIT /determine_if_error/;
        IFEND;
      ELSE
        text (1, 39) := 'Unable to find element connected to: ';
        text (40, *) := channel_name;
        EXIT /determine_if_error/;
      IFEND;

      IF element_p^.element_type = cmc$controller_element THEN
        IF NOT element_p^.controller.connection.unit [unit_number].configured THEN
          text (1, 54) := 'Unable to find system/deadstart device connected to : ';
          text (55, *) := equipment_name;
          EXIT /determine_if_error/;
        IFEND;
        unit_name := element_p^.controller.connection.unit [unit_number].element_name;
        cmp$find_element (unit_name, {not used} iou_name, cmv$installed_mainframe, connected_list_fid,
              unit_element_p, status);
        IF NOT status.normal OR (unit_element_p = NIL) THEN
          text (1, 41) := 'Unable to find system/deadstart device : ';
          text (42, *) := unit_name;
          EXIT /determine_if_error/;
        IFEND;
      ELSEIF element_p^.element_type = cmc$storage_device_element THEN
        IF unit_name = osc$null_name THEN
          unit_name := equipment_name;
        IFEND;
        IF element_p^.storage_device.physical_unit_number <> unit_number THEN
          text (1, 41) := 'Unable to find system/deadstart device : ';
          text (42, *) := unit_name;
          EXIT /determine_if_error/;
        IFEND;
      IFEND;

      IF equipment_name <> osc$null_name THEN
        cmp$find_state_element (equipment_name, {not used} iou_name, state_info_fid, state_element_p, status);
        IF NOT status.normal OR (state_element_p = NIL) THEN
          text := 'Unable to determine state of system device equipment.';
          EXIT /determine_if_error/;
        IFEND;
        IF state_element_p^.status.state <> cmc$on THEN
          text := 'System/deadstart controller is not in the ON state.';
          EXIT /determine_if_error/;
        IFEND;
      IFEND;

      cmp$find_state_element (unit_name, {not used} iou_name, state_info_fid, state_element_p, status);
      IF NOT status.normal OR (state_element_p = NIL) THEN
        text := 'Unable to determine state of system device unit.';
        EXIT /determine_if_error/;
      IFEND;
      IF state_element_p^.status.state <> cmc$on THEN
        text := 'System/deadstart device is not in the ON state.';
        EXIT /determine_if_error/;
      IFEND;
      RETURN;
    END /determine_if_error/;

    osp$set_status_abnormal (cmc$configuration_management_id, cme$lcu_sys_dev_path_not_found, iou_name,
          status);
    osp$append_status_parameter (osc$status_parameter_delimiter, channel_name, status);
    osp$append_status_integer (osc$status_parameter_delimiter, equipment_number, 10, TRUE, status);
    osp$append_status_integer (osc$status_parameter_delimiter, unit_number, 10, TRUE, status);
    osp$append_status_parameter (osc$status_parameter_delimiter, text, status);

  PROCEND validate_system_device_path;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$acquire_all_peripherals ',EJECT ??

{ PURPOSE:
{   This procedure determines how many IOU resources to be acquired, builds the I/O interface tables and
{   activates the full configuration.

  PROCEDURE [XDCL] cmp$acquire_all_peripherals
    (VAR status: ost$status);

    VAR
      intervention_array: ARRAY [1 .. 1] OF clt$boolean,
      intervention_variable: clt$variable_reference,
      iou_name: cmt$element_name,
      line: string (80),
      set_operator_intervention: boolean,
      state: cmt$element_state;

    status.normal := TRUE;

    cmp$acquire_all_peripherals_r1 (status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Check the state of the System/Deadstart device channel.  If it is not ON then allow operator
    { intervention in LCU to turn it back ON.

    set_operator_intervention := FALSE;
    line := ' ';

    IF cmv$system_device_data [cmc$sdt_tape_device].specified THEN
      cmp$convert_iou_number (cmv$system_device_data [cmc$sdt_tape_device].iou_number, iou_name, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      cmp$get_element_state (cmv$system_device_data [cmc$sdt_tape_device].channel_name, iou_name, state,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF state <> cmc$on THEN
        line (1, 28) := ' Deadstart device channel : ';
        line (29, 5) := iou_name (1, 5);
        line (35, 5) := cmv$system_device_data [cmc$sdt_tape_device].channel_name;
        line (41, *) := 'is not in the ON state.';
        syp$display_deadstart_message (line);
        syp$display_deadstart_message (' If this is the only channel to the deadstart device, you must use');
        syp$display_deadstart_message (' the LCU command CHANGE_ELEMENT_STATE to turn it ON.');
        set_operator_intervention := TRUE;
        press_next;
      IFEND;
    IFEND;

    cmp$convert_iou_number (cmv$system_device_data [cmc$sdt_disk_device].iou_number, iou_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    cmp$get_element_state (cmv$system_device_data [cmc$sdt_disk_device].channel_name, iou_name, state,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF state <> cmc$on THEN
      line := ' ';
      line (1, 25) := ' System device channel : ';
      line (27, 5) := iou_name (1, 5);
      line (34, 6) := cmv$system_device_data [cmc$sdt_disk_device].channel_name;
      line (42, *) := 'is not in the ON state.';
      syp$display_deadstart_message (line);
      syp$display_deadstart_message (' You may use the LCU command CHANGE_ELEMENT_STATE to turn it ON,');
      syp$display_deadstart_message (' if you have dual access.');
      set_operator_intervention := TRUE;
      press_next;
    IFEND;

    IF set_operator_intervention THEN
      intervention_array [1].value := TRUE;
      intervention_array [1].kind := clc$true_false_boolean;
      clp$read_variable ('CMV$FORCE_INTERVENTION', intervention_variable, status);
      intervention_variable.value.boolean_value := ^intervention_array;
      clp$write_variable ('CMV$FORCE_INTERVENTION', intervention_variable.value, status);
    IFEND;

  PROCEND cmp$acquire_all_peripherals;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$build_active_conf', EJECT ??

{ PURPOSE:
{   This procedure builds two files containing information for all peripherals belonging to the current
{   mainframe. It will discard all other mainframes' equipments.

  PROCEDURE [XDCL] cmp$build_active_conf
    (    connected_pc_fid: amt$file_identifier;
         connected_active_fid: amt$file_identifier;
         state_info_fid: amt$file_identifier;
         active_state_info_fid: amt$file_identifier;
         mainframe: cmt$element_name;
     VAR status: ost$status);

    TYPE
      t$tape_subsystem = RECORD
        dual_pp_present: boolean,
        dual_pp_name: cmt$element_name,
        single_pp_present: boolean,
        single_pp_name: cmt$element_name,
      RECEND;

    VAR
      active_state_element_p: ^cmt$state_information,
      active_state_info_seg: amt$segment_pointer,
      commpn: cmt$communications_port_number,
      connected_list_element_p: ^cmt$element_definition,
      connected_list_seg: amt$segment_pointer,
      connected_pc_count: integer,
      connected_pc_element_p: ^cmt$element_definition,
      connected_pc_index: integer,
      connected_pc_seg: amt$segment_pointer,
      controller_type: cmt$controller_type,
      cpn: cmt$controller_port_number,
      element_p: ^cmt$element_definition,
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      iou_name: cmt$element_name,
      lc_list_element_p: ^cmt$state_information,
      local_status: ost$status,
      mainframe_found: boolean,
      sd_port: cmt$data_storage_port_number,
      state_info_seg: amt$segment_pointer,
      tape_subsystem: t$tape_subsystem;

    status.normal := TRUE;
    mainframe_found := FALSE;
    tape_subsystem.dual_pp_present := FALSE;
    tape_subsystem.single_pp_present := FALSE;

    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (connected_pc_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
      RETURN;
    IFEND;

    IF (eoi_addr [1].eoi_byte_address MOD #SIZE (cmt$element_definition)) <> 0 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_incompatible_lc, ' ', status);
      RETURN;
    IFEND;
    connected_pc_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);

    amp$get_segment_pointer (connected_pc_fid, amc$sequence_pointer, connected_pc_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (connected_active_fid, amc$sequence_pointer, connected_list_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (state_info_fid, amc$sequence_pointer, state_info_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (active_state_info_fid, amc$sequence_pointer, active_state_info_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    RESET state_info_seg.sequence_pointer;
    RESET active_state_info_seg.sequence_pointer;
    RESET connected_list_seg.sequence_pointer;
    RESET connected_pc_seg.sequence_pointer;

   /connected_pc_loop/
    FOR connected_pc_index := 1 TO connected_pc_count DO
      NEXT connected_pc_element_p IN connected_pc_seg.sequence_pointer;
      IF connected_pc_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;
      NEXT lc_list_element_p IN state_info_seg.sequence_pointer;
      IF lc_list_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;

      IF lc_list_element_p^.element_type <> cmc$data_channel_element THEN
        IF lc_list_element_p^.application_info_size <> 0 THEN
          NEXT lc_list_element_p^.application_info_p: [lc_list_element_p^.application_info_size] IN
                state_info_seg.sequence_pointer;
          IF lc_list_element_p^.application_info_p = NIL THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
            RETURN;
          IFEND;
        IFEND;

        IF lc_list_element_p^.site_info_size <> 0 THEN
          NEXT lc_list_element_p^.site_info_p: [lc_list_element_p^.site_info_size] IN
                state_info_seg.sequence_pointer;
          IF lc_list_element_p^.site_info_p = NIL THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
            RETURN;
          IFEND;
        IFEND;
      IFEND;

      amp$set_segment_eoi (connected_active_fid, connected_list_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      amp$set_segment_eoi (active_state_info_fid, active_state_info_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

     /find_element_match/
      BEGIN
        CASE connected_pc_element_p^.element_type OF
        = cmc$data_channel_element =
          IF connected_pc_element_p^.data_channel.mainframe_ownership = mainframe THEN
            IF NOT mainframe_found THEN
              mainframe_found := TRUE;
            IFEND;
            EXIT /find_element_match/;
          IFEND;

        = cmc$controller_element =
          FOR cpn := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
            IF connected_pc_element_p^.controller.connection.port [cpn].configured AND (mainframe =
                  connected_pc_element_p^.controller.connection.port [cpn].mainframe_ownership) THEN
              cmp$get_controller_type (connected_pc_element_p^.product_id, controller_type, local_status);
              IF (controller_type = cmc$mt698_xx) OR (controller_type = cmc$mt7221_1) OR
                    (controller_type = cmc$mt7021_3x) THEN
                IF NOT tape_subsystem.dual_pp_present AND
                      (connected_pc_element_p^.controller.peripheral_driver_name(1, 2) = 'E2') THEN
                  tape_subsystem.dual_pp_present := TRUE;
                  tape_subsystem.dual_pp_name := connected_pc_element_p^.element_name;
                IFEND;
                IF NOT tape_subsystem.single_pp_present AND
                      (connected_pc_element_p^.controller.peripheral_driver_name(1, 2) = 'E1') THEN
                  tape_subsystem.single_pp_present := TRUE;
                  tape_subsystem.single_pp_name := connected_pc_element_p^.element_name;
                IFEND;
              IFEND;
              EXIT /find_element_match/;
            IFEND;
          FOREND;

        = cmc$channel_adapter_element =
          IF connected_pc_element_p^.channel_adapter.connection.channel.configured AND
                (connected_pc_element_p^.channel_adapter.connection.channel.upline_connection_type =
                cmc$data_channel_element) AND (mainframe =
                connected_pc_element_p^.channel_adapter.connection.channel.mainframe_ownership) THEN
            EXIT /find_element_match/;
          IFEND;

        = cmc$communications_element =
          FOR commpn := LOWERVALUE (cmt$communications_port_number) TO
                UPPERVALUE (cmt$communications_port_number) DO
            IF connected_pc_element_p^.communications_element.connection.port [commpn].configured THEN
              IF connected_pc_element_p^.communications_element.connection.port [commpn].mainframe_ownership =
                    mainframe THEN
                EXIT /find_element_match/;
              IFEND;
            IFEND;
          FOREND;

        = cmc$external_processor_element =
          FOR cpn := LOWERVALUE(cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
            IF connected_pc_element_p^.external_processor.connection.io_port [cpn].configured THEN
              IF connected_pc_element_p^.external_processor.connection.io_port [cpn].mainframe_ownership =
                    mainframe THEN
                EXIT /find_element_match/;
              IFEND;
            IFEND;
          FOREND;

        = cmc$storage_device_element =
          FOR sd_port := LOWERVALUE (cmt$data_storage_port_number) TO
                UPPERVALUE (cmt$data_storage_port_number) DO
            IF connected_pc_element_p^.storage_device.connection.port [sd_port].configured THEN
              IF connected_pc_element_p^.storage_device.connection.port [sd_port].upline_connection_type =
                    cmc$data_channel_element THEN
                IF connected_pc_element_p^.storage_device.connection.port [sd_port].mainframe_ownership =
                      mainframe THEN
                  EXIT /find_element_match/;
                IFEND;
              ELSEIF connected_pc_element_p^.storage_device.connection.port [sd_port].upline_connection_type =
                    cmc$controller_element THEN
                cmp$find_element (
                      connected_pc_element_p^.storage_device.connection.port [sd_port].element_name, iou_name,
                      mainframe, connected_pc_fid, element_p, local_status);
                IF local_status.normal THEN
                  FOR cpn := LOWERVALUE (cmt$controller_port_number) TO
                        UPPERVALUE (cmt$controller_port_number) DO
                    IF element_p^.controller.connection.port [cpn].configured AND
                          (mainframe = element_p^.controller.connection.port [cpn].mainframe_ownership) THEN
                      EXIT /find_element_match/;
                    IFEND;
                  FOREND;
                ELSE
                  osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_connection_not_found,
                                           connected_pc_element_p^.element_name, status);
                  RETURN;
                IFEND;
              IFEND;
            IFEND;
          FOREND;
        ELSE
        CASEND;

        CYCLE /connected_pc_loop/;

      END /find_element_match/;

      { Found a match, now move the element over. }

      IF tape_subsystem.dual_pp_present AND tape_subsystem.single_pp_present THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_inconsistent_tape_subs,
              tape_subsystem.dual_pp_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, tape_subsystem.single_pp_name, status);
        RETURN;
      IFEND;

      NEXT connected_list_element_p IN connected_list_seg.sequence_pointer;
      IF connected_list_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_lc, ' ', status);
        RETURN;
      IFEND;

      connected_list_element_p^ := connected_pc_element_p^;
      amp$set_segment_eoi (connected_active_fid, connected_list_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      amp$set_segment_position (connected_active_fid, connected_list_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      NEXT active_state_element_p IN active_state_info_seg.sequence_pointer;
      active_state_element_p^.element_name := lc_list_element_p^.element_name;
      active_state_element_p^.status := lc_list_element_p^.status;
      active_state_element_p^.element_type := lc_list_element_p^.element_type;
      IF active_state_element_p^.element_type = cmc$data_channel_element THEN
        active_state_element_p^.iou := lc_list_element_p^.iou;
      ELSE
        active_state_element_p^.product_id := lc_list_element_p^.product_id;
        active_state_element_p^.application_info_size := lc_list_element_p^.application_info_size;
        active_state_element_p^.site_info_size := lc_list_element_p^.site_info_size;
        IF lc_list_element_p^.application_info_size <> 0 THEN
          NEXT active_state_element_p^.application_info_p: [lc_list_element_p^.application_info_size] IN
                active_state_info_seg.sequence_pointer;
          active_state_element_p^.application_info_p^ := lc_list_element_p^.application_info_p^;
        ELSE
          active_state_element_p^.application_info_p := NIL;
        IFEND;

        IF lc_list_element_p^.site_info_size <> 0 THEN
          NEXT active_state_element_p^.site_info_p: [lc_list_element_p^.site_info_size] IN
                active_state_info_seg.sequence_pointer;
          active_state_element_p^.site_info_p^ := lc_list_element_p^.site_info_p^;
        ELSE
          active_state_element_p^.site_info_p := NIL;
        IFEND;
      IFEND;

      amp$set_segment_eoi (active_state_info_fid, active_state_info_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      amp$set_segment_position (active_state_info_fid, active_state_info_seg, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND /connected_pc_loop/;

    IF NOT mainframe_found THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pcu_mainframe_not_found, mainframe,
            status);
      RETURN;
    IFEND;

    update_connectivity (connected_active_fid, active_state_info_fid, mainframe, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Validate all elements not known to NOS/VE and reclassify them accordingly as storage device or
    { controller.

    validate_foreign_devices (connected_active_fid, active_state_info_fid, status);

  PROCEND cmp$build_active_conf;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$build_conf_tables', EJECT ??

{ PURPOSE:
{   This procedure builds the various mainframe pageable structures and assigns logical units to all
{   applicable elements.
{ NOTE:
{   The information used to build those tables are from two files created via INSPC.

  PROCEDURE [XDCL] cmp$build_conf_tables
    (VAR physical_conf_fid: amt$file_identifier;
     VAR state_info_fid: amt$file_identifier;
     VAR status: ost$status);

    VAR
      channel: cmt$physical_channel,
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      equipment_number: cmt$physical_equipment_number,
      iou_name: cmt$element_name,
      lc_index: integer,
      logical_element_index: integer,
      logical_conf_seg: amt$segment_pointer,
      physical_element_count: integer,
      physical_element_index: integer,
      physical_conf_array_p: cmt$physical_configuration,
      physical_conf_seg: amt$segment_pointer,
      physical_conf_element_p: ^cmt$element_definition,
      state_info_element_p: ^cmt$state_information,
      state_element_array_p: ^ARRAY [ * ] OF cmt$state_information,
      system_device_lun: iot$logical_unit,
      unit_number: cmt$physical_unit_number;

    status.normal := TRUE;
    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (physical_conf_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_eoi_not_returned,
            'eoi not returned"cmp$configure_peripheral"physical_conf_fid', status);
      RETURN;
    IFEND;
    physical_element_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);
    PUSH physical_conf_array_p: [1 .. physical_element_count];
    IF physical_conf_array_p = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_nil_sequence_pointer,
            'physical_conf_array_p in cmp$build_conf_tables, cmm$configure_in_job_template', status);
      RETURN;
    IFEND;

    amp$fetch_access_information (state_info_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_eoi_not_returned,
            'eoi not returned"cmp$configure_peripheral"state_info_fid', status);
      RETURN;
    IFEND;
    PUSH state_element_array_p: [1 .. physical_element_count];
    IF state_element_array_p = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_nil_sequence_pointer,
            'state_element_array_p in cmp$build_conf_tables, cmm$configure_in_job_template', status);
      RETURN;
    IFEND;

    amp$get_segment_pointer (physical_conf_fid, amc$sequence_pointer, physical_conf_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    amp$get_segment_pointer (state_info_fid, amc$sequence_pointer, logical_conf_seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    RESET logical_conf_seg.sequence_pointer;
    RESET physical_conf_seg.sequence_pointer;

    lc_index := 1;
    FOR logical_element_index := 1 TO physical_element_count DO
      NEXT physical_conf_element_p IN physical_conf_seg.sequence_pointer;
      IF physical_conf_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_nil_sequence_pointer,
              'physical_conf_element_p in cmp$build_conf_tables, cmm$configure_in_job_template', status);
        RETURN;
      IFEND;
      NEXT state_info_element_p IN logical_conf_seg.sequence_pointer;
      IF state_info_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_nil_sequence_pointer,
              'state_info_element_p in cmp$build_conf_tables, cmm$configure_in_job_template', status);
        RETURN;
      IFEND;

      IF state_info_element_p^.element_name = physical_conf_element_p^.element_name THEN
        state_element_array_p^ [lc_index].element_name := state_info_element_p^.element_name;
        state_element_array_p^ [lc_index].status := state_info_element_p^.status;
        state_element_array_p^ [lc_index].element_type := state_info_element_p^.element_type;
        IF state_element_array_p^ [lc_index].element_type = cmc$data_channel_element THEN
          state_element_array_p^ [lc_index].iou := state_info_element_p^.iou;
        ELSE
          state_element_array_p^ [lc_index].product_id := state_info_element_p^.product_id;
          state_element_array_p^ [lc_index].application_info_size :=
                state_info_element_p^.application_info_size;
          state_element_array_p^ [lc_index].site_info_size := state_info_element_p^.site_info_size;
          IF state_info_element_p^.application_info_size <> 0 THEN
            NEXT state_info_element_p^.application_info_p: [state_info_element_p^.application_info_size] IN
                  logical_conf_seg.sequence_pointer;
            PUSH state_element_array_p^ [lc_index].application_info_p:
                  [STRLENGTH (state_info_element_p^.application_info_p^)];
            state_element_array_p^ [lc_index].application_info_p^ :=
                  state_info_element_p^.application_info_p^;
          ELSE
            state_element_array_p^ [lc_index].application_info_p := NIL;
          IFEND;
          IF state_info_element_p^.site_info_size <> 0 THEN
            NEXT state_info_element_p^.site_info_p: [state_info_element_p^.site_info_size] IN
                  logical_conf_seg.sequence_pointer;
            PUSH state_element_array_p^ [lc_index].site_info_p:
                  [STRLENGTH (state_info_element_p^.site_info_p^)];
            state_element_array_p^ [lc_index].site_info_p^ := state_info_element_p^.site_info_p^;
          ELSE
            state_element_array_p^ [lc_index].site_info_p := NIL;
          IFEND;
          state_element_array_p^ [lc_index].logical_unit := 0;
        IFEND;
        lc_index :=  lc_index + 1;
      IFEND;
    FOREND;

    RESET physical_conf_seg.sequence_pointer;

    FOR physical_element_index := 1 TO physical_element_count DO
      NEXT physical_conf_element_p IN physical_conf_seg.sequence_pointer;
      IF physical_conf_element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$jtd_nil_sequence_pointer,
              'physical_conf_element_p in cmp$build_conf_tables, cmm$configure_in_job_template', status);
        RETURN;
      IFEND;
      physical_conf_array_p^ [physical_element_index] := physical_conf_element_p^;
    FOREND;

    cmp$get_system_device_path (cmc$sdt_disk_device, iou_name, channel, equipment_number, unit_number,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    system_device_lun := cmc$job_template_unit_ordinal;
    syp$trace_deadstart_message ('building cm tables');
    cmp$build_pct (physical_element_count, physical_conf_array_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    cmp$build_state_table (UPPERBOUND (state_element_array_p^), state_element_array_p^,
          {use_mrt_state=} TRUE, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    cmp$assign_logical_unit_numbers (iou_name, equipment_number, unit_number, system_device_lun, status);

  PROCEND cmp$build_conf_tables;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$check_for_unique_element', EJECT ??

{ PURPOSE:
{   This procedure searches a segment access file constructed as a sequence of to see if the named element
{   is unique.  A mainframe parameter must be specified, it is only used when the element refers to a
{   channel element.

  PROCEDURE [XDCL, #GATE] cmp$check_for_unique_element
    (    name: cmt$element_name;
         mainframe: cmt$element_name;
         input_fid: amt$file_identifier;
     VAR status: ost$status);

    VAR
      element_p: ^cmt$element_definition,
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      loop_count: integer,
      loop_index: integer,
      seg: amt$segment_pointer;

    status.normal := TRUE;
    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (input_fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_incompatible_lc, ' ', status);
      RETURN;
    IFEND;
    loop_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);

    amp$get_segment_pointer (input_fid, amc$sequence_pointer, seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET seg.sequence_pointer;

    FOR loop_index := 1 TO loop_count DO
      NEXT element_p IN seg.sequence_pointer;
      IF element_p^.element_name = name THEN
        IF element_p^.element_type = cmc$data_channel_element THEN
          IF mainframe = element_p^.data_channel.mainframe_ownership THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_duplicate_element_names, name,
                  status);
            RETURN;
          IFEND;
        ELSE
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_duplicate_element_names, name,
                status);
          RETURN;
        IFEND;
      IFEND;
    FOREND;

  PROCEND cmp$check_for_unique_element;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$check_init_status', EJECT ??

{ PURPOSE:
{   This procedure checks the status from INITIALIZE_MS_VOLUMES and performs the dialog with the operator to
{   allow him/her to back out of the INIMV process.

  PROCEDURE [XDCL, #GATE] cmp$check_init_status
    (    status: ost$status;
         initialize_status_info: dmt$initialize_status_info;
         element: cmt$element_name;
     VAR continue_initialization: boolean);

    VAR
      v$answer_table: [READ, oss$job_paged_literal] array [1 .. 2] of cmt$answer_prompt_table_entry := [
{ } ['Y', 1, 'YES', 3, 'Continue volume initialization', 30],
{ } ['N', 1, 'NO ', 2, 'Abort volume initialization', 27]];

    VAR
      ignore_status: ost$status,
      line: string (80),
      selection: integer;

    IF (osv$deadstart_phase = osc$installation_deadstart) AND NOT cmv$post_deadstart THEN
      continue_initialization := TRUE;
      RETURN;
    IFEND;

    IF status.normal THEN
      RETURN;
    IFEND;

    IF status.condition = dme$vol_label_date_not_expired THEN
      clp$put_job_output (' INITIALIZE_MS_VOLUME detected a recorded volume serial number: ', ignore_status);
      line := ' ';
      line (3, 7) := initialize_status_info.recorded_vsn;
      line (11, 12) := 'for element ';
      line (24, *) := element;
      clp$put_job_output (line, ignore_status);
      clp$put_job_output (' Files on this volume will be lost if you initialize it.', ignore_status);
    ELSE
      clp$put_job_output (' INITIALIZE_MS_VOLUME detected the following error :', ignore_status);
      osp$generate_error_message (status, ignore_status);
      IF status.condition = dme$unknown_ms_label_type THEN
        clp$put_job_output (' - Continue volume initialization:', ignore_status);
        clp$put_job_output ('   This will try to overwrite the exiting label without forcing a format.',
            ignore_status);
        clp$put_job_output (' - Reissue INITIALIZE_MS_VOLUME with Format_Volume set to Format_At_All_Costs.',
            ignore_status);
        clp$put_job_output ('   This will unconditionally format and initialize the volume without',
            ignore_status);
        clp$put_job_output ('   validating the label.', ignore_status);
        clp$put_job_output (' ', ignore_status);
        clp$put_job_output (' Note: Existing Device Flaws cannot be retained. They are part of the label.',
            ignore_status);
      IFEND;
    IFEND;
    cmp$prompt_for_answer (' Enter YES to allow initialize to continue, NO to stop.', ' Enter yes or no:',
          '--ERROR-- You must enter YES or NO. Please try again.', v$answer_table, selection);
    continue_initialization := selection = 1;

  PROCEND cmp$check_init_status;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$configure_peripheral', EJECT ??

{ PURPOSE:
{   This procedure is used at configuration transition time to set up SCL variables for the
{   SYSTEM_DEADSTART_PROLOG procedure and to invoke the SYSTEM_DEADSTART_PROLOG procedure.  The latter in
{   turns will invoke PCU and LCU to allow more peripheral subsystem to be configured and activated.

  PROCEDURE [XDCL] cmp$configure_peripheral
    (VAR status: ost$status);

    CONST
      c$physical_config_file_name = 'PHYSICAL_CONFIG                ';

    VAR
      cm_status: clt$variable_reference,
      file_attributes_p: ^amt$file_attributes,
      ignore_status: ost$status,
      pc_fid: amt$file_identifier,
      status_array: ARRAY [1 .. 1] OF clt$status;

    status.normal := TRUE;
    initialize_cm_variables;

    PUSH file_attributes_p: [1 .. 2];
    file_attributes_p^ [1].key := amc$access_mode;
    file_attributes_p^ [1].access_mode :=
          $pft$usage_selections [pfc$read, pfc$modify, pfc$execute, pfc$shorten, pfc$append];
    file_attributes_p^ [2].key := amc$ring_attributes;
    file_attributes_p^ [2].ring_attributes.r1 := osc$user_ring;
    file_attributes_p^ [2].ring_attributes.r2 := osc$user_ring;
    file_attributes_p^ [2].ring_attributes.r3 := osc$user_ring;
    IF osv$deadstart_phase = osc$installation_deadstart THEN
      amp$open ('CMF$DEFAULT_CONFIGURATION      ', amc$record, file_attributes_p, pc_fid, status);
      prepare_configuration_file (pc_fid);

    ELSEIF cmv$use_installed_configuration THEN
      amp$return (c$physical_config_file_name, ignore_status);
      amp$open (c$physical_config_file_name, amc$record, file_attributes_p, pc_fid, status);
      IF NOT status.normal THEN
        syp$process_deadstart_status (' ', FALSE, status);
        RETURN;
      IFEND;

      { Copy device file to BAM file.

      cmp$get_conf_file (pc_fid, status);
      IF NOT status.normal THEN
        clp$convert_to_clt$status (status, status_array [1]);
        cm_status.value.kind := clc$status_value;
        cm_status.value.status_value := ^status_array;
        clp$write_variable ('CMV$DEVICE_FILE_COPY_STATUS', cm_status.value, status);
        IF NOT status.normal THEN
          syp$process_deadstart_status (' ', FALSE, status);
          RETURN;
        IFEND;
      IFEND;
    IFEND;

    amp$close (pc_fid, ignore_status);

    clp$include_line ('$LOCAL.OSF$DS_LIBRARY.CMP$SYSTEM_DEADSTART_PROLOG', TRUE, osc$null_name, status);
    IF NOT status.normal THEN
      syp$process_deadstart_status (' ', FALSE, status);
      RETURN;
    IFEND;

  PROCEND cmp$configure_peripheral;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$find_element', EJECT ??

{ PURPOSE:
{   This procedure searches a segment access file that is in the form of a sequence for a particular element.
{   A mainframe parameter must be specified, it is only used when the element refers to a channel element.

  PROCEDURE [XDCL, #GATE] cmp$find_element
    (    element_name: cmt$element_name;
         iou_name: cmt$element_name;
         mainframe_owner: cmt$element_name;
         fid: amt$file_identifier;
     VAR element_p: ^cmt$element_definition;
     VAR status: ost$status);

    VAR
      eoi_addr: ARRAY [1 .. 1] OF amt$access_info,
      loop_count: integer,
      loop_index: integer,
      seg: amt$segment_pointer;

    status.normal := TRUE;
    element_p := NIL;

    eoi_addr [1].key := amc$eoi_byte_address;
    amp$fetch_access_information (fid, eoi_addr, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF NOT eoi_addr [1].item_returned THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_incompatible_lc, ' ', status);
      RETURN;
    IFEND;
    loop_count := eoi_addr [1].eoi_byte_address DIV #SIZE (cmt$element_definition);

    amp$get_segment_pointer (fid, amc$sequence_pointer, seg, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET seg.sequence_pointer;

    FOR loop_index := 1 TO loop_count DO
      NEXT element_p IN seg.sequence_pointer;
      IF element_p = NIL THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_element_not_found, element_name,
              status);
        RETURN;
      IFEND;
      IF element_p^.element_name = element_name THEN
        CASE element_p^.element_type OF
        = cmc$storage_device_element, cmc$controller_element, cmc$channel_adapter_element,
                cmc$external_processor_element, cmc$communications_element =
          RETURN;
        = cmc$data_channel_element =
          IF (element_p^.data_channel.mainframe_ownership = mainframe_owner) AND
                (element_p^.data_channel.iou = iou_name) THEN
            RETURN;
          IFEND;
        ELSE
        CASEND;
      IFEND;
    FOREND;

    osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_element_not_found, element_name,
          status);

  PROCEND cmp$find_element;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_volumes_active', EJECT ??

{ PURPOSE:
{   This procedure activates all ON Volumes in the configuration.  All Volumes in the ON state will be
{   redundantly activated if LCU is exited:
{     1. During a continuation deadstart
{     2. During an installation deadstart with Recover_system_set
{     3. After Deadstart is completed.

  PROCEDURE [XDCL, #GATE] cmp$get_volumes_active
    (VAR status: ost$status);

    VAR
      active_path: boolean,
      condition_name: ost$status_condition_name,
      continue: boolean,
      element_p: ^cmt$element_definition,
      element_descriptor: cmt$element_descriptor,
      down_element: boolean,
      iou_name: cmt$element_name,
      job_mode: jmt$job_mode,
      local_status: ost$status,
      lun: iot$logical_unit,
      members_to_remove: stt$inactive_members_to_remove,
      message: string (60),
      operator_message: string (256),
      operator_message_length: integer,
      operator_response: ost$string,
      selection: integer,
      state: cmt$element_state,
      unit_index: integer;

    VAR
      v$retry_answer_table: [READ, oss$job_paged_literal] array [1 .. 2] of cmt$answer_prompt_table_entry := [
{   } ['Y', 1, 'YES', 3, 'Retries activating the volume', 29],
{   } ['N', 1, 'NO ', 2, 'Skips volume activation of the failing volume', 45]];

    VAR
      v$missing_volue_answer_table: [READ, oss$job_paged_literal] array [1 .. 3] of
            cmt$answer_prompt_table_entry := [
{   } ['Y', 1, 'YES', 3, 'Deletes the missing volumes from the set', 40],
{   } ['N', 1, 'NO ', 2, 'Does not delete the missing volumes from the set', 48],
{   } ['MANS', 4, 'MANAGE_SET', 10, 'Calls the Manage_Set Utility', 28]];

?? NEWTITLE := 'P$MANAGE_SET', EJECT ??

    PROCEDURE p$manage_set
      (    set_name: stt$set_name;
       VAR status: ost$status);

      VAR
        i: integer,
        str: string (100);

      STRINGREP (str, i, '$LOCAL.OSF$DS_LIBRARY.MANAGE_SET, SET_NAME=', set_name, ', INPUT=COMMAND');
      clp$include_line (str (1, i), TRUE, osc$null_name, status);

    PROCEND p$manage_set;
?? OLDTITLE ??
?? NEWTITLE := '  p$put_job_output_message', EJECT ??

    PROCEDURE p$put_job_output_message
      (    lun: iot$logical_unit;
           message1: string ( * <= 40));

      VAR
        date: ost$date,
        date_time_string: dpt$critical_window_date_time,
        ignore_status: ost$status,
        message_line: string (80),
        i: integer,
        time: ost$time;

      IF syv$detailed_critical_displays < syc$dcd_trace_vol_act_deact_2 THEN
        RETURN; {----->
      IFEND;

      time.time_format := osc$hms_time;
      pmp$get_time (time.time_format, time, ignore_status);
      date.date_format := osc$mdy_date;
      pmp$get_date (date.date_format, date, ignore_status);
      date_time_string.string_part := ' ';
      date_time_string.hms := time.hms;
      date_time_string.mdy := date.mdy;

      STRINGREP (message_line, i, ' ', date_time_string.string_part, ' LUN= ', lun, ' ', message1);
      clp$put_job_output (message_line (1, i), ignore_status);

    PROCEND p$put_job_output_message;
?? OLDTITLE ??
?? EJECT ??
    status.normal := TRUE;
    iou_name := 'IOU0';
    message := ' ';

    IF NOT ((osv$deadstart_phase <> osc$installation_deadstart) OR
          ((osv$deadstart_phase = osc$installation_deadstart) AND cmv$post_deadstart) OR
          (osv$recover_system_set_phase = osc$reinitialize_system_device)) THEN
      RETURN;
    IFEND;

   /forloop/
    FOR lun := cmc$job_template_unit_ordinal TO UPPERVALUE (iot$logical_unit) DO
      p$put_job_output_message (lun, 'CMP$PC_GET_LOGICAL_UNIT');
      cmp$pc_get_logical_unit (lun, element_p, local_status);
      IF NOT local_status.normal THEN
        EXIT /forloop/;
      IFEND;

     /unit_loop/
      FOR unit_index := 1 TO UPPERBOUND (cmv$product_id_ptr^) DO
        IF (cmv$product_id_ptr^ [unit_index].cm_unit_type < cmc$ms844_4x) OR
              (cmv$product_id_ptr^ [unit_index].product_id <> element_p^.product_id) THEN
          CYCLE /unit_loop/;
        IFEND;

        p$put_job_output_message (lun, 'CMP$GET_ELEMENT_STATE');
        cmp$get_element_state (element_p^.element_name, {not used} iou_name, state, local_status);
        IF state <> cmc$on THEN
          CYCLE /unit_loop/;
        IFEND;

        p$put_job_output_message (lun, 'CMP$VERIFY_ACTIVE_PATH');
        cmp$verify_active_path (element_p^, active_path);
        IF NOT active_path THEN
          CYCLE /unit_loop/;
        IFEND;

        down_element := FALSE;
        continue := TRUE;
        REPEAT
          dmp$get_volume_active (lun, element_p^.product_id, local_status);
          IF NOT local_status.normal THEN
            IF (local_status.condition <> dme$volume_already_active) AND
                  (local_status.condition <> ste$vol_not_found) AND
                  (local_status.condition <> dme$volume_already_online) THEN
              pfp$log_error (local_status, $pmt$ascii_logset [pmc$job_log, pmc$system_log],
                    pmc$msg_origin_system, TRUE);
              pmp$get_job_mode (job_mode, status);
              IF jmp$system_job() OR (job_mode <> jmc$batch) THEN
                clp$put_job_output (
                      ' WARNING -- The following error was detected while activating volume mounted on',
                      status);
                message (2, *) := element_p^.element_name;
                clp$put_job_output (message, status);
                osp$generate_error_message (local_status, status);
                cmp$prompt_for_answer (' Do you want to retry activating that volume?', ' Enter yes or no:',
                      '--ERROR-- You must enter YES or NO. Please try again.', v$retry_answer_table,
                      selection);
                continue := selection = 1;
              ELSE
                osp$get_status_condition_name (local_status.condition, condition_name, status);
                STRINGREP (operator_message, operator_message_length,
                      ' WARNING -- The error ', condition_name (1, clp$trimmed_string_size(condition_name)),
                      ' was detected while activating volume ',
                      element_p^.element_name (1, clp$trimmed_string_size(element_p^.element_name)),
                      '.  Do you want to retry activating this volume? (Reply with yes or no)');
                ofp$send_operator_message (operator_message (1, operator_message_length),
                      ofc$system_operator, {acknowledgement_allowed = } TRUE, status);
                ofp$receive_operator_response (ofc$system_operator, osc$wait, operator_response, status);
                continue := (operator_response.value(1) = 'Y') OR (operator_response.value(1) = 'y');
              IFEND;
              IF continue THEN

                { Turn DOWN then ON the element to clear anything set by DM or IO.  STATUS is ignored if
                { cannot turn element back to ON.

                element_descriptor.element_type := element_p^.element_type;
                element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
                element_descriptor.peripheral_descriptor.element_name := element_p^.element_name;
                cmp$process_state_change ({tape_element=} FALSE, {system_call=} TRUE, element_descriptor,
                      {system_critical} FALSE, state, {new_state=} cmc$down, status);
                IF status.normal THEN
                  cmp$process_state_change ({tape_element=} FALSE, {system_call=} TRUE, element_descriptor,
                        {system_critical} FALSE, cmc$down, {new_state=} cmc$on, status);
                IFEND;
              ELSE
                down_element := TRUE;
              IFEND;
            ELSE
              local_status.normal := TRUE;
            IFEND;
          IFEND;
          status.normal := TRUE;
        UNTIL (continue = FALSE) OR local_status.normal;

        IF down_element THEN

          { Attempt to automatically DOWN the volume.

          element_descriptor.element_type := element_p^.element_type;
          element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
          element_descriptor.peripheral_descriptor.element_name := element_p^.element_name;
          cmp$process_state_change ({tape_element=} FALSE, {system_call=} TRUE, element_descriptor,
                {system critical} FALSE, state, {new_state=} cmc$down, local_status);
          IF NOT local_status.normal THEN
            clp$put_job_output (' WARNING -- The following error was detected when trying to DOWN', status);
            clp$put_job_output (message, status);
            osp$generate_error_message (local_status, status);
          IFEND;
        IFEND;
        EXIT /unit_loop/;
      FOREND /unit_loop/;
    FOREND /forloop/;

    { Now verify that all volumes are active.

    IF NOT cmv$post_deadstart THEN
      stp$verify_all_volumes_active (stv$system_set_name, local_status);
      IF NOT local_status.normal THEN
        syp$display_deadstart_message ('WARNING -- Not all volumes are active ');
        osp$generate_error_message (local_status, status);
        pmp$log_ascii ('NOT ALL MASS STORAGE VOLUMES ARE ACTIVE',
              $pmt$ascii_logset [pmc$system_log, pmc$job_log], pmc$msg_origin_system, local_status);
        IF osv$verify_missing_volumes THEN
          cmp$prompt_for_answer (' Do you want to delete the missing volumes from the set?',
                ' Enter yes, no, MANS or ?:', '--ERROR-- You must enter YES, NO or MANS. Please try again.',
                v$missing_volue_answer_table, selection);
          CASE selection OF
          = 1 =
            members_to_remove.kind := stc$imtr_remove_all_inactive;
            stp$remove_inactive_members (members_to_remove, stv$system_set_name, status);
            IF NOT status.normal THEN
              syp$process_deadstart_status (' ', FALSE, status);
            IFEND;

          = 3 =
            p$manage_set (stv$system_set_name, status);
            IF NOT status.normal THEN
              syp$process_deadstart_status (' ', FALSE, status);
            IFEND;
          ELSE
            ; { do not remove volume from set
          CASEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND cmp$get_volumes_active;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$install_system_conf', EJECT ??

{ PURPOSE:
{   This procedure writes the physical configuration text file to the device file.

  PROCEDURE [XDCL] cmp$install_system_conf
    (    input_fid: amt$file_identifier;
     VAR status : ost$status);

    VAR
      local_status: ost$status;

    status.normal := TRUE;
    amp$rewind (input_fid, osc$nowait, local_status);

    cmp$install_conf_file (input_fid, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND cmp$install_system_conf;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$post_deadstart', EJECT ??
  FUNCTION [XDCL, #GATE] cmp$post_deadstart: boolean;

    cmp$post_deadstart := cmv$post_deadstart;

  FUNCEND cmp$post_deadstart;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$save_mf_configuration', EJECT ??

{ PURPOSE:
{   This procedure saves a copy of the physical configuration file on file $SYSTEM.MAINFRAME.CONFIGURATION.
{   This is mainly for sites to rebuild their configuration file after a deadstart.
{ NOTE:
{   On a Continuation deadstart, this routine must be called after the point of committment, i.e when PF can
{   be referenced.

  PROCEDURE [XDCL] cmp$save_mf_configuration
    (VAR status: ost$status);

    VAR
      c_path: ARRAY [1 .. 3] OF pft$name,
      file_attrs_p: ^amt$file_attributes,
      fid: amt$file_identifier,
      local_file: amt$local_file_name,
      local_status: ost$status,
      open_file_attr_p: amt$file_access_selections,
      path: ARRAY [1 .. 4] OF pft$name,
      unique_name: ost$unique_name;

    status.normal := TRUE;

   /main_program/
    BEGIN
      pmp$generate_unique_name (unique_name, local_status);
      local_file := unique_name.value;
      path [1] := osc$null_name;
      path [2] := osc$null_name;
      path [3] := 'MAINFRAME';
      path [4] := 'CONFIGURATION';

      PUSH file_attrs_p: [1 .. 1];
      file_attrs_p^ [1].key := amc$ring_attributes;
      file_attrs_p^ [1].ring_attributes.r1 := osc$tsrv_ring;
      file_attrs_p^ [1].ring_attributes.r2 := osc$user_ring_2;
      file_attrs_p^ [1].ring_attributes.r3 := osc$user_ring_2;
      amp$file (local_file, file_attrs_p^, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      c_path [1] := osc$null_name;
      c_path [2] := osc$null_name;
      c_path [3] := 'MAINFRAME';
      pfp$define_catalog (c_path, status);
      IF NOT status.normal AND (status.condition <> pfe$name_already_subcatalog) THEN
        EXIT /main_program/;
      IFEND;

      IF osv$deadstart_phase <> osc$installation_deadstart THEN
        pfp$purge (path, v$low_cycle, osc$null_name, local_status);
      IFEND;
      pfp$define (local_file, path, v$pf_cycle, osc$null_name, pfc$maximum_retention, pfc$log, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      PUSH open_file_attr_p: [1 .. 4];
      open_file_attr_p^ [1].key := amc$ring_attributes;
      open_file_attr_p^ [1].ring_attributes.r1 := osc$tsrv_ring;
      open_file_attr_p^ [1].ring_attributes.r2 := osc$user_ring;
      open_file_attr_p^ [1].ring_attributes.r3 := osc$user_ring;
      open_file_attr_p^ [2].key := amc$access_mode;
      open_file_attr_p^ [2].access_mode := $pft$usage_selections [pfc$read,pfc$append,pfc$shorten,pfc$modify];
      open_file_attr_p^ [3].key := amc$open_position;
      open_file_attr_p^ [3].open_position := amc$open_at_boi;
      open_file_attr_p^ [4].key := amc$return_option;
      open_file_attr_p^ [4].return_option := amc$return_at_close;
      amp$open (local_file, amc$record, open_file_attr_p, fid, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      cmp$get_conf_file (fid, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

    END /main_program/;
    amp$rewind (fid, osc$nowait, local_status);
    amp$close (fid, local_status);
    amp$return (local_file , local_status);

  PROCEND cmp$save_mf_configuration;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$update_pcu_state_info', EJECT ??

{ PURPOSE:
{   This procedure updates the state information on a device file.
{ DESIGN:
{   1. Get the physical configuration file from the device file.
{   2. Run that file through PCU EDIT_PHYSICAL_CONFIGURATION
{   3. Use CHANGE_ELEMENT_DEFINTION E=xxx S=new_sate
{   4. QUIT Write_physical_configuration=TRUE
{   5. Rewrite the updated file to the device files.

  PROCEDURE [XDCL] cmp$update_pcu_state_info
    (    element_name: cmt$element_name;
         state: cmt$element_state;
     VAR status: ost$status);

    CONST
      utility_name = 'PHYSICAL_CONFIGURATION_UTILITY ';

    VAR
      edit_string: string (256),
      file_attr_p: ^amt$file_attributes,
      file_name: amt$local_file_name,
      ignore_status: ost$status,
      pc_fid: amt$file_identifier,
      pcu_utl_attr_p: ^clt$utility_attributes;

    status.normal := TRUE;

   /main_program/
    BEGIN
      pmp$get_unique_name (file_name, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      PUSH file_attr_p: [1 .. 2];
      file_attr_p^ [1].key := amc$access_mode;
      file_attr_p^ [1].access_mode := $pft$usage_selections [pfc$read, pfc$execute,pfc$shorten, pfc$append];
      file_attr_p^ [2].key := amc$ring_attributes;
      file_attr_p^ [2].ring_attributes.r1 := osc$user_ring;
      file_attr_p^ [2].ring_attributes.r2 := osc$user_ring;
      file_attr_p^ [2].ring_attributes.r3 := osc$user_ring;
      amp$open (file_name, amc$record, file_attr_p, pc_fid, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      cmp$get_conf_file (pc_fid, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;
      amp$rewind (pc_fid, osc$nowait, ignore_status);
      amp$close (pc_fid, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      PUSH pcu_utl_attr_p: [1 .. 4];
      pcu_utl_attr_p^ [1].key := clc$utility_command_search_mode;
      pcu_utl_attr_p^ [1].command_search_mode := clc$global_command_search;
      pcu_utl_attr_p^ [2].key := clc$utility_command_table;
      pcu_utl_attr_p^ [2].command_table := pcu_command_list;
      pcu_utl_attr_p^ [3].key := clc$utility_prompt;
      pcu_utl_attr_p^ [3].prompt.value := 'PCU';
      pcu_utl_attr_p^ [3].prompt.size := 3;
      pcu_utl_attr_p^ [4].key := clc$utility_termination_command;
      pcu_utl_attr_p^ [4].termination_command := 'QUIT';
      clp$begin_utility (utility_name, pcu_utl_attr_p^, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      cmp$open_utility_files (status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      cmp$set_default_mainframe_name (status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      edit_string := '    ';
      edit_string(2, 8) := 'EDIPC I=';
      edit_string(11, 31) := file_name;
      edit_string (43, 3) := 'O= ';
      edit_string (47, 31) := file_name;
      edit_string (80,1) := ';';
      edit_string (83, 9) := 'CHAED E= ';
      edit_string (93, 31) := element_name;
      edit_string (126, 6) := 'STATE=';
      CASE state OF
      = cmc$on =
        edit_string (133, 4) := 'ON';
      = cmc$off =
        edit_string (133, 4) := 'OFF';
      = cmc$down =
        edit_string (133, 4) := 'DOWN';
      CASEND;
      edit_string (138, 1) := ';';
      edit_string (142, 20) := 'QUIT WPC=TRUE;';
      clp$scan_command_line (edit_string, ignore_status);
      IF NOT ignore_status.normal THEN
        status := ignore_status;
      IFEND;
      clp$end_utility (utility_name, ignore_status);

      cmp$close_utility_files;

      IF status.normal THEN
        amp$open (file_name, amc$record, file_attr_p, pc_fid, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        cmp$install_system_conf (pc_fid, status);
      IFEND;
    END /main_program/;
    IF NOT status.normal THEN
      osp$generate_error_message (status, ignore_status);
    IFEND;
    amp$close (pc_fid, ignore_status);
    amp$return (file_name, ignore_status);

  PROCEND cmp$update_pcu_state_info;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$validate_cip_path ', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$validate_cip_path
    (    logical_unit: iot$logical_unit;
     VAR continue_initialization: boolean);

    VAR
      v$answer_table: [READ, oss$job_paged_literal] array [1 .. 2] of cmt$answer_prompt_table_entry := [
{   } ['Y', 1, 'YES', 3, 'Initializes the volume and destroys CIP', 39],
{   } ['N', 1, 'NO ', 2, 'Stops volume initialization', 27]];

    VAR
      local_status: ost$status,
      msi: cmt$mass_storage_information,
      selection: integer;

    continue_initialization := TRUE;
    cmp$get_mass_storage_info (logical_unit, msi, local_status);
    IF NOT local_status.normal AND (local_status.condition = cme$it_unusable_cip_access) THEN
      clp$put_job_output ('  WARNING - NOS/VE can not determine if CIP resides on a device', local_status);
      clp$put_job_output ('  which is only accessable to NOS/VE via a CIO channel.  The', local_status);
      clp$put_job_output ('  INITIALIZE_MS_VOLUME command will destroy CIP if allowed to continue.',
            local_status);
      cmp$prompt_for_answer (' Enter Yes to allow initialize to continue, No to stop.', ' Enter yes or no:',
            '--ERROR-- You must enter YES or NO. Please try again.', v$answer_table, selection);
      continue_initialization := selection = 1;
    IFEND;

  PROCEND cmp$validate_cip_path;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] CMP$VALIDATE_MS_CLASS', EJECT ??

{ PURPOSE:
{   This procedure validates the mass storage classes assigned to the active
{   volumes.  The following rules are enforced:
{     o Class C and P is required on the system set.
{     o Class J and K are required on every set.
{     o Class L is required on every non-system set.
{     o Class N is required on at least one device.
{     o Class Q is required on the system device.
{     o Every class is required on at least one device.
{
  PROCEDURE [XDCL, #GATE] cmp$validate_ms_class
    (VAR status: ost$status);

    VAR
      class_member: 'A' .. 'Z',
      master_volume: stt$volume_info,
      set_count: stt$number_of_sets,
      set_index: integer,
      set_list_p: ^stt$set_list,
      set_ms_class: dmt$class,
      str: string (52),
      str_len: 0 .. 255,
      system_ms_class: dmt$class,
      system_set: boolean,
      set_list_size: stt$number_of_sets,
      volume_list_size: stt$number_of_members,
      volume_count: stt$number_of_members,
      volume_index: integer,
      volume_list_p: ^stt$volume_list,
      volume_ms_class: dmt$class;

    status.normal := TRUE;
    system_ms_class := $dmt$class [];

    set_count := 10;
    REPEAT
      set_list_size := set_count;
      PUSH set_list_p: [1 .. set_list_size];
      stp$get_active_set_list (set_list_p^, set_count);
    UNTIL set_count <= set_list_size;

  /set_loop/
    FOR set_index := 1 TO set_count DO
      system_set := (set_index = 1 {LOWERBOUND (set_list_p^)} );

      volume_count := 10;
      REPEAT
        volume_list_size := volume_count;
        PUSH volume_list_p: [1 .. volume_list_size];
        stp$get_volumes_in_set (set_list_p^ [set_index], master_volume, volume_list_p^, volume_count,
              status);
      UNTIL volume_count <= volume_list_size;

      get_volume_ms_class (master_volume.recorded_vsn, volume_ms_class);
      set_ms_class := volume_ms_class;

      IF NOT (rmc$msc_system_critical_files IN set_ms_class) AND system_set THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_sys_device,
              master_volume.recorded_vsn, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_system_critical_files, status);
        RETURN;
      IFEND;

    /volume_loop/
      FOR volume_index := LOWERBOUND (volume_list_p^) TO volume_count DO
        get_volume_ms_class (volume_list_p^ [volume_index].recorded_vsn, volume_ms_class);
        set_ms_class := set_ms_class + volume_ms_class;
      FOREND /volume_loop/;

      system_ms_class := system_ms_class + set_ms_class;

      IF NOT (rmc$msc_system_swap_files IN set_ms_class) AND system_set THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_system_swap_files, status);
        RETURN;
      IFEND;

      IF NOT (rmc$msc_system_catalogs IN set_ms_class) THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_system_catalogs, status);
        RETURN;
      IFEND;

      IF NOT (rmc$msc_system_permanent_files IN set_ms_class) THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_system_permanent_files,
              status);
        RETURN;
      IFEND;

      IF NOT (rmc$msc_product_files IN set_ms_class) AND system_set THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_product_files, status);
        RETURN;
      IFEND;

      IF NOT (rmc$msc_user_permanent_files IN set_ms_class) and (NOT system_set) THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_user_permanent_files, status);
        RETURN;
      IFEND;

      IF NOT (rmc$msc_user_catalogs IN set_ms_class) AND (NOT system_set) THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_set,
              set_list_p^ [set_index], status);
        osp$append_status_parameter (osc$status_parameter_delimiter, rmc$msc_user_catalogs, status);
        RETURN;
      IFEND;
    FOREND /set_loop/;

    IF NOT (rmc$msc_user_temporary_files IN system_ms_class) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$class_missing_on_system,
            rmc$msc_user_temporary_files, status);
      RETURN;
    IFEND;

    str := ' ';
    str_len := 0;
    FOR class_member := 'A' TO 'Z' DO
      IF NOT (class_member IN system_ms_class) THEN
        str (str_len + 1) := ' ';
        str (str_len + 2) := class_member;
        str_len := str_len + 2;
      IFEND;
    FOREND;

    IF str_len <> 0 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcu_class_has_no_members,
            str (1, str_len), status);
      RETURN;
    IFEND;

  PROCEND cmp$validate_ms_class;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$validate_set_membership', EJECT ??

{ PURPOSE:
{   This procedure checks for SET membership of the volume being initialized via INITIALIZE_MS_VOLUME.
{   If the volume is currently a member of the set, then prompt for operator intervention. If the operator
{   enters yes to the prompt, then remove the volume from the set.

  PROCEDURE [XDCL, #GATE] cmp$validate_set_membership
    (    recorded_vsn: rmt$recorded_vsn;
         new_set_name: stt$set_name;
     VAR allow_to_continue: boolean;
     VAR status: ost$status);

    VAR
      found_ast_entry: stt$active_set_entry,
      found_ast_index: stt$ast_index,
      local_status: ost$status,
      master_info: stt$volume_info,
      master_vsn: rmt$recorded_vsn,
      member_count: stt$number_of_members,
      member_list_p: ^stt$volume_list,
      message: string (80),
      selection: integer,
      set_key_found: boolean,
      set_name: stt$set_name,
      volume_info: stt$volume_info;

    VAR
      v$answer_table: [READ, oss$job_paged_literal] array [1 .. 2] of cmt$answer_prompt_table_entry := [
{ } ['Y', 1, 'YES', 3, 'Removes the volume from the set and continues', 45],
{ } ['N', 1, 'NO ', 2, 'Does not remove the volume from the set', 39]];

    status.normal := TRUE;
    allow_to_continue := TRUE;
    IF (osv$deadstart_phase = osc$installation_deadstart) AND NOT cmv$post_deadstart THEN
      RETURN;
    IFEND;

    stp$get_volumes_set_name (recorded_vsn, set_name, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    PUSH member_list_p: [1 .. 1];
    stp$get_volumes_in_set (set_name, master_info, member_list_p^, member_count, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    master_vsn := master_info.recorded_vsn;
    stp$is_volume_in_set (recorded_vsn, set_name, volume_info, local_status);
    IF NOT local_status.normal THEN

      { Volume is not a member of the Set, OK to continue initialization.

      RETURN;
    IFEND;

    message := ' ';
    message := ' Volume         is currently a member of set ';
    message (9, 6):= recorded_vsn;
    message (46, *) := set_name;
    clp$put_job_output (message, local_status);
    cmp$prompt_for_answer (' Enter Yes to remove the volume from the set and continue, No to stop.',
          ' Enter yes or no:', '--ERROR-- You must enter YES or NO. Please try again.', v$answer_table,
          selection);
    allow_to_continue := selection = 1;
    IF allow_to_continue THEN
      stp$remove_member_vol_from_set (set_name, recorded_vsn, master_vsn, status);
      IF NOT status.normal AND ((status.condition = ste$member_not_active) OR
            (status.condition = ste$vol_not_in_set)) THEN
        stp$search_ast_by_set (set_name, found_ast_entry, found_ast_index, set_key_found);
        IF set_key_found THEN
          stp$r2_remove_inactive_member (found_ast_index, recorded_vsn, master_vsn, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      IFEND;
      message := ' ';
      message := ' Volume          has been removed from set   ';
      message (9, 6):= recorded_vsn;
      message (46, *) := set_name;
      clp$put_job_output (message, local_status);
      IF new_set_name = 'INIMV ATTEMPTED' THEN
        clp$put_job_output (' and the initialization of the device continues.', local_status);
      ELSE
        message := ' ';
        message := ' Volume          added to set ';
        message (9, 6):= recorded_vsn;
        IF new_set_name = 'UNSPECIFIED' THEN
          message (31, *) := stv$system_set_name;
        ELSE
          message (31, *) := new_set_name;
        IFEND;
        clp$put_job_output (message, local_status);
      IFEND;
    IFEND;

  PROCEND cmp$validate_set_membership;
?? OLDTITLE ??
MODEND cmm$configure_in_job_template;
