?? RIGHT := 110 ??
?? TITLE := ' CONFIGURATION MANAGEMENT: Configuration status', EJECT ??
MODULE cmm$config_status_interfaces;
?? RIGHT := 110 ??

{ PURPOSE:
{   This module contains interfaces that retrieve configuration
{   information.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cme$logical_configuration_mgr
*copyc cmt$element_definition
*copyc cmt$element_descriptor
*copyc cmt$element_information
*copyc cmt$element_selector
*copyc cmt$job_ownership
*copyc cmt$physical_channel
*copyc dmt$active_volume_table_index
*copyc iot$logical_unit
*copyc ost$caller_identifier
*copyc ost$status
*copyc rmt$device_class
?? POP ??
*copyc avp$configuration_administrator
*copyc avp$removable_media_operator
*copyc avp$system_displays
*copyc avp$system_operator
*copyc cmp$convert_channel_ordinal
*copyc cmp$convert_iou_name
*copyc cmp$format_error_message
*copyc cmp$get_channel_def
*copyc cmp$get_controller_type
*copyc cmp$get_element_state
*copyc cmp$get_logical_pp_index
*copyc cmp$get_logical_unit_number
*copyc cmp$get_ms_class_on_volume_r1
*copyc cmp$get_physical_attributes
*copyc cmp$get_pp_def
*copyc cmp$get_unit_type
*copyc cmp$pc_get_element
*copyc cmp$retrieve_iou_definition
*copyc cmp$search_active_volume_table
*copyc cmp$search_peripheral_table
*copyc dmp$calculate_device_capacity
*copyc dmp$calculate_remaining_space
*copyc dmp$volume_is_active
*copyc dmp$volume_is_online
*copyc dsp$retrieve_iou_information
*copyc osp$set_status_abnormal
*copyc pmp$get_mainframe_id
*copyc stp$get_volumes_set_name
*copyc cmv$logical_pp_table_p
*copyc cmv$logical_unit_table
*copyc cmv$peripheral_element_table
*copyc cmv$physical_configuration
*copyc cmv$state_info_table
*copyc iov$tusl_p
*copyc stv$system_set_name

?? OLDTITLE ??
?? NEWTITLE := 'F$MULTIPLE_IOU_SYSTEM', EJECT ??

  FUNCTION [INLINE, UNSAFE] f$multiple_iou_system: boolean;

    VAR
      iou_information_table: dst$iou_information_table,
      number_of_ious: dst$number_of_ious;

    dsp$retrieve_iou_information (number_of_ious, iou_information_table);
    f$multiple_iou_system := number_of_ious > 1;

  FUNCEND f$multiple_iou_system;
?? OLDTITLE ??
?? NEWTITLE := 'CMP$GET_CHANNEL_DEFINITION', EJECT ??
*copyc cmh$get_channel_definition

  PROCEDURE [XDCL, #GATE] cmp$get_channel_definition
    (    channel_identification: cmt$channel_descriptor;
     VAR channel_definition: cmt$data_channel_definition;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      channel_def: cmt$data_channel_definition,
      channel_id: cmt$channel_descriptor;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_CHANNEL_DEFINITION', status);
      RETURN; {----->
    IFEND;
    channel_id := channel_identification;
    cmp$get_channel_def (channel_id, channel_def, status);
    channel_definition := channel_def;

  PROCEND cmp$get_channel_definition;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_element_activity', EJECT ??

{ PURPOSE:
{   This procedure returns maintenance activity of element.

  PROCEDURE cmp$get_element_activity
    (    logical_unit: iot$logical_unit;
         element_descriptor: cmt$element_descriptor;
     VAR reservable_resource: boolean;
     VAR assigned_job: cmt$job_ownership;
     VAR reserved_job: cmt$job_ownership;
     VAR status: ost$status);

    VAR
      element_reservation: cmt$element_reservation,
      peripheral_index: integer;

    status.normal := TRUE;
    reservable_resource := FALSE;
    IF element_descriptor.element_type = cmc$storage_device_element THEN
      IF cmv$logical_unit_table^ [logical_unit].status.assignable_device THEN
        reservable_resource := TRUE;
      IFEND;
    IFEND;

    cmp$search_peripheral_table (element_descriptor, element_reservation, FALSE, peripheral_index, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;
    IF cmv$peripheral_element_table.pointer^ [peripheral_index].reservable_element <> cmc$not_reservable THEN
      reservable_resource := TRUE;
    IFEND;

    IF reservable_resource THEN
      assigned_job.active := FALSE;
      reserved_job.active := FALSE;

      IF element_descriptor.element_type = cmc$storage_device_element THEN
        IF cmv$logical_unit_table^ [logical_unit].status.assignable_device THEN
          IF cmv$logical_unit_table^ [logical_unit].status.assigned THEN
            assigned_job.active := TRUE;
            assigned_job.job_identification := cmv$logical_unit_table^ [logical_unit].status.assigned_jsn;
          IFEND;
        IFEND;
      IFEND;

      IF cmv$peripheral_element_table.pointer^ [peripheral_index].reservable_element <>
            cmc$not_reservable THEN
        IF cmv$peripheral_element_table.pointer^ [peripheral_index].entry_interlock THEN
          IF cmv$peripheral_element_table.pointer^ [peripheral_index].reserved_status THEN
            reserved_job.active := TRUE;
            reserved_job.job_identification := cmv$peripheral_element_table.pointer^ [peripheral_index].
                  reserved_job;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND cmp$get_element_activity;
?? OLDTITLE ??

?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_element_definition ', EJECT ??

*copyc cmh$get_element_definition

  PROCEDURE [XDCL, #GATE] cmp$get_element_definition
    (    element: cmt$element_descriptor;
     VAR definition: cmt$element_definition;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      channel_definition: cmt$data_channel_definition,
      element_count: integer,
      element_descriptor: cmt$element_descriptor,
      exact_match: boolean,
      found: boolean,
      i: integer,
      lc_index: integer,
      local_status: ost$status,
      physical_entry_p: ^cmt$element_definition,
      physical_id: cmt$physical_identification;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_ELEMENT_DEFINITION', status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;
    found := FALSE;
    exact_match := FALSE;

    CASE element.element_type OF
    = cmc$controller_element, cmc$storage_device_element, cmc$external_processor_element,
          cmc$channel_adapter_element, cmc$communications_element =
      IF NOT element.peripheral_descriptor.use_logical_identification THEN

{ set up element descriptor for search

        physical_id.product_identification.product_number := '      ';
        physical_id.serial_number := '      ';

        physical_id.hardware_address.physical_address_specifier :=
              element.peripheral_descriptor.hardware_address.physical_address_specifier;
        IF f$multiple_iou_system () THEN
          physical_id.hardware_address.iou := element.peripheral_descriptor.hardware_address.iou;
        ELSE
          physical_id.hardware_address.iou := 'IOU0';
        IFEND;
        physical_id.hardware_address.channel := element.peripheral_descriptor.hardware_address.channel;
        physical_id.hardware_address.channel.iou := element.peripheral_descriptor.hardware_address.channel.
              iou;
        physical_id.hardware_address.channel_address := element.peripheral_descriptor.hardware_address.
              channel_address;
        physical_id.hardware_address.unit_address := element.peripheral_descriptor.hardware_address.
              unit_address;
        physical_id.product_identification.product_number := '     ';
        physical_id.product_identification.underscore := ' ';
        physical_id.product_identification.model_number := '   ';
        physical_id.serial_number := '   ';
        cmp$get_element_name (physical_id, element_descriptor, status);

        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
      IFEND;

    = cmc$data_channel_element =

{ If the channel is not in the configuration then an error will be returned here.
      cmp$get_channel_definition (element.channel_descriptor, channel_definition, status);
      IF NOT status.normal THEN
        IF status.condition = cme$lcm_element_not_found THEN

{ This is a normal condition since a different channel port may exist.

          status.normal := TRUE;
        ELSE
          RETURN; {----->
        IFEND;
      IFEND;
    ELSE
    CASEND;

  /for_loop/
    FOR lc_index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO

      physical_entry_p := ^cmv$physical_configuration^ [lc_index];
      CASE element.element_type OF
      = cmc$data_channel_element =

{ Match IOU name if there is more than 1 IOU present.
        IF f$multiple_iou_system () THEN
          IF (physical_entry_p^.element_type = cmc$data_channel_element) AND
                (physical_entry_p^.data_channel.iou <> element.channel_descriptor.iou) THEN
            CYCLE /for_loop/; {----->
          IFEND;
        IFEND;

        IF (physical_entry_p^.element_type = cmc$data_channel_element) THEN
          exact_match := (physical_entry_p^.data_channel.number = channel_definition.number) AND
                (physical_entry_p^.data_channel.concurrent = channel_definition.concurrent) AND
                (channel_definition.port = physical_entry_p^.data_channel.port);
          IF exact_match THEN
            definition := physical_entry_p^;
            found := TRUE;
            EXIT /for_loop/; {----->
          ELSEIF (physical_entry_p^.data_channel.number = channel_definition.number) AND
                (physical_entry_p^.data_channel.concurrent = channel_definition.concurrent) THEN
            definition := physical_entry_p^;
            found := TRUE;
          IFEND;
        IFEND;

      = cmc$controller_element, cmc$storage_device_element, cmc$external_processor_element,
            cmc$channel_adapter_element, cmc$communications_element =

        IF element.peripheral_descriptor.use_logical_identification THEN
          IF (physical_entry_p^.element_name = element.peripheral_descriptor.element_name) THEN
            found := TRUE;
            EXIT /for_loop/; {----->
          IFEND;

        ELSEIF (physical_entry_p^.element_name = element_descriptor.peripheral_descriptor.element_name) THEN
          found := TRUE;
          EXIT /for_loop/; {----->
        IFEND;

      ELSE { CASE statement }

{ error not implemented

      CASEND;
    FOREND /for_loop/;

    IF NOT found THEN
      cmp$format_error_message (element, physical_id, FALSE, cme$lcm_element_not_found, status);
      RETURN; {----->

    ELSEIF element.element_type = cmc$data_channel_element THEN
      IF (NOT exact_match) THEN

{ Strip the port value in the channel name.

        IF definition.data_channel.port <> cmc$unspecified_port THEN
          definition.data_channel.port := cmc$unspecified_port;
          i := osc$max_name_size;
          WHILE (i >= 1) AND (definition.element_name (i, 1) = ' ') DO
            IF (definition.element_name (i, 1) = 'A') OR (definition.element_name (i, 1) = 'B') THEN
              definition.element_name (i, 1) := ' ';
            IFEND;
            i := i - 1;
          WHILEND;
        IFEND;
      IFEND;
    ELSE
      definition := cmv$physical_configuration^ [lc_index];
    IFEND;

  PROCEND cmp$get_element_definition;
?? OLDTITLE ??
?? NEWTITLE := '      cmp$get_element_information ', EJECT ??

*copyc cmh$get_element_information

  PROCEDURE [XDCL, #GATE] cmp$get_element_information
    (    element: cmt$element_descriptor;
     VAR information: cmt$element_information;
     VAR status: ost$status);

    VAR
      assigned_job: cmt$job_ownership,
      avt_entry_not_found: boolean,
      caller_id: ost$caller_identifier,
      channel_definition: cmt$data_channel_definition,
      densities: cmt$densities,
      element_count: integer,
      element_descriptor: cmt$element_descriptor,
      element_name: cmt$element_name,
      element_p: ^cmt$element_info_item,
      element_type: cmt$element_type,
      entry_type: rmt$device_class,
      ext_vsn: rmt$external_vsn,
      ext_vsn_found: boolean,
      found: boolean,
      index: integer,
      iou_name: cmt$element_name,
      item_returned: boolean,
      lc_index: integer,
      local_status: ost$status,
      logical_unit: iot$logical_unit,
      physical_attributes_p: ^dmt$physical_device_attributes,
      physical_entry_p: ^cmt$element_definition,
      physical_id: cmt$physical_identification,
      product_id: cmt$product_identification,
      rec_vsn: rmt$recorded_vsn,
      rec_vsn_found: boolean,
      reservable_resource: boolean,
      reserved_job: cmt$job_ownership,
      search_key: dmt$avt_search_key,
      serial_number: cmt$serial_number,
      state_information_p: ^cmt$state_information,
      system_critical: boolean,
      write_inhibited: boolean;

?? NEWTITLE := '[inline] P$GET_ELEMENT_DENSITY_ACCESS', EJECT ??

{ PURPOSE:
{   This procedure returns density information of tape element.

  PROCEDURE [INLINE] p$get_element_density_access
    (    logical_unit: iot$logical_unit;
     VAR densities: cmt$densities;
     VAR write_inhibited: boolean);

    VAR
      unit_type: iot$unit_type;

    unit_type := cmv$logical_unit_table^ [logical_unit].unit_interface_table^.unit_type;
    IF (unit_type = ioc$dt_mt679_2) OR (unit_type = ioc$dt_mt679_3) OR (unit_type = ioc$dt_mt679_4) THEN
      densities := $cmt$densities [rmc$800, rmc$1600];
    ELSEIF unit_type = ioc$dt_mt5682_1x THEN
      densities := $cmt$densities [rmc$38000];
    ELSE
      densities := $cmt$densities [rmc$1600, rmc$6250];
    IFEND;

    IF $cmt$element_access [cmc$write] <= cmv$logical_unit_table^ [logical_unit].element_access THEN
      write_inhibited := FALSE;
    ELSE
      write_inhibited := TRUE;
    IFEND;

  PROCEND p$get_element_density_access;
?? OLDTITLE ??
?? NEWTITLE := 'RETRIEVE_DEVICE_CLASS', EJECT ??

    PROCEDURE retrieve_device_class
      (    product: cmt$product_identification;
           element_type: cmt$element_type;
       VAR device_class: rmt$device_class;
       VAR found_device_class: boolean);

      VAR
        cm_unit_type: cmt$unit_type,
        found: boolean,
        io_unit_type: iot$unit_type,
        unit_class: cmt$unit_class;

      found_device_class := TRUE;
      IF (element_type <> cmc$data_channel_element) AND (element_type <> cmc$controller_element) THEN
        cmp$get_unit_type (product_id, cm_unit_type, io_unit_type, unit_class, found);
        IF found THEN
          IF unit_class = cmc$magnetic_tape_unit THEN
            device_class := rmc$magnetic_tape_device;
          ELSEIF unit_class = cmc$mass_storage_unit THEN
            device_class := rmc$mass_storage_device;
          ELSE
            found_device_class := FALSE;
          IFEND;
        ELSE { Not found, foreign or network devices }
          IF element_type = cmc$storage_device_element THEN
            device_class := rmc$mass_storage_device;
          ELSEIF element_type = cmc$communications_element THEN
            IF unit_class = cmc$rhfam_unit THEN
              device_class := rmc$rhfam_device;
            ELSEIF unit_class = cmc$network_unit THEN
              device_class := rmc$network_device;
            IFEND;
          ELSEIF (element_type = cmc$channel_adapter_element) AND (unit_class = cmc$network_unit) THEN
            device_class := rmc$network_device;
          ELSE
            found_device_class := FALSE;
          IFEND;
        IFEND;
      ELSE
        found_device_class := FALSE;
      IFEND;

    PROCEND retrieve_device_class;
?? OLDTITLE ??
?? EJECT ??

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_ELEMENT_INFORMATION', status);
      RETURN; {----->
    IFEND;
    status.normal := TRUE;
    iou_name := 'IOU0';
    ext_vsn_found := FALSE;
    avt_entry_not_found := TRUE;
    found := FALSE;

    FOR index := LOWERBOUND (information) TO UPPERBOUND (information) DO
      information [index].item_returned := FALSE;
    FOREND;

    element_descriptor.element_type := element.element_type;
    CASE element.element_type OF
    = cmc$controller_element, cmc$storage_device_element, cmc$external_processor_element,
          cmc$channel_adapter_element, cmc$communications_element =

      IF NOT element.peripheral_descriptor.use_logical_identification THEN

{ set up element descriptor for search

        physical_id.hardware_address.physical_address_specifier :=
              element.peripheral_descriptor.hardware_address.physical_address_specifier;
        IF f$multiple_iou_system () THEN
          physical_id.hardware_address.iou := element.peripheral_descriptor.hardware_address.iou;
        ELSE
          physical_id.hardware_address.iou := 'IOU0';
        IFEND;
        physical_id.hardware_address.channel := element.peripheral_descriptor.hardware_address.channel;
        physical_id.hardware_address.channel_address := element.peripheral_descriptor.hardware_address.
              channel_address;
        physical_id.hardware_address.unit_address := element.peripheral_descriptor.hardware_address.
              unit_address;
        physical_id.product_identification.product_number := '     ';
        physical_id.product_identification.underscore := ' ';
        physical_id.product_identification.model_number := '   ';
        physical_id.serial_number := '   ';
        cmp$get_element_name (physical_id, element_descriptor, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
      ELSE
        element_descriptor.peripheral_descriptor.element_name := element.peripheral_descriptor.element_name;
      IFEND;

    = cmc$data_channel_element =
      cmp$get_channel_definition (element.channel_descriptor, channel_definition, status);
      IF NOT status.normal THEN
        IF status.condition = cme$lcm_element_not_found THEN
          status.normal := TRUE;
        ELSE
          RETURN; {----->
        IFEND;
      IFEND;
      IF f$multiple_iou_system () THEN
        iou_name := element.channel_descriptor.iou;
      IFEND;
    ELSE
    CASEND;

  /for_loop/
    FOR lc_index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO

      physical_entry_p := ^cmv$physical_configuration^ [lc_index];
      CASE element.element_type OF
      = cmc$data_channel_element =
        IF f$multiple_iou_system () THEN
          IF (physical_entry_p^.element_type = cmc$data_channel_element) AND
                (physical_entry_p^.data_channel.iou <> element.channel_descriptor.iou) THEN
            CYCLE /for_loop/; {----->
          IFEND;
        IFEND;
        IF (physical_entry_p^.data_channel.number = channel_definition.number) AND
              (physical_entry_p^.data_channel.concurrent = channel_definition.concurrent) THEN
          found := TRUE;
          EXIT /for_loop/; {----->
        IFEND;

      = cmc$controller_element, cmc$storage_device_element, cmc$external_processor_element,
            cmc$channel_adapter_element, cmc$communications_element =

        IF ((element.peripheral_descriptor.use_logical_identification) AND
              (physical_entry_p^.element_name = element.peripheral_descriptor.element_name))
{     } OR (physical_entry_p^.element_name = element_descriptor.peripheral_descriptor.element_name) THEN
          found := TRUE;
          EXIT /for_loop/; {----->
        IFEND;

      ELSE { CASE statement }

{ error not implemented

      CASEND;
    FOREND /for_loop/;

    IF NOT found THEN
      cmp$format_error_message (element, physical_id, FALSE, cme$lcm_element_not_found, status);
      RETURN; {----->
    ELSE
      element_name := physical_entry_p^.element_name;
      element_type := physical_entry_p^.element_type;
      serial_number := physical_entry_p^.serial_number;
      product_id := physical_entry_p^.product_id;
    IFEND;

    CASE element_type OF
    = cmc$storage_device_element =

      cmp$get_logical_unit_number (element_name, logical_unit, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      retrieve_device_class (product_id, element_type, entry_type, item_returned);
      IF item_returned AND (entry_type = rmc$magnetic_tape_device) THEN

      /search_tusl_for_evsn/
        FOR index := LOWERBOUND (iov$tusl_p^) TO UPPERBOUND (iov$tusl_p^) DO
          IF iov$tusl_p^ [index].element_name = element_name THEN
            IF iov$tusl_p^ [index].assignment_state <> ioc$not_assigned THEN
              ext_vsn := iov$tusl_p^ [index].evsn;
              ext_vsn_found := TRUE;
            IFEND;

            IF iov$tusl_p^ [index].unit_ready THEN
              rec_vsn := iov$tusl_p^ [index].rvsn;
              rec_vsn_found := TRUE;
            IFEND;
            EXIT /search_tusl_for_evsn/; {----->
          IFEND;
        FOREND /search_tusl_for_evsn/;
      ELSE
        search_key.value := dmc$search_avt_by_lun;
        search_key.logical_unit_number := logical_unit;
        cmp$search_active_volume_table (search_key, rec_vsn, avt_entry_not_found);
        rec_vsn_found := NOT avt_entry_not_found;
      IFEND;

    ELSE
      ;
    CASEND;


    FOR index := LOWERBOUND (information) TO UPPERBOUND (information) DO

      state_information_p := ^cmv$state_info_table^ [lc_index];
      element_p := ^information [index];
      CASE element_p^.selector OF
      = cmc$application_information =
        IF element_p^.application_information = NIL THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_nil_pointer_detected,
                'CMP$GET_ELEMENT_INFORMATION', status);
          RETURN; {----->
        IFEND;
        IF (state_information_p^.application_info_p <> NIL) THEN
          IF (STRLENGTH (element_p^.application_information^) <
                STRLENGTH (state_information_p^.application_info_p^)) THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_insufficient_space, ' ',
                  status);
            RETURN; {----->
          IFEND;
          element_p^.application_information^ := state_information_p^.application_info_p^;
          element_p^.item_returned := TRUE;
        IFEND;
      = cmc$application_string_size =
        IF (state_information_p^.application_info_p <> NIL) THEN
          element_p^.application_info_string_size := state_information_p^.application_info_size;
          element_p^.item_returned := TRUE;
        IFEND;
      = cmc$dau_size =
        PUSH physical_attributes_p: [1 .. 2];
        physical_attributes_p^ [1].keyword := dmc$bytes_per_mau;
        physical_attributes_p^ [2].keyword := dmc$maus_per_dau;
        cmp$get_physical_attributes (product_id, physical_attributes_p, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        element_p^.item_returned := TRUE;
        element_p^.dau_size := (physical_attributes_p^ [1].bytes_per_mau *
              physical_attributes_p^ [2].maus_per_dau);

      = cmc$device_class =
        IF NOT avt_entry_not_found THEN
          element_p^.item_returned := TRUE;
          element_p^.device_class := entry_type;
        ELSE
          retrieve_device_class (product_id, element_type, element_p^.device_class, element_p^.item_returned);
        IFEND;

      = cmc$element_status =
        cmp$get_element_state (element_name, iou_name, element_p^.element_status.state, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        element_p^.item_returned := TRUE;
        IF element_p^.element_status.state <> cmc$on THEN
          element_p^.element_status.repair_action_required := FALSE;
        IFEND;

      = cmc$external_vsn =
        IF ext_vsn_found THEN
          element_p^.item_returned := TRUE;
          element_p^.external_vsn := ext_vsn;
        IFEND;

      = cmc$maintenance_activity =
        ;

      = cmc$mass_storage_capacity =
        dmp$calculate_device_capacity (product_id, element_p^.total_capacity, local_status);
        element_p^.item_returned := local_status.normal;

      = cmc$mass_storage_available =
        dmp$calculate_remaining_space (logical_unit, element_p^.available_capacity, local_status);
        element_p^.item_returned := local_status.normal;

      = cmc$product_identification =
        IF found AND NOT (element_type = cmc$data_channel_element) THEN
          element_p^.item_returned := TRUE;
          element_p^.product_identification := product_id;
        IFEND;

      = cmc$recorded_vsn =
        IF rec_vsn_found THEN
          element_p^.item_returned := TRUE;
          element_p^.recorded_vsn := rec_vsn;
        IFEND;

      = cmc$serial_number =
        IF found AND NOT (element_type = cmc$data_channel_element) THEN
          element_p^.item_returned := TRUE;
          element_p^.serial_number := serial_number;
        IFEND;

      = cmc$site_information =
        IF element_p^.site_information = NIL THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_nil_pointer_detected,
                'CMP$GET_ELEMENT_INFORMATION', status);
          RETURN; {----->
        IFEND;
        IF (state_information_p^.site_info_p <> NIL) THEN
          IF (STRLENGTH (element_p^.site_information^) < STRLENGTH (state_information_p^.site_info_p^)) THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_insufficient_space, ' ',
                  status);
            RETURN; {----->
          IFEND;
          element_p^.site_information^ := state_information_p^.site_info_p^;
          element_p^.item_returned := TRUE;
        IFEND;

      = cmc$site_info_string_size =
        IF (state_information_p^.site_info_p <> NIL) THEN
          element_p^.site_info_string_size := state_information_p^.site_info_size;
          element_p^.item_returned := TRUE;
        IFEND;

      = cmc$system_critical_element =
        element_p^.system_critical_element := FALSE;

        cmp$system_critical (cmv$physical_configuration^ [lc_index], system_critical, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        element_p^.item_returned := TRUE;
        element_p^.system_critical_element := system_critical;

      = cmc$element_capability =
        element_p^.item_returned := TRUE;
        element_p^.element_capability.element_type := element_type;
        retrieve_device_class (product_id, element_type, element_p^.element_capability.device_class,
              element_p^.item_returned);
        IF (element_p^.element_capability.device_class = rmc$magnetic_tape_device) AND
              (element_p^.item_returned) THEN
          p$get_element_density_access (logical_unit, densities, write_inhibited);

          element_p^.element_capability.densities := densities;
          element_p^.element_capability.write_inhibited := write_inhibited;
        IFEND;

      = cmc$volume_online =
        dmp$volume_is_online (logical_unit, element_p^.online);
        element_p^.item_returned := (logical_unit <> 0);

      = cmc$volume_active =
        dmp$volume_is_active (logical_unit, element_p^.active);
        element_p^.item_returned := (logical_unit <> 0);

      = cmc$system_activity =
        element_p^.item_returned := TRUE;
        cmp$get_element_activity (logical_unit, element_descriptor, reservable_resource, assigned_job,
              reserved_job, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
        element_p^.system_activity.reservable_resource := reservable_resource;
        IF reservable_resource THEN
          element_p^.system_activity.job_assignment.active := assigned_job.active;
          IF assigned_job.active THEN
            element_p^.system_activity.job_assignment.job_identification := assigned_job.job_identification;
          IFEND;
          element_p^.system_activity.job_reservation.active := reserved_job.active;
          IF reserved_job.active THEN
            element_p^.system_activity.job_reservation.job_identification := reserved_job.job_identification;
          IFEND;
        IFEND;

      ELSE
        ; { ERROR, undefined selector }
      CASEND;

    FOREND;

  PROCEND cmp$get_element_information;
?? OLDTITLE ??
?? NEWTITLE := '      cmp$get_element_name', EJECT ??

*copyc cmh$get_element_name

  PROCEDURE [XDCL, #GATE] cmp$get_element_name
    (    physical_identification: cmt$physical_identification;
     VAR element: cmt$element_descriptor;
     VAR status: ost$status);

    VAR
      address_specified: array [cmt$physical_address_parts] of boolean,
      caller_id: ost$caller_identifier,
      channel: cmt$physical_channel,
      channel_address: cmt$physical_equipment_number,
      channel_name: cmt$element_name,
      channel_number: cmt$channel_identification,
      definition: cmt$element_definition,
      element_count: integer,
      element_def: ^cmt$element_definition,
      element_descriptor: cmt$element_descriptor,
      found: boolean,
      i: integer,
      iou_name: cmt$element_name,
      lc_index: integer,
      local_status: ost$status,
      pa_index: cmt$physical_address_parts,
      pen: cmt$physical_equipment_number,
      physical_descriptor: cmt$element_descriptor,
      product_id: cmt$product_identification,
      serial_number: cmt$serial_number,
      unit_address: cmt$physical_unit_number;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_ELEMENT_NAME', status);
      RETURN; {----->
    IFEND;
    found := FALSE;
    status.normal := TRUE;
    iou_name := 'IOU0';

    IF (physical_identification.product_identification.product_number = '  $885') OR
          (physical_identification.product_identification.product_number = '  $895') THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ambiguous_product_id, ' ', status);
      RETURN; {----->
    IFEND;

    IF (physical_identification.product_identification.product_number <> '      ') AND
          (physical_identification.serial_number <> '      ') THEN
      product_id := physical_identification.product_identification;
      serial_number := physical_identification.serial_number;

    /for_loop/
      FOR lc_index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO

        IF (cmv$physical_configuration^ [lc_index].product_id = product_id) AND
              (cmv$physical_configuration^ [lc_index].serial_number = serial_number) AND
              (cmv$physical_configuration^ [lc_index].element_type <> cmc$data_channel_element) THEN
          found := TRUE;
          element.element_type := cmv$physical_configuration^ [lc_index].element_type;
          CASE element.element_type OF
          = cmc$controller_element, cmc$storage_device_element, cmc$external_processor_element,
                cmc$channel_adapter_element, cmc$communications_element =

            element.peripheral_descriptor.use_logical_identification := TRUE;
            element.peripheral_descriptor.element_name := cmv$physical_configuration^ [lc_index].element_name;
          ELSE
          CASEND;

          EXIT /for_loop/; {----->

        IFEND;

      FOREND /for_loop/;

    ELSE

{ match physical  channel number, channel address and unit address
      IF physical_identification.hardware_address.physical_address_specifier =
            $cmt$physical_address_specifier [] THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_empty_pa_set, ' ', status);
        RETURN; {----->
      IFEND;

      FOR pa_index := LOWERVALUE (cmt$physical_address_parts) TO UPPERVALUE (cmt$physical_address_parts) DO
        address_specified [pa_index] := pa_index IN physical_identification.hardware_address.
              physical_address_specifier;
        IF address_specified [pa_index] THEN
          CASE pa_index OF
          = cmc$iou =
            IF f$multiple_iou_system () THEN
              iou_name := physical_identification.hardware_address.iou;
            IFEND;
          = cmc$channel =
            channel_number.ordinal := physical_identification.hardware_address.channel.ordinal;
            IF f$multiple_iou_system () THEN
              channel_number.iou := physical_identification.hardware_address.channel.iou;
            ELSE
              channel_number.iou := iou_name;
            IFEND;
            cmp$convert_channel_ordinal (channel_number.ordinal, channel_name, channel.number,
                  channel.concurrent, channel.port, status);
            IF NOT status.normal THEN
              RETURN; {----->
            IFEND;
          = cmc$channel_address =
            channel_address := physical_identification.hardware_address.channel_address;
          = cmc$unit_address =
            unit_address := physical_identification.hardware_address.unit_address;
          CASEND;
        IFEND;
      FOREND;

      IF f$multiple_iou_system () THEN
        IF NOT address_specified [cmc$iou] THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_missing_pa_set_member, 'IOU',
                status);
          RETURN; {----->
        IFEND;
      IFEND;

      IF address_specified [cmc$channel_address] THEN
        IF NOT address_specified [cmc$channel] THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_missing_pa_set_member,
                'Channel ID', status);
          RETURN; {----->
        IFEND;
      IFEND;
      IF address_specified [cmc$unit_address] THEN
        IF (NOT address_specified [cmc$channel]) OR (NOT address_specified [cmc$channel_address]) THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_missing_pa_set_member,
                'Channel ID and Address', status);
          RETURN; {----->
        IFEND;
      IFEND;

    /for_loop2/
      FOR lc_index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO
        IF address_specified [cmc$channel] AND address_specified [cmc$channel_address] AND
              address_specified [cmc$unit_address] THEN
          IF (cmv$physical_configuration^ [lc_index].element_type = cmc$data_channel_element) AND
                (cmv$physical_configuration^ [lc_index].data_channel.iou = iou_name) AND
                (cmv$physical_configuration^ [lc_index].data_channel.ordinal = channel_number.ordinal) THEN
            FOR pen := LOWERVALUE (cmt$physical_equipment_number)
                  TO UPPERVALUE (cmt$physical_equipment_number) DO
              IF (cmv$physical_configuration^ [lc_index].data_channel.connection.equipment [pen].
                    configured) THEN
                cmp$pc_get_element (cmv$physical_configuration^ [lc_index].
                      data_channel.connection.equipment [pen].element_name, iou_name, element_def, status);
                IF NOT status.normal THEN
                  EXIT /for_loop2/; {----->
                IFEND;

                IF element_def^.element_type = cmc$controller_element THEN
                  IF pen = channel_address THEN
                    IF element_def^.controller.connection.unit [unit_address].configured THEN
                      found := TRUE;
                      element.element_type := cmc$storage_device_element;
                      element.peripheral_descriptor.use_logical_identification := TRUE;
                      element.peripheral_descriptor.element_name := element_def^.controller.connection.
                            unit [unit_address].element_name;
                      EXIT /for_loop2/; {----->

                    IFEND;
                  IFEND;
                ELSEIF element_def^.element_type = cmc$storage_device_element THEN
                  IF pen = unit_address THEN
                    found := TRUE;
                    element.element_type := element_def^.element_type;
                    element.peripheral_descriptor.use_logical_identification := TRUE;
                    element.peripheral_descriptor.element_name := element_def^.element_name;
                    EXIT /for_loop2/; {----->
                  IFEND;
                IFEND;
              IFEND;
            FOREND;
          IFEND;
        ELSEIF address_specified [cmc$channel] AND address_specified [cmc$channel_address] AND
              NOT address_specified [cmc$unit_address] THEN
          IF (cmv$physical_configuration^ [lc_index].element_type = cmc$data_channel_element) AND
                (cmv$physical_configuration^ [lc_index].data_channel.ordinal = channel_number.ordinal) AND
                (cmv$physical_configuration^ [lc_index].data_channel.iou = iou_name) AND
                (cmv$physical_configuration^ [lc_index].data_channel.connection.equipment [channel_address].
                configured) THEN
            found := TRUE;

            physical_descriptor.element_type := cmc$channel_adapter_element;
            physical_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
            physical_descriptor.peripheral_descriptor.element_name :=
                  cmv$physical_configuration^ [lc_index].data_channel.connection.equipment [channel_address].
                  element_name;
            cmp$get_element_definition (physical_descriptor, definition, status);
            IF NOT status.normal THEN
              RETURN; {----->
            IFEND;

            element.element_type := definition.element_type;
            element.peripheral_descriptor.use_logical_identification := TRUE;
            element.peripheral_descriptor.element_name := cmv$physical_configuration^ [lc_index].data_channel.
                  connection.equipment [channel_address].element_name;
            EXIT /for_loop2/; {----->

          IFEND;

        ELSEIF address_specified [cmc$channel] AND NOT address_specified [cmc$channel_address] AND
              NOT address_specified [cmc$unit_address] THEN
          IF (cmv$physical_configuration^ [lc_index].element_type = cmc$data_channel_element) AND
                (cmv$physical_configuration^ [lc_index].data_channel.iou = iou_name) AND
                (cmv$physical_configuration^ [lc_index].data_channel.number = channel.number) AND
                (cmv$physical_configuration^ [lc_index].data_channel.concurrent = channel.concurrent) THEN
            found := TRUE;
            element.element_type := cmc$data_channel_element;
            element.channel_descriptor.use_logical_identification := TRUE;
            element.channel_descriptor.name := cmv$physical_configuration^ [lc_index].element_name;
            IF (cmv$physical_configuration^ [lc_index].data_channel.port = channel.port) THEN
              EXIT /for_loop2/; {----->
            ELSE

{
{ Allow a channel name with no port to be returned if the request specifies no port.
{ Else an exact match is needed.
{

              IF (channel.port <> cmc$unspecified_port) THEN
                found := FALSE;
                CYCLE /for_loop2/; {----->
              ELSE

{ Strip Port value from Channel name.

                i := osc$max_name_size;
                WHILE (i >= 1) AND (element.channel_descriptor.name (i, 1) = ' ') DO
                  IF (element.channel_descriptor.name (i, 1) = 'A') OR
                        (element.channel_descriptor.name (i, 1) = 'B') THEN
                    element.channel_descriptor.name (i, 1) := ' ';
                  IFEND;
                  i := i - 1;
                WHILEND;
              IFEND;
            IFEND;
          IFEND;

        ELSEIF address_specified [cmc$iou] THEN
          IF NOT address_specified [cmc$channel_address] AND NOT address_specified [cmc$channel] AND
                NOT address_specified [cmc$unit_address] THEN
            found := TRUE;
            element.element_type := cmc$iou_element;
            element.name := iou_name;
            EXIT /for_loop2/; {----->
          IFEND;

        IFEND;
      FOREND /for_loop2/;
    IFEND;
    IF NOT found THEN
      cmp$format_error_message (element_descriptor, physical_identification, TRUE,
            cme$lcm_element_name_not_found, status);
      RETURN; {----->
    IFEND;

  PROCEND cmp$get_element_name;
?? OLDTITLE ??
?? NEWTITLE := '  cmp$get_ms_class_on_volume', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$get_ms_class_on_volume
    (    recorded_vsn: rmt$recorded_vsn;
     VAR volume_found: boolean;
     VAR ms_class_info: cmt$ms_class_info);

    cmp$get_ms_class_on_volume_r1 (recorded_vsn, volume_found, ms_class_info);

  PROCEND cmp$get_ms_class_on_volume;
?? OLDTITLE ??
?? NEWTITLE := '  cmp$get_number_of_elements', EJECT ??

*copyc cmh$get_number_of_elements

  PROCEDURE [XDCL, #GATE] cmp$get_number_of_elements
    (    selector: cmt$element_selector;
     VAR number_of_elements: integer;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      class: rmt$device_class,
      unit_type: cmt$unit_type,
      found: boolean,
      io_unit_type: iot$unit_type,
      unit_class: cmt$unit_class,
      index: integer;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_NUMBER_OF_ELEMENTS', status);
      RETURN; {----->
    IFEND;
    status.normal := TRUE;
    number_of_elements := 0;

    FOR index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO
      CASE selector.key OF
      = cmc$select_by_type =

        IF cmv$physical_configuration^ [index].element_type = selector.element_type THEN
          number_of_elements := number_of_elements + 1;
        IFEND;
      = cmc$select_by_product =
        IF selector.product_id.model_number = '   ' THEN
          IF cmv$physical_configuration^ [index].product_id.product_number =
                selector.product_id.product_number THEN
            number_of_elements := number_of_elements + 1;
          IFEND;
        ELSE

          IF cmv$physical_configuration^ [index].product_id = selector.product_id THEN
            number_of_elements := number_of_elements + 1;
          IFEND;
        IFEND;
      = cmc$select_by_device_class =

        IF (cmv$physical_configuration^ [index].element_type <> cmc$data_channel_element) AND
              (cmv$physical_configuration^ [index].element_type <> cmc$controller_element) THEN

          cmp$get_unit_type (cmv$physical_configuration^ [index].product_id, unit_type, io_unit_type,
                unit_class, found);

          CASE unit_class OF
          = cmc$magnetic_tape_unit =
            class := rmc$magnetic_tape_device;
          = cmc$mass_storage_unit =
            class := rmc$mass_storage_device;
          = cmc$network_unit =
            class := rmc$network_device;
          = cmc$rhfam_unit =
            class := rmc$rhfam_device;
          ELSE
            class := rmc$null_device;
          CASEND;
          IF (NOT found) AND (cmv$physical_configuration^ [index].element_type =
                cmc$storage_device_element) THEN
            class := rmc$mass_storage_device;
          IFEND;
          IF class = selector.device_class THEN
            number_of_elements := number_of_elements + 1;
          IFEND;
        IFEND;
      = cmc$select_all =

        IF (cmv$physical_configuration^ [index].element_type <> cmc$data_channel_element) THEN
          number_of_elements := number_of_elements + 1;
        IFEND;


      ELSE
        ;
      CASEND;

    FOREND;

    IF number_of_elements = 0 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_elements_not_found, ' ', status);
      RETURN; {----->
    IFEND;

  PROCEND cmp$get_number_of_elements;
?? OLDTITLE ??
?? NEWTITLE := '   cmp$get_element_names', EJECT ??

*copyc cmh$get_element_names

  PROCEDURE [XDCL, #GATE] cmp$get_element_names
    (    selector: cmt$element_selector;
         elements: ^array [ * ] of cmt$element_name;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      class: rmt$device_class,
      unit_type: cmt$unit_type,
      found: boolean,
      io_unit_type: iot$unit_type,
      unit_class: cmt$unit_class,
      number_of_elements,
      index: integer;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_ELEMENT_NAMES', status);
      RETURN; {----->
    IFEND;
    status.normal := TRUE;

    IF elements = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_nil_pointer_detected,
            'CMP$GET_ELEMENT_NAMES', status);
      RETURN; {----->
    IFEND;
    FOR index := LOWERBOUND (elements^) TO UPPERBOUND (elements^) DO
      elements^ [index] := osc$null_name;
    FOREND;


    number_of_elements := 0;
    FOR index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO
      CASE selector.key OF
      = cmc$select_by_type =

        IF cmv$physical_configuration^ [index].element_type = selector.element_type THEN
          number_of_elements := number_of_elements + 1;
          elements^ [number_of_elements] := cmv$physical_configuration^ [index].element_name;
        IFEND;
      = cmc$select_by_product =
        IF selector.product_id.model_number = '   ' THEN
          IF cmv$physical_configuration^ [index].product_id.product_number =
                selector.product_id.product_number THEN
            number_of_elements := number_of_elements + 1;
            elements^ [number_of_elements] := cmv$physical_configuration^ [index].element_name;
          IFEND;
        ELSE

          IF cmv$physical_configuration^ [index].product_id = selector.product_id THEN
            number_of_elements := number_of_elements + 1;
            elements^ [number_of_elements] := cmv$physical_configuration^ [index].element_name;
          IFEND;
        IFEND;
      = cmc$select_by_device_class =

        IF (cmv$physical_configuration^ [index].element_type <> cmc$data_channel_element) AND
              (cmv$physical_configuration^ [index].element_type <> cmc$controller_element) THEN

          cmp$get_unit_type (cmv$physical_configuration^ [index].product_id, unit_type, io_unit_type,
                unit_class, found);

          CASE unit_class OF
          = cmc$magnetic_tape_unit =
            class := rmc$magnetic_tape_device;
          = cmc$mass_storage_unit =
            class := rmc$mass_storage_device;
          = cmc$network_unit =
            class := rmc$network_device;
          = cmc$rhfam_unit =
            class := rmc$rhfam_device;
          ELSE
            class := rmc$null_device;
          CASEND;
          IF (NOT found) AND (cmv$physical_configuration^ [index].element_type =
                cmc$storage_device_element) THEN
            class := rmc$mass_storage_device;
          IFEND;
          IF class = selector.device_class THEN
            number_of_elements := number_of_elements + 1;
            elements^ [number_of_elements] := cmv$physical_configuration^ [index].element_name;
          IFEND;
        IFEND;
      = cmc$select_all =

        IF (cmv$physical_configuration^ [index].element_type <> cmc$data_channel_element) THEN
          number_of_elements := number_of_elements + 1;
          elements^ [number_of_elements] := cmv$physical_configuration^ [index].element_name;
        IFEND;


      ELSE
        ;
      CASEND;
      IF number_of_elements >= UPPERBOUND (elements^) THEN
        RETURN; {----->
      IFEND;
    FOREND;

  PROCEND cmp$get_element_names;
?? OLDTITLE ??
?? NEWTITLE := '   cmp$get_iou_definition ', EJECT ??

*copyc cmh$get_iou_definition

  PROCEDURE [XDCL, #GATE] cmp$get_iou_definition
    (    iou_name: cmt$element_name;
     VAR iou_definition: cmt$iou_definition;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      iou_def: cmt$iou_definition;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_IOU_DEFINITION', status);
      RETURN; {----->
    IFEND;
    status.normal := TRUE;
    cmp$retrieve_iou_definition (iou_name, iou_def, status);
    IF status.normal THEN
      iou_definition := iou_def;
    IFEND;
  PROCEND cmp$get_iou_definition;

?? OLDTITLE ??
?? NEWTITLE := '   cmp$get_pp_definition', EJECT ??

*copyc cmh$get_pp_definition

  PROCEDURE [XDCL, #GATE] cmp$get_pp_definition
    (    pp_identification: cmt$pp_descriptor;
     VAR pp_definition: cmt$pp_definition;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      pp_id: cmt$pp_descriptor,
      pp_def: cmt$pp_definition;

    #CALLER_ID (caller_id);
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR avp$system_displays () OR
          (caller_id.ring <= 6)) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$lcm_ring_validation_error,
            'CMP$GET_PP_DEFINITION', status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;
    pp_id := pp_identification;
    cmp$get_pp_def (pp_id, pp_def, status);
    IF status.normal THEN
      pp_definition := pp_def;
    IFEND;

  PROCEND cmp$get_pp_definition;
?? OLDTITLE ??
?? NEWTITLE := '  cmp$multiple_iou_system', EJECT ??
*copyc cmh$multiple_iou_system

  FUNCTION [XDCL, #GATE, UNSAFE] cmp$multiple_iou_system: boolean;

    cmp$multiple_iou_system := f$multiple_iou_system ();

  FUNCEND cmp$multiple_iou_system;
?? OLDTITLE ??
?? NEWTITLE := 'CMP$SYSTEM_CRITICAL', EJECT ??

{ PURPOSE:
{   This procedure determines whether or not an element is system critical.

  PROCEDURE [XDCL] cmp$system_critical
    (    element: cmt$element_definition;
     VAR system_critical: boolean;
     VAR status: ost$status);

    VAR
      ch_port: integer,
      ch_state: cmt$element_state,
      channel_element: ^cmt$element_definition,
      channels_on: integer,
      cio_channel_name: cmt$element_name,
      controller_type: cmt$controller_type,
      dual_access: boolean,
      eq_element: ^cmt$element_definition,
      eq_index: integer,
      ignore_status: ost$status,
      iou_name: cmt$element_name,
      logical_pp: iot$pp_number,
      logical_unit: iot$logical_unit,
      mainframe_id: pmt$mainframe_id,
      non_dual_access_controller: boolean,
      other_channel: ^cmt$element_definition,
      other_equipment: ^cmt$element_definition,
      other_logical_pp: iot$pp_number,
      port: integer,
      state: cmt$element_state,
      system_device: boolean,
      unit_element: ^cmt$element_definition,
      unit_index: integer;

?? NEWTITLE := 'F$SYSTEM_DEVICE', EJECT ??

    FUNCTION f$system_device
      (    logical_unit: iot$logical_unit): boolean;

      VAR
        avt_entry_not_found: boolean,
        ignore_status: ost$status,
        ms_class_info: cmt$ms_class_info,
        rec_vsn: rmt$recorded_vsn,
        search_key: dmt$avt_search_key,
        set_name: stt$set_name,
        volume_found: boolean;

      f$system_device := FALSE;

      IF logical_unit <> 0 THEN
        search_key.value := dmc$search_avt_by_lun;
        search_key.logical_unit_number := logical_unit;
        cmp$search_active_volume_table (search_key, rec_vsn, avt_entry_not_found);

        IF NOT avt_entry_not_found THEN
          stp$get_volumes_set_name (rec_vsn, set_name, ignore_status);
          cmp$get_ms_class_on_volume_r1 (rec_vsn, volume_found, ms_class_info);
          f$system_device := volume_found AND ms_class_info.allocation_allowed AND
                ((ms_class_info.classes ['J'] AND (set_name = stv$system_set_name)) OR
                ms_class_info.classes ['Q']);
        IFEND;
      IFEND;

    FUNCEND f$system_device;
?? OLDTITLE ??
?? EJECT ??

    system_critical := FALSE;
    system_device := FALSE;
    dual_access := FALSE;
    status.normal := TRUE;

    pmp$get_mainframe_id (mainframe_id, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    CASE element.element_type OF
    = cmc$data_channel_element =
      cmp$pc_get_element (element.element_name, element.data_channel.iou, channel_element, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      cmp$get_logical_pp_index (channel_element^, logical_pp, ignore_status);
      IF NOT ignore_status.normal THEN
        {
        { Element defined, but no PP Table entry.  i.e. forgein equipment defined but cmp$execute_pp_program
        { has not been executed yet.  Ignore status and return NOT system critical.
        {
        RETURN; {----->
      IFEND;

    /equipment_loop_0/
      FOR eq_index := LOWERVALUE (cmt$physical_equipment_number)
            TO UPPERVALUE (cmt$physical_equipment_number) DO
        IF element.data_channel.connection.equipment [eq_index].configured THEN
          cmp$pc_get_element (element.data_channel.connection.equipment [eq_index].element_name, iou_name,
                eq_element, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          IF eq_element^.element_type = cmc$storage_device_element THEN { Hydra }
            cmp$get_logical_unit_number (eq_element^.element_name, logical_unit, status);
            IF NOT status.normal THEN
              RETURN; {----->
            IFEND;

            system_device := f$system_device (logical_unit);
            IF system_device THEN
              EXIT /equipment_loop_0/; {----->
            IFEND;

          ELSEIF eq_element^.element_type = cmc$controller_element THEN

          /unit_loop_0/
            FOR unit_index := LOWERVALUE (cmt$physical_unit_number)
                  TO UPPERVALUE (cmt$physical_unit_number) DO
              IF eq_element^.controller.connection.unit [unit_index].configured THEN
                cmp$pc_get_element (eq_element^.controller.connection.unit [unit_index].element_name,
                      iou_name, unit_element, status);
                IF NOT status.normal THEN
                  RETURN; {----->
                IFEND;

                cmp$get_logical_unit_number (unit_element^.element_name, logical_unit, status);
                IF NOT status.normal THEN
                  RETURN; {----->
                IFEND;

                IF (logical_unit <> 0) AND (cmv$logical_pp_table_p^ [logical_pp].pp_info.
                      pp_interface_table_p^.unit_descriptors [logical_unit].unit_interface_table_rma <>
                      0) THEN
                  system_device := f$system_device (logical_unit);
                  IF system_device THEN
                    EXIT /equipment_loop_0/; {----->
                  IFEND;
                IFEND;
              IFEND;
            FOREND /unit_loop_0/;
          ELSE
            RETURN; {----->
          IFEND;
        IFEND;
      FOREND /equipment_loop_0/;

{ IF NOT system_device THEN check another port of the channel

      IF NOT system_device THEN
        cio_channel_name := ' ';
        IF (element.element_name (5) = 'A') OR (element.element_name (5) = 'B') THEN
          cio_channel_name := element.element_name;
          IF (element.element_name (5) = 'A') THEN
            cio_channel_name (5) := 'B';
          ELSE
            cio_channel_name (5) := 'A';
          IFEND;

          cmp$pc_get_element (cio_channel_name, element.data_channel.iou, channel_element, ignore_status);

          IF ignore_status.normal THEN
            cmp$get_element_state (cio_channel_name, channel_element^.data_channel.iou, ch_state,
                  ignore_status);
            IF ch_state = cmc$on THEN

            /equipment_loop_1/
              FOR eq_index := LOWERVALUE (cmt$physical_equipment_number)
                    TO UPPERVALUE (cmt$physical_equipment_number) DO
                IF channel_element^.data_channel.connection.equipment [eq_index].configured THEN
                  cmp$pc_get_element (channel_element^.data_channel.connection.equipment [eq_index].
                        element_name, iou_name, eq_element, status);
                  IF NOT status.normal THEN
                    RETURN; {----->
                  IFEND;

                  IF eq_element^.element_type = cmc$storage_device_element THEN { Hydra }
                    cmp$get_logical_unit_number (eq_element^.element_name, logical_unit, status);
                    IF NOT status.normal THEN
                      RETURN; {----->
                    IFEND;

                    system_device := f$system_device (logical_unit);
                    IF system_device THEN
                      EXIT /equipment_loop_1/; {----->
                    IFEND;

                  ELSEIF eq_element^.element_type = cmc$controller_element THEN

                  /unit_loop_1/
                    FOR unit_index := LOWERVALUE (cmt$physical_unit_number)
                          TO UPPERVALUE (cmt$physical_unit_number) DO
                      IF eq_element^.controller.connection.unit [unit_index].configured THEN
                        cmp$pc_get_element (eq_element^.controller.connection.unit [unit_index].element_name,
                              iou_name, unit_element, status);
                        IF NOT status.normal THEN
                          RETURN; {----->
                        IFEND;

                        cmp$get_logical_unit_number (unit_element^.element_name, logical_unit, status);
                        IF NOT status.normal THEN
                          RETURN; {----->
                        IFEND;

                        system_device := f$system_device (logical_unit);
                        IF system_device THEN
                          EXIT /equipment_loop_1/; {----->
                        IFEND;
                      IFEND;
                    FOREND /unit_loop_1/;
                  ELSE
                    RETURN; {----->
                  IFEND;
                IFEND;
              FOREND /equipment_loop_1/;
            IFEND; { CHANNEL is ON }
          IFEND; { Normal status from cmp$pc_get_element }
        IFEND;
      IFEND;

      IF system_device THEN

        logical_pp := 0; { IF PPIT not built at deadstart. }
        cmp$get_logical_pp_index (channel_element^, logical_pp, ignore_status);

        IF eq_element^.element_type = cmc$storage_device_element THEN { Hydra }

        /port_loop_1/
          FOR port := LOWERVALUE (cmt$data_storage_port_number)
                TO UPPERVALUE (cmt$data_storage_port_number) DO
            IF eq_element^.storage_device.connection.port [port].configured THEN
              IF ((eq_element^.storage_device.connection.port [port].element_name <>
                    channel_element^.element_name) OR (eq_element^.storage_device.connection.port [port].
                    iou <> channel_element^.data_channel.iou)) AND
                    (eq_element^.storage_device.connection.port [port].mainframe_ownership =
                    channel_element^.data_channel.mainframe_ownership) THEN
                cmp$get_element_state (eq_element^.storage_device.connection.port [port].element_name,
                      eq_element^.storage_device.connection.port [port].iou, state, status);
                IF NOT status.normal THEN
                  RETURN; {----->
                IFEND;
                IF state = cmc$on THEN
                  cmp$pc_get_element (eq_element^.storage_device.connection.port [port].element_name,
                        eq_element^.storage_device.connection.port [port].iou, other_channel, status);
                  IF NOT status.normal THEN
                    RETURN; {----->
                  IFEND;

                  cmp$get_logical_pp_index (other_channel^, other_logical_pp, ignore_status);
                  IF ignore_status.normal THEN { PPIT build at deadstart. }
                    IF logical_pp <> other_logical_pp THEN { CCH#A and CCH#B have the same PPIT. }
                      dual_access := TRUE;
                      EXIT /port_loop_1/; {----->
                    IFEND;
                  IFEND;
                IFEND;
              IFEND;
            IFEND;
          FOREND /port_loop_1/;
        ELSEIF eq_element^.element_type = cmc$controller_element THEN

        /port_loop_2/
          FOR port := LOWERVALUE (cmt$data_storage_port_number)
                TO UPPERVALUE (cmt$data_storage_port_number) DO
            IF (unit_element^.storage_device.connection.port [port].configured) THEN
              IF unit_element^.storage_device.connection.port [port].element_name <>
                    eq_element^.element_name THEN

{ Dual controllers to system device.

                cmp$get_element_state (unit_element^.storage_device.connection.port [port].element_name,
                      iou_name, state, status);
                IF NOT status.normal THEN
                  RETURN; {----->
                IFEND;

                IF state = cmc$on THEN

{ Check the state of all channels connected to this equipment

                  cmp$pc_get_element (unit_element^.storage_device.connection.port [port].element_name,
                        iou_name, other_equipment, status);
                  IF NOT status.normal THEN
                    RETURN; {----->
                  IFEND;

                  FOR ch_port := LOWERVALUE (cmt$controller_port_number)
                        TO UPPERVALUE (cmt$controller_port_number) DO
                    IF other_equipment^.controller.connection.port [ch_port].configured THEN
                      IF ((other_equipment^.controller.connection.port [ch_port].element_name <>
                            channel_element^.element_name) OR (other_equipment^.controller.connection.
                            port [ch_port].iou <> channel_element^.data_channel.iou)) AND
                            (eq_element^.controller.connection.port [ch_port].mainframe_ownership =
                            channel_element^.data_channel.mainframe_ownership) THEN
                        cmp$get_element_state (other_equipment^.controller.connection.port [ch_port].
                              element_name, other_equipment^.controller.connection.port [ch_port].iou,
                              ch_state, status);
                        IF NOT status.normal THEN
                          RETURN; {----->
                        IFEND;

                        IF ch_state = cmc$on THEN
                          cmp$pc_get_element (other_equipment^.controller.connection.port [ch_port].
                                element_name, other_equipment^.controller.connection.port [ch_port].iou,
                                other_channel, status);
                          IF NOT status.normal THEN
                            RETURN; {----->
                          IFEND;

                          cmp$get_logical_pp_index (other_channel^, other_logical_pp, ignore_status);
                          IF ignore_status.normal THEN { PPIT build at deadstart. }
                            IF other_logical_pp <> logical_pp THEN { CCH#A and CCH#B have same PPIT. }
                              dual_access := TRUE;
                              EXIT /port_loop_2/; {----->
                            IFEND;
                          IFEND;
                        IFEND;
                      IFEND;
                    IFEND;
                  FOREND;
                IFEND;
              IFEND;
            IFEND;
          FOREND /port_loop_2/;

{ Not dual controller access, so check if dual channel access
{ unless type of controller is non dual access.

          IF NOT dual_access THEN

            cmp$get_controller_type (eq_element^.product_id, controller_type, status);
            IF NOT status.normal THEN
              RETURN; {----->
            IFEND;

            non_dual_access_controller := (controller_type = cmc$ms7155_1) OR
                  (controller_type = cmc$ms7155_1x) OR (controller_type = cmc$mscm3_ct) OR
                  (controller_type = cmc$ms7154_x) OR (controller_type = cmc$ms7255_1_1) OR
                  (controller_type = cmc$ms7255_1_2);

            IF NOT non_dual_access_controller THEN

            /port_loop_3/
              FOR port := LOWERVALUE (cmt$controller_port_number)
                    TO UPPERVALUE (cmt$controller_port_number) DO
                IF (eq_element^.controller.connection.port [port].configured) AND
                      (eq_element^.controller.connection.port [port].mainframe_ownership = mainframe_id) THEN
                  IF (eq_element^.controller.connection.port [port].element_name <>
                        channel_element^.element_name) OR (eq_element^.controller.connection.port [port].
                        iou <> channel_element^.data_channel.iou) THEN
                    cmp$get_element_state (eq_element^.controller.connection.port [port].element_name,
                          eq_element^.controller.connection.port [port].iou, state, status);
                    IF NOT status.normal THEN
                      RETURN; {----->
                    IFEND;

                    IF state = cmc$on THEN
                      cmp$pc_get_element (eq_element^.controller.connection.port [port].element_name,
                            eq_element^.controller.connection.port [port].iou, other_channel, status);
                      IF NOT status.normal THEN
                        RETURN; {----->
                      IFEND;

                      cmp$get_logical_pp_index (other_channel^, other_logical_pp, ignore_status);
                      IF ignore_status.normal THEN { PPIT build at deadstart. }
                        IF other_logical_pp <> logical_pp THEN { CCH#A and CCH#B have same PPIT. }
                          dual_access := TRUE;
                          EXIT /port_loop_3/; {----->
                        IFEND;
                      IFEND;
                    IFEND;
                  IFEND;
                IFEND;
              FOREND /port_loop_3/;
            IFEND;
          IFEND;
        ELSE
          RETURN; {----->
        IFEND;
      IFEND;

      system_critical := (system_device) AND (NOT dual_access);

    = cmc$controller_element =

    /unit_loop_2/
      FOR unit_index := LOWERVALUE (cmt$physical_unit_number) TO UPPERVALUE (cmt$physical_unit_number) DO
        IF element.controller.connection.unit [unit_index].configured THEN
          cmp$pc_get_element (element.controller.connection.unit [unit_index].element_name, iou_name,
                unit_element, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          cmp$get_logical_unit_number (unit_element^.element_name, logical_unit, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          system_device := f$system_device (logical_unit);
          IF system_device THEN
            EXIT /unit_loop_2/; {----->
          IFEND;
        IFEND;
      FOREND /unit_loop_2/;

      IF system_device THEN

      /port_loop_4/
        FOR port := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
          IF (unit_element^.storage_device.connection.port [port].configured) THEN
            IF unit_element^.storage_device.connection.port [port].element_name <> element.element_name THEN
              cmp$get_element_state (unit_element^.storage_device.connection.port [port].element_name,
                    iou_name, state, status);
              IF NOT status.normal THEN
                RETURN; {----->
              IFEND;

              IF state = cmc$on THEN

{ Check the state of all channels connected to this equipment

                cmp$pc_get_element (unit_element^.storage_device.connection.port [port].element_name,
                      iou_name, other_equipment, status);
                IF NOT status.normal THEN
                  RETURN; {----->
                IFEND;

                FOR ch_port := LOWERVALUE (cmt$controller_port_number)
                      TO UPPERVALUE (cmt$controller_port_number) DO
                  IF other_equipment^.controller.connection.port [ch_port].configured THEN

{ Do not care if other_equipment.channel = element.channel

                    cmp$get_element_state (other_equipment^.controller.connection.port [ch_port].element_name,
                          other_equipment^.controller.connection.port [ch_port].iou, ch_state, status);
                    IF NOT status.normal THEN
                      RETURN; {----->
                    IFEND;

                    IF ch_state = cmc$on THEN
                      cmp$pc_get_element (other_equipment^.controller.connection.port [ch_port].element_name,
                            other_equipment^.controller.connection.port [ch_port].iou, other_channel, status);
                      IF NOT status.normal THEN
                        RETURN; {----->
                      IFEND;

                      cmp$get_logical_pp_index (other_channel^, other_logical_pp, ignore_status);
                      IF ignore_status.normal THEN { PPIT build at deadstart. }

{ CCH#A and CCH#B have same PPIT does not count in this case.

                        dual_access := TRUE;
                        EXIT /port_loop_4/; {----->
                      IFEND;
                    IFEND;
                  IFEND;
                FOREND;
              IFEND;
            IFEND;
          IFEND;
        FOREND /port_loop_4/;

{ Not dual controller access, so check if dual channel access ?
{ No, if element is controller, dual channel access does not count.

      IFEND;

      system_critical := (system_device) AND (NOT dual_access);

    = cmc$storage_device_element =

      cmp$get_logical_unit_number (element.element_name, logical_unit, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      system_critical := f$system_device (logical_unit);
    ELSE
      ;
    CASEND;

  PROCEND cmp$system_critical;
?? OLDTITLE ??
MODEND cmm$config_status_interfaces

