?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE : Manage CM Tables Ring 1' ??
MODULE cmm$manage_cm_tables_r1;
?? RIGHT := 110 ??

{ PURPOSE:
{   This module contains interfaces that build and update Mainframe Wired data structures for Configuration
{   Management.
{
{ DESIGN:
{   The data structures managed in this module are mainly used to allow job(s) to reserve certain elements
{   in the physical configuration or even not present in the configuration at all.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$mainframe_paged_literal
*copyc cmc$logical_unit_constants
*copyc dmc$cti_device_type_numbers
*copyc cme$logical_configuration_mgr
*copyc cme$manage_interface_tables
*copyc cme$physical_configuration_mgr
*copyc cme$reserve_element
*copyc mse$request_maintenance_access
*copyc cmt$connection
*copyc cmt$controller_type
*copyc cmt$device_information
*copyc cmt$element_descriptor
*copyc cmt$element_reservation
*copyc cmt$mass_storage_information
*copyc dst$device_path
*copyc dst$iou_resource
*copyc dst$resource_request_types
*copyc iot$pp_number
*copyc jmt$system_supplied_name
*copyc ost$global_task_id
*copyc pmt$mainframe_id
?? POP ??
*copyc cmp$clear_unit_shared
*copyc cmp$convert_channel_number
*copyc cmp$convert_channel_ordinal
*copyc cmp$convert_iou_name
*copyc cmp$convert_iou_number
*copyc cmp$crack_physical_address
*copyc cmp$determine_active_connection
*copyc cmp$format_error_message
*copyc cmp$get_channel_def
*copyc cmp$get_controller_type
*copyc cmp$get_driver_state
*copyc cmp$get_element_name_via_lun
*copyc cmp$get_element_state
*copyc cmp$get_logical_pp_index
*copyc cmp$get_logical_unit_number
*copyc cmp$get_max_number_of_pp
*copyc cmp$get_unit_type
*copyc cmp$locate_element_via_adr
*copyc cmp$locate_element_via_lun
*copyc cmp$locate_element_via_name
*copyc cmp$pc_get_element
*copyc cmp$pc_get_logical_unit
*copyc cmp$request_channels
*copyc cmp$search_peripheral_table
*copyc cmp$set_unit_shared
*copyc dsp$retrieve_iou_information
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$clear_signature_lock
*copyc osp$free_heap_pages
*copyc osp$set_signature_lock
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc pmp$get_job_names
*copyc pmp$zero_out_table
*copyc cmv$configuration_activated
*copyc cmv$data_channel_address
*copyc cmv$iou_table_p
*copyc cmv$logical_pp_table_lock
*copyc cmv$logical_pp_table_p
*copyc cmv$logical_unit_lock
*copyc cmv$logical_unit_table
*copyc cmv$max_number_of_pp
*copyc cmv$peripheral_element_table
*copyc cmv$physical_configuration
*copyc cmv$state_info_table
*copyc iov$initial_queue_lock_sc
*copyc osv$mainframe_wired_cb_heap
*copyc pmv$mainframe_id
*copyc i#real_memory_address
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    c$init_peripheral_element_entry: [READ, oss$mainframe_paged_literal] cmt$peripheral_element_entry := [
{ element_name                  } osc$null_name,
{ product_id                    } ['      ', ' ', '   '],
{ serial_number                 } '      ',
{ logical_unit_number           } 0,
{ element_status                } [cmc$off, FALSE],
{ gtid                          } [4095, 255],
{ maintenance_activity          } [msc$concurrent_access, NIL],
{ physical_descriptor           } [FALSE,
{   hardware_address              } [$cmt$physical_address_specifier [],
{     iou                           } 0,
{     channel                       } [0, cmc$unspecified_port, FALSE],
{     channel_address               } 0,
{     unit_address                  } 0]],
{ entry_interlock               } FALSE,
{ state_change_request          } [FALSE],
{ reservable_element            } cmc$reservable,
{ reserved_status               } FALSE];

?? NEWTITLE := 'check_active_path', EJECT ??

  PROCEDURE check_active_path
    (    equipment_number: cmt$physical_equipment_number;
         mass_storage: cmt$mass_storage_information;
     VAR active_path: boolean);

    VAR
      channel_element_p: ^cmt$element_definition,
      channel_name: cmt$element_name,
      channel_ordinal: cmt$channel_ordinal,
      controller_element_p: ^cmt$element_definition,
      equipment: array [cmt$physical_equipment_number] of cmt$element_connection,
      iou_name: cmt$element_name,
      local_status: ost$status,
      state: cmt$element_state,
      valid: boolean;

    active_path := FALSE;

    cmp$convert_iou_number (mass_storage.iou_number, iou_name, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$convert_channel_number (mass_storage.channel.number, mass_storage.channel.concurrent,
          mass_storage.channel.port, channel_ordinal, channel_name, valid);
    cmp$pc_get_element (channel_name, iou_name, channel_element_p, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$get_element_state (channel_element_p^.element_name, channel_element_p^.data_channel.iou, state,
          local_status);
    IF NOT local_status.normal OR (state <> cmc$on) THEN
      RETURN; {----->
    IFEND;
    equipment := channel_element_p^.data_channel.connection.equipment;

    CASE mass_storage.unit_type OF
    = cmc$ms844_4x, cmc$ms885_1x, cmc$ms885_4x =
      IF equipment [equipment_number].configured THEN
        cmp$pc_get_element (equipment [equipment_number].element_name, {not used} iou_name,
              controller_element_p, local_status);
      IFEND;

    = cmc$ms895_2 =
      IF equipment [mass_storage.storage_director_address].configured THEN
        cmp$pc_get_element (equipment [mass_storage.storage_director_address].element_name,
              {not used} iou_name, controller_element_p, local_status);
      IFEND;

    = cmc$ms834_2, cmc$msfsd_2, cmc$msxmd_3, cmc$ms5832_1, cmc$ms5832_2, cmc$ms5833_1, cmc$ms5833_1p,
          cmc$ms5833_2, cmc$ms5833_3p, cmc$ms5833_4, cmc$ms5837_1, cmc$ms5837_1p, cmc$ms5837_2, cmc$ms5837_3p,
          cmc$ms5837_4, cmc$ms5838_1, cmc$ms5838_1p, cmc$ms5838_2, cmc$ms5838_3p, cmc$ms5838_4, cmc$ms47444_1,
          cmc$ms47444_1p, cmc$ms47444_2, cmc$ms47444_3p, cmc$ms47444_4, cmc$ms_ntdd_1, cmc$ms_ntdd_2,
          cmc$ms_ntdd_3, cmc$ms_ntdd_4, cmc$ms_ntdd_5, cmc$ms_ntdd_6 =
      IF equipment [mass_storage.control_module].configured THEN
        cmp$pc_get_element (equipment [mass_storage.control_module].element_name, {not used} iou_name,
              controller_element_p, local_status);
      IFEND;
    ELSE
    CASEND;
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

    active_path := TRUE;

  PROCEND check_active_path;
?? OLDTITLE ??
?? NEWTITLE := 'UNMARK_PP_ELEMENT', EJECT ??

{ PURPOSE:
{   This procedure unmarks an element in the logical PP table.

  PROCEDURE unmark_pp_element
    (    table_index: integer;
         cleanup: boolean);

    VAR
      entry_p: ^cmt$logical_pp_table_entry,
      first_lun: iot$logical_unit,
      local_status: ost$status,
      logical_unit_p: ^cmt$logical_unit,
      lun_index: iot$logical_unit,
      mf_element_p: ^cmt$element_definition,
      need_to_free_commun_buffer: boolean,
      number_of_units: iot$logical_unit,
      unit_descriptor_entry_p: ^iot$unit_descriptor_entry;

    entry_p := ^cmv$logical_pp_table_p^ [table_index];
    IF entry_p^.flags.reservd_by_other_has_ch_present THEN
      update_ch_connection_status (table_index);
    IFEND;

    entry_p^.flags.entry_in_use := FALSE;
    entry_p^.flags.entry_reserved_by_other := FALSE;
    entry_p^.flags.entry_reserved_by_system_job := FALSE;
    entry_p^.flags.reservd_by_other_has_ch_present := FALSE;
    entry_p^.task_info.gtid.index := 4095;
    entry_p^.task_info.gtid.seqno := 255;
    entry_p^.task_info.reserved_job_name := '';
    entry_p^.pp_info.physical_pp.iou_number := 0;
    entry_p^.pp_info.physical_pp.number := 33(8);
    entry_p^.pp_info.physical_pp.channel_protocol := dsc$cpt_nio;
    need_to_free_commun_buffer := (entry_p^.pp_info.cip_driver_name = 'NETW') OR
          (entry_p^.pp_info.cip_driver_name = 'ICAD') OR (entry_p^.pp_info.cip_driver_name = 'NPDR') OR
          (entry_p^.pp_info.cip_driver_name = 'NDI0') OR (entry_p^.pp_info.cip_driver_name = 'IVB0') OR
          (entry_p^.pp_info.cip_driver_name = 'IVB4') OR (entry_p^.pp_info.cip_driver_name = 'ESMD');
    entry_p^.pp_info.driver_name := ' ';
    entry_p^.pp_info.cip_driver_name := ' ';
    entry_p^.controller_info.controller_type := cmc$null_controller;

    IF NOT entry_p^.flags.configured THEN
      RETURN; {----->
    IFEND;

    entry_p^.flags.configured := FALSE;
    entry_p^.flags.pp_loaded := FALSE;
    IF need_to_free_commun_buffer AND (entry_p^.pp_info.pp_communication_buffer_p <> NIL) THEN
      FREE entry_p^.pp_info.pp_communication_buffer_p IN osv$mainframe_wired_cb_heap^;
    IFEND;

{ Free response_buffer
    IF entry_p^.pp_info.pp_interface_table_p^.response_buffer <> NIL THEN
      FREE entry_p^.pp_info.pp_interface_table_p^.response_buffer IN osv$mainframe_wired_cb_heap^;
    IFEND;

    number_of_units := entry_p^.pp_info.pp_interface_table_p^.number_of_units;
    first_lun := entry_p^.pp_info.pp_interface_table_p^.first_logical_unit;

    FOR lun_index := first_lun TO (number_of_units + first_lun - 1) DO
      unit_descriptor_entry_p := ^entry_p^.pp_info.pp_interface_table_p^.unit_descriptors [lun_index];

      IF (unit_descriptor_entry_p^.logical_unit <> 0)
{   } AND (unit_descriptor_entry_p^.unit_interface_table <> NIL) THEN
        cmp$pc_get_logical_unit (lun_index, mf_element_p, local_status);

        IF NOT local_status.normal THEN
{ NOT in active configuration.
          logical_unit_p := ^cmv$logical_unit_table^ [lun_index];
          logical_unit_p^.configured := FALSE;
          logical_unit_p^.logical_unit_number := 0;
          IF logical_unit_p^.unit_interface_table <> NIL THEN
            FREE logical_unit_p^.unit_interface_table IN osv$mainframe_wired_cb_heap^;
          IFEND;
          IF logical_unit_p^.unit_communication_buffer_pva <> NIL THEN
            FREE logical_unit_p^.unit_communication_buffer_pva IN osv$mainframe_wired_cb_heap^;
          IFEND;

        ELSEIF NOT cleanup THEN { IN active configuration, then check if ICA, MDI, MTI, EXPRESSLINK or LCN. }
          IF (mf_element_p^.element_type = cmc$communications_element)
{       } OR ((mf_element_p^.element_type = cmc$channel_adapter_element) AND
                (mf_element_p^.product_id.product_number = ' $2629')) THEN

            logical_unit_p := ^cmv$logical_unit_table^ [lun_index];
            logical_unit_p^.configured := FALSE;
            IF logical_unit_p^.unit_interface_table <> NIL THEN
              FREE logical_unit_p^.unit_interface_table IN osv$mainframe_wired_cb_heap^;
            IFEND;
            IF logical_unit_p^.unit_communication_buffer_pva <> NIL THEN
              FREE logical_unit_p^.unit_communication_buffer_pva IN osv$mainframe_wired_cb_heap^;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    FOREND;

    IF entry_p^.pp_info.pp_interface_table_p <> NIL THEN
      FREE entry_p^.pp_info.pp_interface_table_p IN osv$mainframe_wired_cb_heap^;
      cmp$get_max_number_of_pp (cmv$max_number_of_pp);
      IF entry_p^.controller_info.controlware_loaded THEN
        entry_p^.controller_info.controlware_loaded := FALSE;
      IFEND;
      IF entry_p^.controller_info.control_module_loaded THEN
        entry_p^.controller_info.control_module_loaded := FALSE;
      IFEND;
    IFEND;

    osp$free_heap_pages (osv$mainframe_wired_cb_heap);

  PROCEND unmark_pp_element;
?? OLDTITLE ??
?? NEWTITLE := 'update_ch_connection_status ', EJECT ??

{ PURPOSE:
{   This procedure will call the interface cmp$update_connection_status_r1 to update connection status for
{   the specified channel.

  PROCEDURE update_ch_connection_status
    (    pp_index: iot$pp_number);

    VAR
      entry_p: ^cmt$logical_pp_table_entry,
      channel_element_def_p: ^cmt$element_definition,
      channel_name: cmt$element_name,
      channel_ordinal: cmt$channel_ordinal,
      channel_valid: boolean,
      concurrent: boolean,
      iou_name: cmt$element_name,
      local_status: ost$status;

    entry_p := ^cmv$logical_pp_table_p^ [pp_index];
    concurrent := (entry_p^.pp_info.channel.channel_protocol = dsc$cpt_cio);
    cmp$convert_channel_number (entry_p^.pp_info.channel.number, concurrent, entry_p^.pp_info.channel_port,
          channel_ordinal, channel_name, channel_valid);
    IF NOT channel_valid THEN
      RETURN; {----->
    IFEND;

    cmp$convert_iou_number (entry_p^.pp_info.channel.iou_number, iou_name, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$pc_get_element (channel_name, iou_name, channel_element_def_p, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$change_connection_status_r1 (channel_element_def_p^, pmv$mainframe_id, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

  PROCEND update_ch_connection_status;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] CMP$BUILD_ELEMENT_DEF_TABLE', EJECT ??

{ PURPOSE:
{   This procedure scans the CM mainframe pageable structure and builds the mainframe wired tables.

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

    VAR
      cm_unit_type: cmt$unit_type,
      controller_type: cmt$controller_type,
      element_definition_p: ^cmt$element_definition,
      found: boolean,
      index: integer,
      io_unit_type: iot$unit_type,
      pet_entry_p: ^cmt$peripheral_element_entry,
      state_info_p: ^cmt$state_information,
      state_table_index: integer,
      status_p: ^ost$status,
      unit_class: cmt$unit_class;

    VAR
      c$valid_peripheral_elem_entry: [READ, oss$mainframe_paged_literal] set of cmt$element_type :=
            [cmc$data_channel_element, cmc$channel_adapter_element, cmc$controller_element,
            cmc$external_processor_element, cmc$storage_device_element, cmc$communications_element];

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

    PROCEDURE p$build_channel_adapter_element
      (    channel_adapter_p: {input} ^cmt$channel_adapter_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        i: integer,
        iou_number: dst$iou_number,
        total_connections: integer;

      physical_descriptor.microcode_identification := channel_adapter_p^.microcode_identification;
      physical_descriptor.peripheral_driver_name := channel_adapter_p^.peripheral_driver_name;

      total_connections := 0;
      FOR i := LOWERBOUND (channel_adapter_p^.connection.equipment)
            TO UPPERBOUND (channel_adapter_p^.connection.equipment) DO
        IF channel_adapter_p^.connection.equipment [i].configured THEN
          total_connections := total_connections + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.equipment_path: [1 .. 1] IN osv$mainframe_wired_cb_heap^;
      ALLOCATE physical_descriptor.equipment_connection: [1 .. total_connections] IN
            osv$mainframe_wired_cb_heap^;

      IF channel_adapter_p^.connection.channel.configured THEN
        cmp$convert_iou_name (channel_adapter_p^.connection.channel.iou, iou_number, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;

        physical_descriptor.equipment_path^ [1].address_specifier := $cmt$physical_address_specifier
              [cmc$iou, cmc$channel, cmc$channel_address];
        physical_descriptor.equipment_path^ [1].iou := iou_number;
        physical_descriptor.equipment_path^ [1].channel_address :=
              channel_adapter_p^.physical_equipment_number;
        physical_descriptor.equipment_path^ [1].unit_address := 0;

        cmp$pc_get_element (channel_adapter_p^.connection.channel.element_name,
              channel_adapter_p^.connection.channel.iou, channel_element_p, status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;

        physical_descriptor.equipment_path^ [1].channel.number := channel_element_p^.data_channel.number;
        physical_descriptor.equipment_path^ [1].channel.port := channel_element_p^.data_channel.port;
        physical_descriptor.equipment_path^ [1].channel.concurrent :=
              channel_element_p^.data_channel.concurrent;

{ Create a connection_status entry for this channel adapter and each configured equipment.
        total_connections := 0;
        FOR i := LOWERBOUND (channel_adapter_p^.connection.equipment)
              TO UPPERBOUND (channel_adapter_p^.connection.equipment) DO
          IF channel_adapter_p^.connection.equipment [i].configured THEN
            total_connections := total_connections + 1;
            physical_descriptor.equipment_connection^ [total_connections].status := cmc$inactive;
            physical_descriptor.equipment_connection^ [total_connections].downline_element :=
                  channel_adapter_p^.connection.equipment [i].element_name;
          IFEND;
        FOREND;
      IFEND;

    PROCEND p$build_channel_adapter_element;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_COMMUNICATIONS_ELEMENT', EJECT ??

    PROCEDURE p$build_communications_element
      (    communications_element_p: {input} ^cmt$communications_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        configured_channels: integer,
        cpn: integer,
        iou_number: dst$iou_number,
        physical_address_p: ^cmt$physical_address;

      physical_descriptor.microcode_identification := communications_element_p^.microcode_identification;
      physical_descriptor.peripheral_driver_name := communications_element_p^.peripheral_driver_name;

      configured_channels := 0;
      FOR cpn := LOWERVALUE (cmt$communications_port_number) TO UPPERVALUE (cmt$communications_port_number) DO
        IF (communications_element_p^.connection.port [cpn].configured) AND
              (communications_element_p^.connection.port [cpn].mainframe_ownership = mainframe_id) THEN
          configured_channels := configured_channels + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.equipment_path: [1 .. configured_channels] IN osv$mainframe_wired_cb_heap^;

{ A communications element does not support downline connections.
      physical_descriptor.equipment_connection := NIL;

      configured_channels := 0;
      FOR cpn := LOWERVALUE (cmt$communications_port_number) TO UPPERVALUE (cmt$communications_port_number) DO
        IF (communications_element_p^.connection.port [cpn].configured) AND
              (communications_element_p^.connection.port [cpn].mainframe_ownership = mainframe_id) THEN
          configured_channels := configured_channels + 1;
          cmp$convert_iou_name (communications_element_p^.connection.port [cpn].iou, iou_number, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

{ Construct the physical address.
          physical_address_p := ^physical_descriptor.equipment_path^ [configured_channels];
          physical_address_p^.address_specifier := $cmt$physical_address_specifier
                [cmc$iou, cmc$channel, cmc$channel_address];
          physical_address_p^.iou := iou_number;
          physical_address_p^.channel_address := communications_element_p^.physical_equipment_number;
          physical_address_p^.unit_address := 0;

          cmp$pc_get_element (communications_element_p^.connection.port [cpn].element_name,
                communications_element_p^.connection.port [cpn].iou, channel_element_p, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          physical_address_p^.channel.number := channel_element_p^.data_channel.number;
          physical_address_p^.channel.port := channel_element_p^.data_channel.port;
          physical_address_p^.channel.concurrent := channel_element_p^.data_channel.concurrent;
        IFEND;
      FOREND;

    PROCEND p$build_communications_element;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_CONTROLLER_ELEMENT', EJECT ??

    PROCEDURE p$build_controller_element
      (    controller_p: {input} ^cmt$controller_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        configured_channels: integer,
        cpn: integer,
        i: integer,
        iou_number: dst$iou_number,
        physical_address_p: ^cmt$physical_address,
        total_connections: integer;

      physical_descriptor.microcode_identification := controller_p^.microcode_identification;
      physical_descriptor.peripheral_driver_name := controller_p^.peripheral_driver_name;

      configured_channels := 0;
      total_connections := 0;
      FOR cpn := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
        IF (controller_p^.connection.port [cpn].configured) AND
              (controller_p^.connection.port [cpn].mainframe_ownership = mainframe_id) THEN
          configured_channels := configured_channels + 1;
        IFEND;
      FOREND;

      FOR i := LOWERBOUND (controller_p^.connection.unit) TO UPPERBOUND (controller_p^.connection.unit) DO
        IF controller_p^.connection.unit [i].configured THEN
          total_connections := total_connections + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.equipment_path: [1 .. configured_channels] IN osv$mainframe_wired_cb_heap^;
      ALLOCATE physical_descriptor.equipment_connection: [1 .. total_connections] IN
            osv$mainframe_wired_cb_heap^;

      configured_channels := 0;
      total_connections := 0;
      FOR cpn := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
        IF (controller_p^.connection.port [cpn].configured) AND
              (controller_p^.connection.port [cpn].mainframe_ownership = mainframe_id) THEN
          configured_channels := configured_channels + 1;
          cmp$convert_iou_name (controller_p^.connection.port [cpn].iou, iou_number, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

{ Construct the physical address.
          physical_address_p := ^physical_descriptor.equipment_path^ [configured_channels];
          physical_address_p^.address_specifier := $cmt$physical_address_specifier
                [cmc$iou, cmc$channel, cmc$channel_address];
          physical_address_p^.iou := iou_number;
          physical_address_p^.channel_address := controller_p^.physical_equipment_number;
          physical_address_p^.unit_address := 0;

          cmp$pc_get_element (controller_p^.connection.port [cpn].element_name,
                controller_p^.connection.port [cpn].iou, channel_element_p, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          physical_address_p^.channel.number := channel_element_p^.data_channel.number;
          physical_address_p^.channel.port := channel_element_p^.data_channel.port;
          physical_address_p^.channel.concurrent := channel_element_p^.data_channel.concurrent;
        IFEND;
      FOREND;

{ Create a connection_status entry for each configured storage device element.
      FOR i := LOWERBOUND (controller_p^.connection.unit) TO UPPERBOUND (controller_p^.connection.unit) DO
        IF controller_p^.connection.unit [i].configured THEN
          total_connections := total_connections + 1;
          physical_descriptor.equipment_connection^ [total_connections].status := cmc$inactive;
          physical_descriptor.equipment_connection^ [total_connections].downline_element :=
                controller_p^.connection.unit [i].element_name;
        IFEND;
      FOREND;

    PROCEND p$build_controller_element;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_DATA_CHANNEL_ELEMENT', EJECT ??

    PROCEDURE p$build_data_channel_element
      (    data_channel_p: {input} ^cmt$data_channel_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        cpn: integer,
        iou_number: dst$iou_number,
        total_connections: integer;

      total_connections := 0;
      FOR cpn := LOWERBOUND (data_channel_p^.connection.equipment)
            TO UPPERBOUND (data_channel_p^.connection.equipment) DO
        IF (data_channel_p^.connection.equipment [cpn].configured) AND
              (data_channel_p^.mainframe_ownership = mainframe_id) THEN
          total_connections := total_connections + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.channel_connection: [1 .. total_connections] IN
            osv$mainframe_wired_cb_heap^;

      cmp$convert_iou_name (data_channel_p^.iou, iou_number, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

{ Construct the physical address.
      physical_descriptor.channel_path.address_specifier := $cmt$physical_address_specifier
            [cmc$iou, cmc$channel];
      physical_descriptor.channel_path.iou := iou_number;
      physical_descriptor.channel_path.channel_address := 0;
      physical_descriptor.channel_path.unit_address := 0;
      physical_descriptor.channel_path.channel.number := data_channel_p^.number;
      physical_descriptor.channel_path.channel.port := data_channel_p^.port;
      physical_descriptor.channel_path.channel.concurrent := data_channel_p^.concurrent;
      physical_descriptor.mainframe_ownership := data_channel_p^.mainframe_ownership;

{ Create a connection_status entry for this channel and each connected element.
      total_connections := 0;
      FOR cpn := LOWERBOUND (data_channel_p^.connection.equipment)
            TO UPPERBOUND (data_channel_p^.connection.equipment) DO
        IF (data_channel_p^.connection.equipment [cpn].configured) AND
              (data_channel_p^.mainframe_ownership = mainframe_id) THEN
          total_connections := total_connections + 1;
          physical_descriptor.channel_connection^ [total_connections].status := cmc$inactive;
          physical_descriptor.channel_connection^ [total_connections].downline_element :=
                data_channel_p^.connection.equipment [cpn].element_name;
        IFEND;
      FOREND;

    PROCEND p$build_data_channel_element;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_EXTERNAL_PROCESSOR_ELEM', EJECT ??

    PROCEDURE p$build_external_processor_elem
      (    external_processor_p: {input} ^cmt$external_cpu_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        configured_channels: integer,
        cpn: integer,
        iou_number: dst$iou_number,
        physical_address_p: ^cmt$physical_address,
        upline_connection_p: ^cmt$upline_connection;

      physical_descriptor.microcode_identification := external_processor_p^.microcode_identification;
      physical_descriptor.peripheral_driver_name := external_processor_p^.peripheral_driver_name;
      configured_channels := 0;

      FOR cpn := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
        IF (external_processor_p^.connection.io_port [cpn].configured) AND
              (external_processor_p^.connection.io_port [cpn].mainframe_ownership = mainframe_id) THEN
          configured_channels := configured_channels + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.equipment_path: [1 .. configured_channels] IN osv$mainframe_wired_cb_heap^;

{ An external_processor element does not support downline connections.
      physical_descriptor.equipment_connection := NIL;

      configured_channels := 0;
      FOR cpn := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
        upline_connection_p := ^external_processor_p^.connection.io_port [cpn];
        IF (upline_connection_p^.configured) AND (upline_connection_p^.mainframe_ownership = mainframe_id)
              THEN
          configured_channels := configured_channels + 1;
          cmp$convert_iou_name (upline_connection_p^.iou, iou_number, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

{ Construct the physical address.
          physical_address_p := ^physical_descriptor.equipment_path^ [configured_channels];
          physical_address_p^.address_specifier := $cmt$physical_address_specifier
                [cmc$iou, cmc$channel, cmc$channel_address];
          physical_address_p^.iou := iou_number;
          physical_address_p^.channel_address := external_processor_p^.physical_equipment_number;
          physical_address_p^.unit_address := 0;

          cmp$pc_get_element (upline_connection_p^.element_name, upline_connection_p^.iou, channel_element_p,
                status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          physical_address_p^.channel.number := channel_element_p^.data_channel.number;
          physical_address_p^.channel.port := channel_element_p^.data_channel.port;
          physical_address_p^.channel.concurrent := channel_element_p^.data_channel.concurrent;
        IFEND;
      FOREND;

    PROCEND p$build_external_processor_elem;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_HYDRA_DEVICE_ELEMENT', EJECT ??

    PROCEDURE p$build_hydra_device_element
      (    hydra_device_p: {input} ^cmt$storage_device_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        iou_number: dst$iou_number,
        sdpn: integer,
        total_paths: integer;

      total_paths := 0;
      FOR sdpn := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        IF (hydra_device_p^.connection.port [sdpn].configured) AND
              (hydra_device_p^.connection.port [sdpn].mainframe_ownership = mainframe_id) THEN
          total_paths := total_paths + 1;
        IFEND;
      FOREND;

      ALLOCATE physical_descriptor.unit_path: [1 .. total_paths] IN osv$mainframe_wired_cb_heap^;

      total_paths := 0;
      FOR sdpn := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        IF (hydra_device_p^.connection.port [sdpn].configured) AND
              (hydra_device_p^.connection.port [sdpn].mainframe_ownership = mainframe_id) THEN

          { Construct the physical address.

          total_paths := total_paths + 1;
          cmp$convert_iou_name (hydra_device_p^.connection.port [sdpn].iou, iou_number, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
          physical_descriptor.unit_path^ [total_paths].address_specifier :=
                $cmt$physical_address_specifier [cmc$iou, cmc$channel, cmc$unit_address];
          physical_descriptor.unit_path^ [total_paths].iou := iou_number;
          physical_descriptor.unit_path^ [total_paths].channel_address := 0;
          physical_descriptor.unit_path^ [total_paths].unit_address := hydra_device_p^.physical_unit_number;

          cmp$pc_get_element (hydra_device_p^.connection.port [sdpn].element_name,
                hydra_device_p^.connection.port [sdpn].iou, channel_element_p, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          physical_descriptor.unit_path^ [total_paths].channel.number :=
                channel_element_p^.data_channel.number;
          physical_descriptor.unit_path^ [total_paths].channel.port := channel_element_p^.data_channel.port;
          physical_descriptor.unit_path^ [total_paths].channel.concurrent :=
                channel_element_p^.data_channel.concurrent;
        IFEND;
      FOREND;

    PROCEND p$build_hydra_device_element;
?? OLDTITLE ??
?? NEWTITLE := 'P$BUILD_STORAGE_DEVICE_ELEMENT', EJECT ??

    PROCEDURE p$build_storage_device_element
      (    storage_device_p: {input} ^cmt$storage_device_definition;
       VAR physical_descriptor: cmt$physical_descriptor;
       VAR status: ost$status);

      VAR
        channel_element_p: ^cmt$element_definition,
        controller_connection_p: ^cmt$upline_connection,
        controller_element: ^cmt$element_definition,
        dummy_iou: cmt$element_name,
        i: integer,
        iou_number: dst$iou_number,
        sdpn: integer,
        physical_address_p: ^cmt$physical_address,
        total_paths: integer,
        upline_connection_p: ^cmt$upline_connection;

      total_paths := 0;

    /count_paths/
      FOR sdpn := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        upline_connection_p := ^storage_device_p^.connection.port [sdpn];
        IF NOT upline_connection_p^.configured THEN
          CYCLE /count_paths/; {----->
        IFEND;

        CASE upline_connection_p^.upline_connection_type OF
        = cmc$controller_element =
          cmp$pc_get_element (upline_connection_p^.element_name, dummy_iou, controller_element, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          FOR i := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
            IF (controller_element^.controller.connection.port [i].configured) AND
                  (controller_element^.controller.connection.port [i].mainframe_ownership = mainframe_id) THEN
              total_paths := total_paths + 1;
            IFEND;
          FOREND;

        = cmc$data_channel_element =
          FOR i := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
            IF (storage_device_p^.connection.port [i].configured) AND
                  (storage_device_p^.connection.port [i].mainframe_ownership = mainframe_id) THEN
              total_paths := total_paths + 1;
            IFEND;
          FOREND;
        ELSE
        CASEND;
      FOREND /count_paths/;

      ALLOCATE physical_descriptor.unit_path: [1 .. total_paths] IN osv$mainframe_wired_cb_heap^;
      total_paths := 0;

    /build_paths_1/
      FOR sdpn := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        upline_connection_p := ^storage_device_p^.connection.port [sdpn];
        IF NOT upline_connection_p^.configured THEN
          CYCLE /build_paths_1/; {----->
        IFEND;

        CASE upline_connection_p^.upline_connection_type OF
        = cmc$controller_element =
          cmp$pc_get_element (upline_connection_p^.element_name, dummy_iou, controller_element, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

          FOR i := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
            controller_connection_p := ^controller_element^.controller.connection.port [i];
            IF (controller_connection_p^.configured)
{         } AND (controller_connection_p^.mainframe_ownership = mainframe_id) THEN

              total_paths := total_paths + 1;

              cmp$convert_iou_name (controller_connection_p^.iou, iou_number, status);
              IF NOT status.normal THEN
                RETURN; {----->
              IFEND;

              physical_address_p := ^physical_descriptor.unit_path^ [total_paths];
              physical_address_p^.address_specifier := -$cmt$physical_address_specifier [];
              physical_address_p^.iou := iou_number;
              physical_address_p^.unit_address := storage_device_p^.physical_unit_number;
              physical_address_p^.channel_address := controller_element^.controller.physical_equipment_number;

              cmp$pc_get_element (controller_connection_p^.element_name, controller_connection_p^.iou,
                    channel_element_p, status);
              IF NOT status.normal THEN
                RETURN; {----->
              IFEND;

              physical_address_p^.channel.number := channel_element_p^.data_channel.number;
              physical_address_p^.channel.port := channel_element_p^.data_channel.port;
              physical_address_p^.channel.concurrent := channel_element_p^.data_channel.concurrent;
            IFEND;
          FOREND;

        = cmc$data_channel_element =
          total_paths := 0;
          FOR i := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
            IF (storage_device_p^.connection.port [i].configured)
{         } AND (storage_device_p^.connection.port [i].mainframe_ownership = mainframe_id) THEN

              total_paths := total_paths + 1;

              cmp$convert_iou_name (storage_device_p^.connection.port [i].iou, iou_number, status);
              IF NOT status.normal THEN
                RETURN; {----->
              IFEND;

              physical_address_p := ^physical_descriptor.unit_path^ [total_paths];
              physical_address_p^.address_specifier := $cmt$physical_address_specifier
                    [cmc$iou, cmc$channel, cmc$channel_address];
              physical_address_p^.iou := iou_number;
              physical_address_p^.unit_address := 0;
              physical_address_p^.channel_address := storage_device_p^.physical_unit_number;

              cmp$pc_get_element (storage_device_p^.connection.port [i].element_name,
                    storage_device_p^.connection.port [i].iou, channel_element_p, status);
              IF NOT status.normal THEN
                RETURN; {----->
              IFEND;

              physical_address_p^.channel.number := channel_element_p^.data_channel.number;
              physical_address_p^.channel.port := channel_element_p^.data_channel.port;
              physical_address_p^.channel.concurrent := channel_element_p^.data_channel.concurrent;
            IFEND;
          FOREND;
        ELSE
        CASEND;
      FOREND /build_paths_1/;

    PROCEND p$build_storage_device_element;
?? OLDTITLE ??
?? EJECT ??
    IF cmv$physical_configuration = NIL THEN
      osp$set_status_condition (cme$active_pc_empty, status);
      RETURN; {----->
    IFEND;

{ Lock table during initialization.
    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

{ Allocate table to be the size of CMV$PHYSICAL_CONFIGURATION + 20 to make room for reservation of
{ elements not in the configuration.

    ALLOCATE cmv$peripheral_element_table.pointer: [1 .. UPPERBOUND (cmv$physical_configuration^) + 20] IN
          osv$mainframe_wired_cb_heap^;

  /pc_loop/
    FOR index := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO
      pet_entry_p := ^cmv$peripheral_element_table.pointer^ [index];
      pet_entry_p^ := c$init_peripheral_element_entry;
      element_definition_p := ^cmv$physical_configuration^ [index];

      IF NOT (element_definition_p^.element_type IN c$valid_peripheral_elem_entry) THEN
        CYCLE /pc_loop/; {----->
      IFEND;

      pet_entry_p^.element_name := element_definition_p^.element_name;
      pet_entry_p^.product_id := element_definition_p^.product_id;
      pet_entry_p^.serial_number := element_definition_p^.serial_number;
      pet_entry_p^.physical_descriptor.configured := TRUE;
      pet_entry_p^.physical_descriptor.element_type := element_definition_p^.element_type;

      { Search cmv$state_info_table to find LOGICAL_UNIT_NUMBER and ELEMENT_STATUS.

      found := FALSE;
      IF cmv$state_info_table <> NIL THEN

      /state_table_loop/
        FOR state_table_index := LOWERBOUND (cmv$state_info_table^) TO UPPERBOUND (cmv$state_info_table^) DO
          state_info_p := ^cmv$state_info_table^ [state_table_index];
          IF element_definition_p^.element_name = state_info_p^.element_name THEN
            IF element_definition_p^.element_type = cmc$data_channel_element THEN
              IF element_definition_p^.data_channel.iou <> state_info_p^.iou THEN
                CYCLE /state_table_loop/; {----->
              IFEND;
            IFEND;

            found := TRUE;
            pet_entry_p^.element_status := state_info_p^.status;
            IF element_definition_p^.element_type <> cmc$data_channel_element THEN
              pet_entry_p^.logical_unit_number := state_info_p^.logical_unit;
            IFEND;

            EXIT /state_table_loop/; {----->
          IFEND;
        FOREND /state_table_loop/;
      IFEND;

      IF NOT found THEN
        pet_entry_p^.element_status.state := cmc$off;
        pet_entry_p^.logical_unit_number := 0;
      IFEND;

      CASE element_definition_p^.element_type OF
      = cmc$data_channel_element =
        p$build_data_channel_element (^element_definition_p^.data_channel, pet_entry_p^.physical_descriptor,
              status);
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;

      = cmc$controller_element =
        cmp$get_controller_type (element_definition_p^.product_id, controller_type, status);
        IF status.normal THEN
          pet_entry_p^.reservable_element := cmc$not_reservable;
        ELSE
          status.normal := TRUE;
          pet_entry_p^.reservable_element := cmc$reservable;
        IFEND;

        p$build_controller_element (^element_definition_p^.controller, pet_entry_p^.physical_descriptor,
              status);
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;

      = cmc$external_processor_element =
        pet_entry_p^.reservable_element := cmc$not_reservable;

        p$build_external_processor_elem (^element_definition_p^.external_processor,
              pet_entry_p^.physical_descriptor, status);
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;

      = cmc$channel_adapter_element =

{ For S0/S0E, channel adapters (ICA) can only be reserved by the system.
        pet_entry_p^.reservable_element := cmc$reservable_only_by_system;
        p$build_channel_adapter_element (^element_definition_p^.channel_adapter,
              pet_entry_p^.physical_descriptor, status);
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;

      = cmc$communications_element =
        pet_entry_p^.reservable_element := cmc$reservable_only_by_system;
        p$build_communications_element (^element_definition_p^.communications_element,
              pet_entry_p^.physical_descriptor, status);
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;

      = cmc$storage_device_element =
        cmp$get_unit_type (element_definition_p^.product_id, cm_unit_type, io_unit_type, unit_class, found);
        IF found THEN
          pet_entry_p^.reservable_element := cmc$not_reservable;
        ELSE
          pet_entry_p^.reservable_element := cmc$reservable;
        IFEND;

        IF cm_unit_type = cmc$mshydra THEN
          p$build_hydra_device_element (^element_definition_p^.storage_device,
                pet_entry_p^.physical_descriptor, status);
        ELSE
          p$build_storage_device_element (^element_definition_p^.storage_device,
                pet_entry_p^.physical_descriptor, status);
        IFEND;
        IF NOT status.normal THEN
          EXIT /pc_loop/; {----->
        IFEND;
      ELSE
      CASEND;
    FOREND /pc_loop/;

    FOR index := (UPPERBOUND (cmv$physical_configuration^) + 1)
          TO UPPERBOUND (cmv$peripheral_element_table.pointer^) DO
      cmv$peripheral_element_table.pointer^ [index] := c$init_peripheral_element_entry;
    FOREND;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$build_element_def_table;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$change_connection_status_r1 ', EJECT ??

{ PURPOSE:
{   This procedure will update the connection status for all elements connected to the specified elements.
{   The new connection status will based on the states of the elements.

  PROCEDURE [XDCL, #GATE] cmp$change_connection_status_r1
    (    primary_element: cmt$element_definition;
         mainframe_id: pmt$mainframe_id;
     VAR status: ost$status);

    VAR
      downline_element_state: cmt$element_state,
      dummy_reservation: cmt$element_reservation,
      driver_present: boolean,
      element_descriptor: cmt$element_descriptor,
      i: integer,
      j: integer,
      pet_entry_p: ^cmt$peripheral_element_entry,
      pet_index: integer,
      primary_element_state: cmt$element_state,
      status_p: ^ost$status,
      upline_connection: cmt$upline_connection,
      upline_element_p: ^cmt$element_definition,
      upline_element_state: cmt$element_state;

    IF cmv$physical_configuration = NIL THEN
      osp$set_status_condition (cme$active_pc_empty, status);
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

  /main_program/
    BEGIN
      CASE primary_element.element_type OF
      = cmc$data_channel_element =
        cmp$get_element_state (primary_element.element_name, primary_element.data_channel.iou,
              primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

        element_descriptor.element_type := primary_element.element_type;
        element_descriptor.channel_descriptor.iou := primary_element.data_channel.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;
        element_descriptor.channel_descriptor.name := primary_element.element_name;

        cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
              pet_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
        pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

        FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
              TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
          cmp$get_element_state (pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element,
                osc$null_name, downline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          cmp$get_driver_state (primary_element.element_name, primary_element.data_channel.iou,
                driver_present, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          IF driver_present AND (primary_element_state = cmc$on) AND (downline_element_state = cmc$on) THEN
            pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
          ELSE
            pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
          IFEND;
        FOREND;

      = cmc$controller_element =
        cmp$get_element_state (primary_element.element_name, osc$null_name, primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

      /locate_upline_1/
        FOR i := LOWERBOUND (primary_element.controller.connection.port)
              TO UPPERBOUND (primary_element.controller.connection.port) DO
          upline_connection := primary_element.controller.connection.port [i];
          IF NOT upline_connection.configured THEN
            CYCLE /locate_upline_1/; {----->
          IFEND;

          IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
            CYCLE /locate_upline_1/; {----->
          IFEND;

          IF upline_connection.mainframe_ownership <> mainframe_id THEN
            CYCLE /locate_upline_1/; {----->
          IFEND;

          cmp$pc_get_element (upline_connection.element_name, upline_connection.iou, upline_element_p,
                status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          cmp$get_element_state (upline_element_p^.element_name, upline_element_p^.data_channel.iou,
                upline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          element_descriptor.element_type := upline_element_p^.element_type;
          element_descriptor.channel_descriptor.iou := upline_element_p^.data_channel.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;
          element_descriptor.channel_descriptor.name := upline_element_p^.element_name;

          cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
                pet_index, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
          pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

          FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
                TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
            IF pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element =
                  primary_element.element_name THEN
              IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
              ELSE
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
              IFEND;
            IFEND;
          FOREND;
        FOREND /locate_upline_1/;

        { Change the downline connection status.

        element_descriptor.element_type := primary_element.element_type;
        element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
        element_descriptor.peripheral_descriptor.element_name := primary_element.element_name;

        cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
              pet_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
        pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

        FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^)
              TO UPPERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^) DO
          cmp$get_element_state (pet_entry_p^.physical_descriptor.equipment_connection^ [j].downline_element,
                osc$null_name, downline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          IF (primary_element_state = cmc$on) AND (downline_element_state = cmc$on) THEN
            pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$active;
          ELSE
            pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$inactive;
          IFEND;
        FOREND;

      = cmc$storage_device_element =
        cmp$get_element_state (primary_element.element_name, osc$null_name, primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

      /locate_upline_2/
        FOR i := LOWERBOUND (primary_element.storage_device.connection.port)
              TO UPPERBOUND (primary_element.storage_device.connection.port) DO
          upline_connection := primary_element.storage_device.connection.port [i];
          IF NOT upline_connection.configured THEN
            CYCLE /locate_upline_2/; {----->
          IFEND;

          CASE upline_connection.upline_connection_type OF
          = cmc$controller_element, cmc$channel_adapter_element =
            cmp$pc_get_element (upline_connection.element_name, osc$null_name, upline_element_p, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            cmp$get_element_state (upline_element_p^.element_name, osc$null_name, upline_element_state,
                  status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            element_descriptor.element_type := upline_element_p^.element_type;
            element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
            element_descriptor.peripheral_descriptor.element_name := upline_element_p^.element_name;

            cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
                  pet_index, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;
            pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

            FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^)
                  TO UPPERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^) DO
              IF pet_entry_p^.physical_descriptor.equipment_connection^ [j].downline_element =
                    primary_element.element_name THEN
                IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
                  pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$active;
                ELSE
                  pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$inactive;
                IFEND;
              IFEND;
            FOREND;

          = cmc$data_channel_element =

            { Process the Hydra device.

            IF upline_connection.mainframe_ownership <> mainframe_id THEN
              CYCLE /locate_upline_2/; {----->
            IFEND;

            cmp$pc_get_element (upline_connection.element_name, upline_connection.iou, upline_element_p,
                  status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            cmp$get_element_state (upline_element_p^.element_name, upline_element_p^.data_channel.iou,
                  upline_element_state, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            element_descriptor.element_type := upline_element_p^.element_type;
            element_descriptor.channel_descriptor.iou := upline_element_p^.data_channel.iou;
            element_descriptor.channel_descriptor.use_logical_identification := TRUE;
            element_descriptor.channel_descriptor.name := upline_element_p^.element_name;

            cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
                  pet_index, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;
            pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

            FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
                  TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
              IF pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element =
                    primary_element.element_name THEN
                IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
                  pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
                ELSE
                  pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
                IFEND;
              IFEND;
            FOREND;
          ELSE
          CASEND;
        FOREND /locate_upline_2/;

      = cmc$channel_adapter_element =
        cmp$get_element_state (primary_element.element_name, osc$null_name, primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

        upline_connection := primary_element.channel_adapter.connection.channel;
        IF NOT upline_connection.configured THEN
          EXIT /main_program/; {----->
        IFEND;

        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          EXIT /main_program/; {----->
        IFEND;

        IF upline_connection.mainframe_ownership <> mainframe_id THEN
          EXIT /main_program/; {----->
        IFEND;

        cmp$pc_get_element (upline_connection.element_name, upline_connection.iou, upline_element_p, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

        cmp$get_element_state (upline_element_p^.element_name, upline_element_p^.data_channel.iou,
              upline_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

        element_descriptor.element_type := upline_element_p^.element_type;
        element_descriptor.channel_descriptor.iou := upline_element_p^.data_channel.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;
        element_descriptor.channel_descriptor.name := upline_element_p^.element_name;

        cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
              pet_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
        pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

        FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
              TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
          IF pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element =
                primary_element.element_name THEN
            IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
              pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
            ELSE
              pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
            IFEND;
          IFEND;
        FOREND;

        { Change the downline connection status.

        element_descriptor.element_type := primary_element.element_type;
        element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
        element_descriptor.peripheral_descriptor.element_name := primary_element.element_name;

        cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
              pet_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
        pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

        FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^)
              TO UPPERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^) DO
          cmp$get_element_state (pet_entry_p^.physical_descriptor.equipment_connection^ [j].downline_element,
                osc$null_name, downline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          IF (primary_element_state = cmc$on) AND (downline_element_state = cmc$on) THEN
            pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$active;
          ELSE
            pet_entry_p^.physical_descriptor.equipment_connection^ [j].status := cmc$inactive;
          IFEND;
        FOREND;

      = cmc$communications_element =
        cmp$get_element_state (primary_element.element_name, osc$null_name, primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

      /locate_upline_3/
        FOR i := LOWERBOUND (primary_element.communications_element.connection.port)
              TO UPPERBOUND (primary_element.communications_element.connection.port) DO
          upline_connection := primary_element.communications_element.connection.port [i];
          IF NOT upline_connection.configured THEN
            CYCLE /locate_upline_3/; {----->
          IFEND;

          IF upline_connection.mainframe_ownership <> mainframe_id THEN
            CYCLE /locate_upline_3/; {----->
          IFEND;

          cmp$pc_get_element (upline_connection.element_name, upline_connection.iou, upline_element_p,
                status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          cmp$get_element_state (upline_element_p^.element_name, upline_element_p^.data_channel.iou,
                upline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          element_descriptor.element_type := upline_element_p^.element_type;
          element_descriptor.channel_descriptor.iou := upline_element_p^.data_channel.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;
          element_descriptor.channel_descriptor.name := upline_element_p^.element_name;

          cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
                pet_index, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
          pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

          FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
                TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
            IF pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element =
                  primary_element.element_name THEN
              IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
              ELSE
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
              IFEND;
            IFEND;
          FOREND;
        FOREND /locate_upline_3/;

      = cmc$external_processor_element =
        cmp$get_element_state (primary_element.element_name, osc$null_name, primary_element_state, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;

      /locate_upline_4/
        FOR i := LOWERBOUND (primary_element.external_processor.connection.io_port)
              TO UPPERBOUND (primary_element.external_processor.connection.io_port) DO
          upline_connection := primary_element.external_processor.connection.io_port [i];
          IF NOT upline_connection.configured THEN
            CYCLE /locate_upline_4/; {----->
          IFEND;

          IF upline_connection.mainframe_ownership <> mainframe_id THEN
            CYCLE /locate_upline_4/; {----->
          IFEND;

          cmp$pc_get_element (upline_connection.element_name, upline_connection.iou, upline_element_p,
                status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          cmp$get_element_state (upline_element_p^.element_name, upline_element_p^.data_channel.iou,
                upline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          element_descriptor.element_type := upline_element_p^.element_type;
          element_descriptor.channel_descriptor.iou := upline_element_p^.data_channel.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;
          element_descriptor.channel_descriptor.name := upline_element_p^.element_name;

          cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
                pet_index, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
          pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

          FOR j := LOWERBOUND (pet_entry_p^.physical_descriptor.channel_connection^)
                TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
            IF pet_entry_p^.physical_descriptor.channel_connection^ [j].downline_element =
                  primary_element.element_name THEN
              IF (upline_element_state = cmc$on) AND (primary_element_state = cmc$on) THEN
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$active;
              ELSE
                pet_entry_p^.physical_descriptor.channel_connection^ [j].status := cmc$inactive;
              IFEND;
            IFEND;
          FOREND;
        FOREND /locate_upline_4/;
      ELSE
      CASEND;
    END /main_program/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$change_connection_status_r1;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$clear_ppit', EJECT ??

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

    VAR
      channel_element_p: ^cmt$element_definition,
      index: iot$pp_number,
      pp_interface_table_p: ^iot$pp_interface_table;

    cmp$pc_get_element (channel_name, iou_name, channel_element_p, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$get_logical_pp_index (channel_element_p^, index, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    pp_interface_table_p := cmv$logical_pp_table_p^ [index].pp_info.pp_interface_table_p;
    pp_interface_table_p^.lockword := iov$initial_queue_lock_sc;
    pp_interface_table_p^.pp_request_queue := NIL;
    pp_interface_table_p^.pp_request_queue_rma := 0;

  PROCEND cmp$clear_ppit;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$count_con_access_job', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$count_con_access_job
    (    peripheral_index: integer;
     VAR count: integer;
     VAR status: ost$status);

    VAR
      con_access_job_list_p: mst$con_access_job_list;

    status.normal := TRUE;
    count := 0;

    IF cmv$peripheral_element_table.pointer^ [peripheral_index].maintenance_activity.access =
          msc$concurrent_access THEN
      con_access_job_list_p := cmv$peripheral_element_table.pointer^ [peripheral_index].maintenance_activity.
            con_access_job_list;
      WHILE con_access_job_list_p <> NIL DO
        count := count + 1;
        con_access_job_list_p := con_access_job_list_p^.forward_link;
      WHILEND;
    IFEND;

  PROCEND cmp$count_con_access_job;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$dedicated_maint_active', EJECT ??

  FUNCTION [XDCL, #GATE] cmp$dedicated_maint_active
    (    table_index: integer): boolean;

    cmp$dedicated_maint_active := (cmv$peripheral_element_table.pointer^ [table_index].maintenance_activity.
          access = msc$dedicated_access);

  FUNCEND cmp$dedicated_maint_active;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$find_state_change_request', EJECT ??

{ PURPOSE:
{   This procedure looks for outstanding state change request.

  PROCEDURE [XDCL, #GATE] cmp$find_state_change_request
    (VAR outstanding_request: boolean;
     VAR element: cmt$element_descriptor;
     VAR new_state: cmt$element_state;
     VAR current_state: cmt$element_state);

    VAR
      index: integer,
      local_status: ost$status;

    outstanding_request := FALSE;

    { Set lock while searching to prevent any request to be queued, or if there is request being queued, wait
    { until lock can be set to make sure we can catch the request.

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, local_status);
    IF NOT local_status.normal THEN
      RETURN; {----->
    IFEND;

  /lock_set/
    BEGIN
      FOR index := LOWERBOUND (cmv$peripheral_element_table.pointer^)
            TO UPPERBOUND (cmv$peripheral_element_table.pointer^) DO
        IF cmv$peripheral_element_table.pointer^ [index].physical_descriptor.configured AND
              cmv$peripheral_element_table.pointer^ [index].state_change_request.pending THEN
          element.element_type := cmv$peripheral_element_table.pointer^ [index].physical_descriptor.
                element_type;
          IF element.element_type = cmc$data_channel_element THEN
            element.channel_descriptor.use_logical_identification := TRUE;
            element.channel_descriptor.name := cmv$peripheral_element_table.pointer^ [index].element_name;
            cmp$convert_iou_number (cmv$peripheral_element_table.pointer^ [index].physical_descriptor.
                  channel_path.iou, element.channel_descriptor.iou, local_status);
          ELSE
            element.peripheral_descriptor.use_logical_identification := TRUE;
            element.peripheral_descriptor.element_name := cmv$peripheral_element_table.pointer^ [index].
                  element_name;
          IFEND;
          new_state := cmv$peripheral_element_table.pointer^ [index].state_change_request.new_state;
          current_state := cmv$peripheral_element_table.pointer^ [index].element_status.state;
          outstanding_request := TRUE;
          EXIT /lock_set/; {----->
        IFEND;
      FOREND;
    END /lock_set/;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, local_status);

  PROCEND cmp$find_state_change_request;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_element_entry_via_adr', EJECT ??

{ PURPOSE:
{   This procedure provides an interface to call the interface cmp$locate_element_via_adr in module
{   cmm$monitor_job_mode_interfaces which cannot be gated.

  PROCEDURE [XDCL, #GATE] cmp$get_element_entry_via_adr
    (    physical_address: cmt$physical_address;
     VAR entry_p: ^cmt$peripheral_element_entry);

    VAR
      element_p: ^cmt$peripheral_element_entry;

    entry_p := NIL;
    cmp$locate_element_via_adr (physical_address, element_p);
    IF element_p <> NIL THEN
      entry_p := element_p;
    IFEND;

  PROCEND cmp$get_element_entry_via_adr;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_element_entry_via_lun', EJECT ??

{ PURPOSE:
{   This procedure provides an interface to call the interface cmp$locate_element_via_lun in module
{   cmm$monitor_job_mode_interfaces which cannot be gated.

  PROCEDURE [XDCL, #GATE] cmp$get_element_entry_via_lun
    (    logical_unit: iot$logical_unit;
     VAR entry_p: ^cmt$peripheral_element_entry);

    VAR
      element_p: ^cmt$peripheral_element_entry;

    entry_p := NIL;
    cmp$locate_element_via_lun (logical_unit, element_p);
    IF element_p <> NIL THEN
      entry_p := element_p;
    IFEND;

  PROCEND cmp$get_element_entry_via_lun;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_element_entry_via_name', EJECT ??

{ PURPOSE:
{   This procedure provides an interface to call the interface cmp$locate_element_via_name in module
{   cmm$monitor_job_mode_interfaces which cannot be gated.  The iou_number parameter is only used when
{   the element is a data channel element.

  PROCEDURE [XDCL, #GATE] cmp$get_element_entry_via_name
    (    element_name: cmt$element_name;
         iou_number: dst$iou_number;
     VAR entry_p: ^cmt$peripheral_element_entry);

    VAR
      element_p: ^cmt$peripheral_element_entry;

    entry_p := NIL;
    cmp$locate_element_via_name (element_name, iou_number, element_p);
    IF element_p <> NIL THEN
      entry_p := element_p;
    IFEND;

  PROCEND cmp$get_element_entry_via_name;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_mass_storage_info', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$get_mass_storage_info
    (    logical_unit: iot$logical_unit;
     VAR mass_storage: cmt$mass_storage_information;
     VAR status: ost$status);

    VAR
      active_path: boolean,
      cio_count: integer,
      equipment_number: cmt$physical_equipment_number,
      first_lun: iot$logical_unit,
      index: integer,
      iou_array_index: dst$number_of_ious,
      iou_information_table: dst$iou_information_table,
      iou_model_type: dst$iou_model_types,
      last_lun: iot$logical_unit,
      lun: iot$logical_unit,
      number_of_ious: dst$number_of_ious,
      physical_path: iot$physical_path,
      pp_interface_table_p: ^iot$pp_interface_table;

    status.normal := TRUE;
    IF (logical_unit > UPPERBOUND (cmv$logical_unit_table^)) OR
          NOT cmv$logical_unit_table^ [logical_unit].configured OR
          (cmv$logical_unit_table^ [logical_unit].unit_interface_table = NIL) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$it_unconfigured_lun, '', status);
      osp$append_status_integer (osc$status_parameter_delimiter, logical_unit, 10, TRUE, status);
      RETURN; {----->
    IFEND;

  /search_unit_type/
    BEGIN
      FOR index := 1 TO UPPERBOUND (cmv$product_id_ptr^) DO
        IF cmv$product_id_ptr^ [index].io_unit_type = cmv$logical_unit_table^ [logical_unit].
              unit_interface_table^.unit_type THEN
          IF cmv$product_id_ptr^ [index].cm_unit_type < cmc$ms844_4x THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$it_not_mass_storage,
                  'Logical Unit is not a Mass storage.', status);
            RETURN; {----->
          IFEND;
          mass_storage.unit_type := cmv$product_id_ptr^ [index].cm_unit_type;
          EXIT /search_unit_type/; {----->
        IFEND;
      FOREND;
      osp$set_status_abnormal (cmc$configuration_management_id, cme$it_unknown_unit_type,
            'Unable to determine unit type.', status);
      RETURN; {----->
    END /search_unit_type/;

    cio_count := 0;
    dsp$retrieve_iou_information (number_of_ious, iou_information_table);

  /pp_table_loop/
    FOR index := 1 TO UPPERBOUND (cmv$logical_pp_table_p^) DO
      IF NOT cmv$logical_pp_table_p^ [index].flags.configured OR
            (cmv$logical_pp_table_p^ [index].pp_info.pp_interface_table_p = NIL) THEN
        CYCLE /pp_table_loop/; {----->
      IFEND;

      pp_interface_table_p := cmv$logical_pp_table_p^ [index].pp_info.pp_interface_table_p;
      first_lun := pp_interface_table_p^.first_logical_unit;
      last_lun := pp_interface_table_p^.number_of_units + pp_interface_table_p^.first_logical_unit - 1;
      IF (logical_unit < first_lun) OR (logical_unit > last_lun) THEN
        CYCLE /pp_table_loop/; {----->
      IFEND;

    /search_lun/
      FOR lun := first_lun TO last_lun DO
        IF (logical_unit <> lun) OR (pp_interface_table_p^.unit_descriptors [logical_unit].
              unit_interface_table_rma = 0) THEN
          CYCLE /search_lun/; {----->
        IFEND;
        physical_path := pp_interface_table_p^.unit_descriptors [logical_unit].physical_path;
        mass_storage.iou_number := cmv$logical_pp_table_p^ [index].pp_info.channel.iou_number;
        mass_storage.channel.number := physical_path.channel_number;
        mass_storage.unit_number := physical_path.physical_unit_number;
        mass_storage.channel.concurrent := cmv$logical_pp_table_p^ [index].pp_info.channel_interlock_p^.
              channel_characteristics [mass_storage.channel.number].concurrent_channel;
        mass_storage.channel.port := cmc$unspecified_port;

        CASE mass_storage.unit_type OF
        = cmc$ms844_4x, cmc$ms885_1x, cmc$ms885_4x =
          equipment_number := physical_path.controller_number;

        = cmc$ms895_2 =
          IF physical_path.storage_directory_address > 1 THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$it_not_cip_device,
                  'Logical unit is potentially not a CIP device', status);
            RETURN; {----->
          IFEND;
          mass_storage.storage_director_address := physical_path.storage_directory_address;
          IF physical_path.physical_unit_number > 1000(16) THEN
            mass_storage.head_of_string_controller := 1;
            mass_storage.unit_number := physical_path.physical_unit_number - 1000(16);
          ELSE
            mass_storage.head_of_string_controller := 0;
          IFEND;

        = cmc$ms834_2, cmc$msfsd_2, cmc$msfsd2_s0, cmc$msxmd_3, cmc$ms5832_1, cmc$ms5832_2, cmc$ms5833_1,
              cmc$ms5833_1p, cmc$ms5833_2, cmc$ms5833_3p, cmc$ms5833_4, cmc$ms5837_1, cmc$ms5837_1p,
              cmc$ms5837_2, cmc$ms5837_3p, cmc$ms5837_4, cmc$ms5838_1, cmc$ms5838_1p, cmc$ms5838_2,
              cmc$ms5838_3p, cmc$ms5838_4, cmc$ms47444_1, cmc$ms47444_1p, cmc$ms47444_2, cmc$ms47444_3p,
              cmc$ms47444_4, cmc$ms_ntdd_1, cmc$ms_ntdd_2, cmc$ms_ntdd_3, cmc$ms_ntdd_4, cmc$ms_ntdd_5,
              cmc$ms_ntdd_6 =
          mass_storage.control_module := physical_path.controller_number;
          IF mass_storage.channel.concurrent THEN
            osp$set_status_condition (cme$it_no_cip_access, status);
            RETURN; {----->
          IFEND;
        ELSE
          osp$set_status_abnormal (cmc$configuration_management_id, cme$it_not_cip_device,
                'Logical unit is potentially not a CIP device', status);
          RETURN; {----->
        CASEND;

        { If the current channel is concurrent then:
        {    * If running on I4C or I4CE then do not search for CIP presence
        {    * If running on I4A then, keep searching for a NIO channel.

        IF mass_storage.channel.concurrent THEN
          IF (cmv$logical_pp_table_p^ [index].pp_info.pp_communication_buffer_p = NIL) OR
             NOT cmv$logical_pp_table_p^ [index].pp_info.pp_communication_buffer_p^.slave THEN
            cio_count := cio_count + 1;
          IFEND;

        /find_iou_model/
          FOR iou_array_index := LOWERBOUND (iou_information_table) TO UPPERBOUND (iou_information_table) DO
            IF iou_information_table [iou_array_index].physical_iou_number = mass_storage.iou_number THEN
              iou_model_type := iou_information_table [iou_array_index].model_type;
              EXIT /find_iou_model/; {----->
            IFEND;
          FOREND /find_iou_model/;

          CASE iou_model_type OF
          = dsc$imn_i4_44_model, dsc$imn_i4_46_model =
            osp$set_status_condition (cme$it_no_cip_access, status);
            RETURN; {----->
          = dsc$imn_i4_40_model, dsc$imn_i4_42_model =
            CYCLE /pp_table_loop/; {----->
          ELSE
          CASEND;
        IFEND;

        IF logical_unit <> cmc$job_template_unit_ordinal THEN
          check_active_path (equipment_number, mass_storage, active_path);
          IF NOT active_path THEN
            CYCLE /pp_table_loop/; {----->
          IFEND;
        IFEND;
        RETURN; {----->
      FOREND /search_lun/;
    FOREND /pp_table_loop/;

    IF cio_count = 1 THEN
      osp$set_status_condition (cme$it_unusable_cip_access, status);
    ELSE
      osp$set_status_condition (cme$it_no_cip_access, status);
    IFEND;

  PROCEND cmp$get_mass_storage_info;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_next_request ', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$get_next_request
    (    element_name: cmt$element_name;
     VAR next_request_p: ^iot$io_request;
     VAR status: ost$status);

    VAR
      logical_unit_number: iot$logical_unit;

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

    next_request_p := cmv$logical_unit_table^ [logical_unit_number].unit_interface_table^.next_request;

  PROCEND cmp$get_next_request;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_pp_table_rma', EJECT ??

{ PURPOSE:
{   This procedure returns the Real Memory Address of the PP interface table of the give channel definition.

  PROCEDURE [XDCL, #GATE] cmp$get_pp_table_rma
    (    element: cmt$element_definition;
     VAR pp_table_rma: ost$real_memory_address;
     VAR status: ost$status);

    VAR
      pp_index: iot$pp_number;

    status.normal := TRUE;
    cmp$get_logical_pp_index (element, pp_index, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;
    pp_table_rma := cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_rma;

  PROCEND cmp$get_pp_table_rma;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$get_reservation_info', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$get_reservation_info
    (    table_index: integer;
     VAR reservable_element: boolean;
     VAR reserved_to_job: boolean;
     VAR reserving_job: jmt$system_supplied_name);

    reservable_element := ((cmv$peripheral_element_table.pointer^ [table_index].reservable_element =
          cmc$reservable) OR (cmv$peripheral_element_table.pointer^ [table_index].reservable_element =
          cmc$reservable_only_by_system));
    reserved_to_job := cmv$peripheral_element_table.pointer^ [table_index].entry_interlock;
    reserving_job := cmv$peripheral_element_table.pointer^ [table_index].reserved_job;

  PROCEND cmp$get_reservation_info;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$mark_element_reserved', EJECT ??

{ PURPOSE:
{   This procedure marks an element as being reserved to a job via cmp$reserve_element.

  PROCEDURE [XDCL, #GATE] cmp$mark_element_reserved
    (    element_reservation: cmt$element_reservation;
         reserved_by_system: boolean;
         job_name: jmt$system_supplied_name;
         gtid: ost$global_task_id;
         physical_pp: dst$iou_resource;
         table_index: integer;
         channel_present: boolean;
     VAR status: ost$status);

    VAR
      entry_p: ^cmt$peripheral_element_entry,
      channel: cmt$physical_channel,
      channel_address: cmt$physical_equipment_number,
      channel_name: cmt$element_name,
      channel_number: ost$physical_channel_number,
      channel_port: cmt$channel_port,
      concurrent: boolean,
      iou_number: dst$iou_number,
      physical_id: cmt$physical_identification,
      status_p: ^ost$status,
      temp_element_descriptor: cmt$element_descriptor,
      unit_address: cmt$physical_unit_number;

    status.normal := TRUE;
    cmp$crack_physical_address (element_reservation, iou_number, channel, channel_address, unit_address,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

  /main_program/
    BEGIN
      entry_p := ^cmv$peripheral_element_table.pointer^ [table_index];
      IF NOT entry_p^.entry_interlock THEN
        entry_p^.entry_interlock := TRUE;
        entry_p^.gtid := gtid;
        entry_p^.reserved_status := TRUE;
        entry_p^.reserved_by_system := reserved_by_system;
        entry_p^.reserved_job := job_name;

        IF NOT entry_p^.physical_descriptor.configured THEN
          CASE element_reservation.element_type OF
          = cmc$data_channel_element =
            entry_p^.physical_descriptor.hardware_address.iou := iou_number;
            IF element_reservation.channel_descriptor.use_logical_identification THEN
              entry_p^.element_name := element_reservation.channel_descriptor.name;
            ELSE

              { Always store the element name for channel, even though reservation is by physical address.

              cmp$convert_channel_ordinal (element_reservation.channel_descriptor.channel_ordinal,
                    channel_name, channel_number, concurrent, channel_port, status);
              IF NOT status.normal THEN
                EXIT /main_program/; {can this happen??? and then?
              IFEND;
              entry_p^.element_name := channel_name;
            IFEND;

            entry_p^.physical_descriptor.hardware_address.address_specifier :=
                  $cmt$physical_address_specifier [cmc$iou, cmc$channel];
            entry_p^.physical_descriptor.hardware_address.iou := iou_number;
            entry_p^.physical_descriptor.hardware_address.channel := channel;

          = cmc$controller_element, cmc$storage_device_element, cmc$communications_element,
                cmc$channel_adapter_element, cmc$external_processor_element =
            IF element_reservation.peripheral_descriptor.use_logical_identification THEN
              entry_p^.element_name := element_reservation.peripheral_descriptor.element_name;
            ELSE
              IF element_reservation.element_type <> cmc$storage_device_element THEN
                entry_p^.physical_descriptor.hardware_address.address_specifier :=
                      $cmt$physical_address_specifier [cmc$iou, cmc$channel, cmc$channel_address];
              ELSE
                entry_p^.physical_descriptor.hardware_address.address_specifier :=
                      $cmt$physical_address_specifier [cmc$iou, cmc$channel, cmc$channel_address,
                      cmc$unit_address];
              IFEND;
              entry_p^.physical_descriptor.hardware_address.iou := iou_number;
              entry_p^.physical_descriptor.hardware_address.channel := channel;
              entry_p^.physical_descriptor.hardware_address.channel_address := channel_address;
              entry_p^.physical_descriptor.hardware_address.unit_address := unit_address;
            IFEND;
          CASEND;
        IFEND;
      ELSE
        temp_element_descriptor.element_type := element_reservation.element_type;
        CASE temp_element_descriptor.element_type OF
        = cmc$data_channel_element =
          temp_element_descriptor.channel_descriptor := element_reservation.channel_descriptor;
        = cmc$controller_element, cmc$external_processor_element, cmc$channel_adapter_element,
              cmc$storage_device_element, cmc$communications_element =
          temp_element_descriptor.peripheral_descriptor := element_reservation.peripheral_descriptor;
        ELSE
        CASEND;
        cmp$format_error_message (temp_element_descriptor, {not used} physical_id, FALSE,
              cme$element_already_reserved, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, entry_p^.reserved_job, status);
      IFEND;
    END /main_program/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$mark_element_reserved;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$mark_pp_element_reserved', EJECT ??

{ PURPOSE:
{   This procedure marks a PP element in the Logical PP Table as being reserved to a job via
{   cmp$reserve_element.

  PROCEDURE [XDCL, #GATE] cmp$mark_pp_element_reserved
    (    element_reservation: cmt$element_reservation;
         reserved_by_system: boolean;
         job_name: jmt$system_supplied_name;
         gtid: ost$global_task_id;
         physical_pp: dst$iou_resource;
         channel_present: boolean;
     VAR pp_index: iot$pp_number;
     VAR status: ost$status);

    VAR
      channel: cmt$physical_channel,
      channel_address: cmt$physical_equipment_number,
      entry_p: ^cmt$logical_pp_table_entry,
      found: boolean,
      iou_number: dst$iou_number,
      local_status: ost$status,
      status_p: ^ost$status,
      unit_address: cmt$physical_unit_number;

    status.normal := TRUE;

{ Check to see if requested PP is already reserved.
    cmp$search_pp_table (physical_pp, pp_index, found, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    entry_p := ^cmv$logical_pp_table_p^ [pp_index];
    IF found THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$element_already_reserved, 'Requested PP',
            status);
      IF entry_p^.flags.entry_reserved_by_nosve THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'NOS/VE', status);
      ELSEIF entry_p^.task_info.reserved_job_name = job_name THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, 'this job', status);
      ELSE
        osp$append_status_parameter (osc$status_parameter_delimiter, entry_p^.task_info.reserved_job_name,
              status);
      IFEND;
      RETURN; {----->
    IFEND;

    cmp$crack_physical_address (element_reservation, iou_number, channel, channel_address, unit_address,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$logical_pp_table_lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    pmp$zero_out_table (#LOC (cmv$logical_pp_table_p^ [pp_index]), #SIZE (entry_p^));
    entry_p^.pp_info.pp_interface_table_p := NIL;
    entry_p^.pp_info.pp_communication_buffer_p := NIL;
    entry_p^.pp_info.channel_interlock_p := NIL;
    entry_p^.pp_info.driver_code_p := NIL;
    entry_p^.pp_info.saved_io_request_p := NIL;
    entry_p^.handlers.response_handler_p := NIL;
    entry_p^.handlers.one_word_response_handler_p := NIL;

    entry_p^.flags.entry_in_use := TRUE;
    entry_p^.flags.entry_reserved_by_other := TRUE;
    entry_p^.flags.entry_reserved_by_system_job := reserved_by_system;
    entry_p^.flags.reservd_by_other_has_ch_present := channel_present;
    entry_p^.task_info.gtid := gtid;
    entry_p^.task_info.reserved_job_name := job_name;
    entry_p^.pp_info.physical_pp := physical_pp;
    entry_p^.flags.resources_acquired := TRUE;
    entry_p^.pp_info.driver_name := ' ';
    entry_p^.pp_info.cip_driver_name := ' ';
    entry_p^.pp_info.channel.iou_number := iou_number;
    IF entry_p^.flags.reservd_by_other_has_ch_present THEN
      IF channel.concurrent THEN
        entry_p^.pp_info.channel.channel_protocol := dsc$cpt_cio;
      ELSE
        entry_p^.pp_info.channel.channel_protocol := dsc$cpt_nio;
      IFEND;
      entry_p^.pp_info.channel.number := channel.number;
      entry_p^.pp_info.channel_port := channel.port;
      update_ch_connection_status (pp_index);
    ELSE
      entry_p^.pp_info.channel.channel_protocol := dsc$cpt_nio;
      entry_p^.pp_info.channel.number := 15;
      entry_p^.pp_info.channel_port := cmc$unspecified_port;
    IFEND;
    entry_p^.controller_info.controller_type := cmc$null_controller;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$logical_pp_table_lock, status_p^);

  PROCEND cmp$mark_pp_element_reserved;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$queue_state_change', EJECT ??

{ PURPOSE:
{   This procedure queues a state change request initiated from NOS/VE.
{ This is done when multiple state change requests were occuring.

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

    VAR
      element_reservation: cmt$element_reservation,
      table_index: integer;

    cmp$search_peripheral_table (element, element_reservation, {not_in_configuration=} FALSE, table_index,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF NOT cmv$peripheral_element_table.pointer^ [table_index].state_change_request.pending THEN
      cmv$peripheral_element_table.pointer^ [table_index].state_change_request := state_change_request;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status);

  PROCEND cmp$queue_state_change;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$return_lun_info', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$return_lun_info
    (    logical_unit: iot$logical_unit;
     VAR assigned_to_job: boolean;
     VAR assigned_job_id: jmt$system_supplied_name);

    assigned_to_job := cmv$logical_unit_table^ [logical_unit].status.assigned;
    assigned_job_id := cmv$logical_unit_table^ [logical_unit].status.assigned_jsn;

  PROCEND cmp$return_lun_info;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$search_pp_table', EJECT ??

{ PURPOSE:
{   Search the Logical PP Table for the given physical pp value.  If the PP is not found then the index to
{   the next available slot in the table is returned.

  PROCEDURE [XDCL, #GATE] cmp$search_pp_table
    (    physical_pp: dst$iou_resource;
     VAR logical_pp_index: iot$pp_number;
     VAR found: boolean;
     VAR status: ost$status);

    VAR
      pp_index: iot$pp_number;

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

    IF cmv$logical_pp_table_p = NIL THEN
      osp$set_status_condition (cme$cm_table_empty, status);
      RETURN; {----->
    IFEND;

    FOR pp_index := LOWERBOUND (cmv$logical_pp_table_p^) TO UPPERBOUND (cmv$logical_pp_table_p^) DO
      IF cmv$logical_pp_table_p^ [pp_index].pp_info.physical_pp = physical_pp THEN
        found := TRUE;
        logical_pp_index := pp_index;
        RETURN; {----->
      IFEND;
    FOREND;

    FOR pp_index := LOWERBOUND (cmv$logical_pp_table_p^) TO UPPERBOUND (cmv$logical_pp_table_p^) DO
      IF (cmv$logical_pp_table_p^ [pp_index].pp_info.physical_pp.number = 33(8)) AND
            NOT cmv$logical_pp_table_p^ [pp_index].flags.entry_in_use THEN
        logical_pp_index := pp_index;
        RETURN; {----->
      IFEND;
    FOREND;
    osp$set_status_condition (cme$no_logical_pp_available, status);

  PROCEND cmp$search_pp_table;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$state_change_pending', EJECT ??

{ PURPOSE:
{   This functions determines whether or not a state change request
{   already queued for the given element.

  FUNCTION [XDCL, #GATE, UNSAFE] cmp$state_change_pending
    (    element: cmt$element_descriptor): boolean;

    VAR
      element_reservation: cmt$element_reservation,
      index: integer,
      local_status: ost$status;

    cmp$state_change_pending := FALSE;
    cmp$search_peripheral_table (element, element_reservation, {not_in_configuration=} FALSE, index,
          local_status);
    IF local_status.normal THEN
      cmp$state_change_pending := cmv$peripheral_element_table.pointer^ [index].state_change_request.pending;
    IFEND;

  FUNCEND cmp$state_change_pending;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$store_file_server_info', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$store_file_server_info
    (    pp_index: iot$pp_number;
         next_request_p: ^iot$io_request;
         one_word_response_allowed: boolean;
         one_word_response_processor: dft$one_word_response_handler;
     VAR status: ost$status);

    VAR
      next_request_rma: integer,
      unit: iot$logical_unit;

    status.normal := TRUE;
    IF (pp_index > UPPERBOUND (cmv$logical_pp_table_p^)) OR (pp_index < LOWERBOUND (cmv$logical_pp_table_p^))
          THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
            'Invalid pp index detected in cmp$store_file_server_info', status);
      RETURN; {----->
    IFEND;

    IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
            ' NIL pp_interface_table_p detected in cmp$store_file_server_info', status);
      RETURN; {----->
    IFEND;

    IF cmv$logical_pp_table_p^ [pp_index].controller_info.controller_type <> cmc$fs740_200 THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
            ' One word response only allowed for file server PP.', status);
      RETURN; {----->
    IFEND;

    FOR unit := LOWERBOUND (cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.unit_descriptors)
          TO UPPERBOUND (cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.unit_descriptors) DO
      IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.unit_descriptors [unit].
            unit_interface_table <> NIL THEN
        cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.unit_descriptors [unit].
              unit_interface_table^.next_request := next_request_p;
        i#real_memory_address (#LOC (next_request_p^), next_request_rma);
        cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.unit_descriptors [unit].
              unit_interface_table^.next_request_rma := next_request_rma;

        cmv$logical_pp_table_p^ [pp_index].handlers.one_word_response_allowed := one_word_response_allowed;
        IF one_word_response_allowed THEN
          cmv$logical_pp_table_p^ [pp_index].handlers.one_word_response_handler_p :=
                one_word_response_processor;
        IFEND;
        RETURN; {----->
      IFEND;
    FOREND;

    osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
          'NIL unit interface table detected in cmp$store_file_server_info', status);

  PROCEND cmp$store_file_server_info;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$store_one_word_response_ptr ', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$store_one_word_response_ptr
    (    pp_index: iot$pp_number;
         one_word_response_processor: dft$one_word_response_handler;
     VAR status: ost$status);

    VAR
      unit: iot$logical_unit;

    status.normal := TRUE;
    IF (pp_index > UPPERBOUND (cmv$logical_pp_table_p^)) OR (pp_index < LOWERBOUND (cmv$logical_pp_table_p^))
          THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
            'Invalid pp index detected in cmp$store_one_word_response_ptr', status);
      RETURN; {----->
    IFEND;

    IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$pc_nil_cm_table,
            ' NIL pp_interface_table_p detected in cmp$store_one_word_response_ptr', status);
      RETURN; {----->
    IFEND;

    cmv$logical_pp_table_p^ [pp_index].handlers.one_word_response_allowed := TRUE;
    cmv$logical_pp_table_p^ [pp_index].handlers.one_word_response_handler_p := one_word_response_processor;

  PROCEND cmp$store_one_word_response_ptr;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$unmark_element_reserved', EJECT ??

{ PURPOSE:
{   This procedure unmark an element as a result of cmp$release_element

  PROCEDURE [XDCL, #GATE] cmp$unmark_element_reserved
    (    element_reservation: cmt$element_reservation;
         job_name: jmt$system_supplied_name;
         system_caller: boolean;
         table_index: integer;
     VAR status: ost$status);

    VAR
      entry_p: ^cmt$peripheral_element_entry,
      status_p: ^ost$status;

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

    PROCEDURE p$set_error_status
      (    element_reservation: cmt$element_reservation;
           condition: ost$status_condition_code;
           str: string ( * <= osc$max_string_size);
       VAR status: ost$status);

      VAR
        temp_element_descriptor: cmt$element_descriptor,
        physical_id: cmt$physical_identification;

      temp_element_descriptor.element_type := element_reservation.element_type;
      CASE temp_element_descriptor.element_type OF
      = cmc$data_channel_element =
        temp_element_descriptor.channel_descriptor := element_reservation.channel_descriptor;
      = cmc$controller_element, cmc$external_processor_element, cmc$channel_adapter_element,
            cmc$storage_device_element, cmc$communications_element =
        temp_element_descriptor.peripheral_descriptor := element_reservation.peripheral_descriptor;
      ELSE
      CASEND;

      cmp$format_error_message (temp_element_descriptor, {not used} physical_id, FALSE, condition, status);
      IF str <> '' THEN
        osp$append_status_parameter (osc$status_parameter_delimiter, str, status);
      IFEND;

    PROCEND p$set_error_status;
?? OLDTITLE ??
?? EJECT ??
    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    entry_p := ^cmv$peripheral_element_table.pointer^ [table_index];
    IF entry_p^.entry_interlock THEN
      IF (entry_p^.reserved_job = job_name) OR (system_caller AND entry_p^.reserved_by_system) THEN
        entry_p^.gtid.index := 4095;
        entry_p^.gtid.seqno := 255;
        entry_p^.entry_interlock := FALSE;
        entry_p^.reserved_status := FALSE;
        entry_p^.reserved_by_system := FALSE;
        entry_p^.reserved_job := '';
        IF NOT entry_p^.physical_descriptor.configured THEN
          entry_p^.physical_descriptor.hardware_address.iou := 0;
          entry_p^.physical_descriptor.hardware_address.channel.number := 0;
          entry_p^.physical_descriptor.hardware_address.channel.concurrent := FALSE;
          entry_p^.physical_descriptor.hardware_address.channel.port := cmc$unspecified_port;
          entry_p^.physical_descriptor.hardware_address.channel_address := 7;
          entry_p^.physical_descriptor.hardware_address.unit_address := 63;
          entry_p^.physical_descriptor.hardware_address.address_specifier :=
                $cmt$physical_address_specifier [];
          entry_p^.element_name := ' ';
        IFEND;
      ELSE
        p$set_error_status (element_reservation, cme$element_already_reserved, entry_p^.reserved_job, status);
      IFEND;
    ELSE
      p$set_error_status (element_reservation, cme$element_not_reserved, '', status);
    IFEND;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$unmark_element_reserved;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$unmark_pp_element_reserved', EJECT ??

{ PURPOSE:
{   This procedure unmarks an element in the logical PP table as a result of cmp$release_element.

  PROCEDURE [XDCL, #GATE] cmp$unmark_pp_element_reserved
    (    job_name: jmt$system_supplied_name;
         system_caller: boolean;
         table_index: integer;
     VAR status: ost$status);

    VAR
      len: integer,
      pp_number: string (11),
      status_p: ^ost$status;

    osp$set_signature_lock (cmv$logical_pp_table_lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

  /pp_table_lock_set/
    BEGIN
      IF cmv$logical_pp_table_p^ [table_index].pp_info.physical_pp.channel_protocol = dsc$cpt_cio THEN
        STRINGREP (pp_number, len, 'IOU', cmv$logical_pp_table_p^ [table_index].pp_info.physical_pp.
              iou_number: 2, ' CPP', cmv$logical_pp_table_p^ [table_index].pp_info.physical_pp.number: 2);
      ELSE
        STRINGREP (pp_number, len, 'IOU', cmv$logical_pp_table_p^ [table_index].pp_info.physical_pp.
              iou_number: 2, '  PP', cmv$logical_pp_table_p^ [table_index].pp_info.physical_pp.number: 3);
      IFEND;

      IF NOT cmv$logical_pp_table_p^ [table_index].flags.entry_in_use THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$element_not_reserved,
              pp_number (1, len), status);
        EXIT /pp_table_lock_set/; {----->
      IFEND;

      IF cmv$logical_pp_table_p^ [table_index].flags.entry_reserved_by_nosve THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$element_already_reserved,
              pp_number (1, len), status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'NOS/VE', status);
        EXIT /pp_table_lock_set/; {----->
      IFEND;

      IF (cmv$logical_pp_table_p^ [table_index].task_info.reserved_job_name <> job_name) AND
            NOT (system_caller AND cmv$logical_pp_table_p^ [table_index].flags.entry_reserved_by_system_job)
            THEN
        osp$set_status_abnormal (cmc$configuration_management_id, cme$element_already_reserved,
              pp_number (1, len), status);
        osp$append_status_parameter (osc$status_parameter_delimiter,
              cmv$logical_pp_table_p^ [table_index].task_info.reserved_job_name, status);
        EXIT /pp_table_lock_set/; {----->
      IFEND;

      unmark_pp_element (table_index, FALSE);
    END /pp_table_lock_set/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$logical_pp_table_lock, status_p^);

  PROCEND cmp$unmark_pp_element_reserved;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$unmark_pp_when_cleanup', EJECT ??

{ PURPOSE:
{   This procedure cleans up all element entries reserved as a result of task termination clean up.

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

    osp$set_signature_lock (cmv$logical_pp_table_lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    unmark_pp_element (table_index, TRUE);
    osp$clear_signature_lock (cmv$logical_pp_table_lock, status);

  PROCEND cmp$unmark_pp_when_cleanup;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$unmark_when_cleanup', EJECT ??

{ PURPOSE:
{   This procedure cleans up all element entries reserved as a result of task termination clean up.

  PROCEDURE [XDCL, #GATE] cmp$unmark_when_cleanup
    (    table_index: integer;
         mainframe_id: pmt$mainframe_id;
     VAR status: ost$status);

    VAR
      entry_p: ^cmt$peripheral_element_entry,
      pc_index_1: integer,
      status_p: ^ost$status;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

  /main_program/
    BEGIN
      entry_p := ^cmv$peripheral_element_table.pointer^ [table_index];
      entry_p^.gtid.index := 4095;
      entry_p^.gtid.seqno := 255;
      entry_p^.entry_interlock := FALSE;
      entry_p^.reserved_status := FALSE;
      entry_p^.reserved_job := '';
      IF NOT entry_p^.physical_descriptor.configured THEN
        entry_p^.physical_descriptor.hardware_address.iou := 0;
        entry_p^.physical_descriptor.hardware_address.channel.number := 0;
        entry_p^.physical_descriptor.hardware_address.channel.concurrent := FALSE;
        entry_p^.physical_descriptor.hardware_address.channel.port := cmc$unspecified_port;
        entry_p^.physical_descriptor.hardware_address.channel_address := 7;
        entry_p^.physical_descriptor.hardware_address.unit_address := 63;
        entry_p^.physical_descriptor.hardware_address.address_specifier := $cmt$physical_address_specifier [];
        entry_p^.element_name := ' ';
      IFEND;

      IF entry_p^.maintenance_activity.access = msc$dedicated_access THEN
        entry_p^.maintenance_activity.dedicated_accessor.job_identification := ' ';
        entry_p^.maintenance_activity.dedicated_accessor.active := FALSE;
        entry_p^.maintenance_activity.access := msc$concurrent_access;
        entry_p^.maintenance_activity.con_access_job_list := NIL;

        { Check to see if the element is in the active physical configuration having multiple channels
        { connections.  If so, release all additional channels to the real state system }

      /pc_loop_1/
        FOR pc_index_1 := 1 TO UPPERBOUND (cmv$physical_configuration^) DO
          IF (cmv$physical_configuration^ [pc_index_1].element_type =
                entry_p^.physical_descriptor.element_type) AND (cmv$physical_configuration^ [pc_index_1].
                element_name = entry_p^.element_name) THEN

            { Release all channels connected to controller to the real state system }

            cmp$request_channels (dsc$rrt_return_channel, cmv$physical_configuration^ [pc_index_1],
                  mainframe_id, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;
            EXIT /pc_loop_1/; {----->
          IFEND;
        FOREND /pc_loop_1/;
      IFEND;
    END /main_program/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$unmark_when_cleanup;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$update_connection_states_r1 ', EJECT ??

{ PURPOSE:
{   This procedure will go through the entire physical_configuration and update the connection_status for all
{   elements based entirely on the states of the elements.
{
{ NOTE:
{   If this procedure is executed after an automatic reconfiguration has occurred any DISABLED connection will
{   be set to ACTIVE.

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

    VAR
      active_connection: boolean,
      channel_element_p: ^cmt$element_definition,
      channel_name: cmt$element_name,
      check_redundant_path: boolean,
      controller_element_p: ^cmt$element_definition,
      controller_number: cmt$physical_equipment_number,
      controller_type: cmt$controller_type,
      downline_element_p: ^cmt$element_definition,
      downline_element_state: cmt$element_state,
      i: integer,
      iou_name: cmt$element_name,
      j: integer,
      status_p: ^ost$status,
      upline_element_state: cmt$element_state;

    IF cmv$physical_configuration = NIL THEN
      osp$set_status_condition (cme$active_pc_empty, status);
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

  /main_program/
    BEGIN
      FOR i := LOWERBOUND (cmv$physical_configuration^) TO UPPERBOUND (cmv$physical_configuration^) DO
        CASE cmv$physical_configuration^ [i].element_type OF
        = cmc$data_channel_element =
          channel_name := cmv$physical_configuration^ [i].element_name;
          iou_name := cmv$physical_configuration^ [i].data_channel.iou;

          cmp$get_element_state (channel_name, iou_name, upline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          FOR j := LOWERBOUND (cmv$peripheral_element_table.pointer^ [i].physical_descriptor.
                channel_connection^) TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [i].
                physical_descriptor.channel_connection^) DO

            cmp$get_element_state (cmv$peripheral_element_table.pointer^ [i].physical_descriptor.
                  channel_connection^ [j].downline_element, iou_name, downline_element_state, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            IF (upline_element_state = cmc$on) AND (downline_element_state = cmc$on) THEN
              cmv$peripheral_element_table.pointer^ [i].physical_descriptor.channel_connection^ [j].status :=
                    cmc$active;
            ELSE
              cmv$peripheral_element_table.pointer^ [i].physical_descriptor.channel_connection^ [j].status :=
                    cmc$inactive;
            IFEND;
          FOREND;

        = cmc$channel_adapter_element, cmc$controller_element =
          cmp$get_element_state (cmv$physical_configuration^ [i].element_name, osc$null_name,
                upline_element_state, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;

          FOR j := LOWERBOUND (cmv$peripheral_element_table.pointer^ [i].physical_descriptor.
                equipment_connection^) TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [i].
                physical_descriptor.equipment_connection^) DO

            cmp$get_element_state (cmv$peripheral_element_table.pointer^ [i].physical_descriptor.
                  equipment_connection^ [j].downline_element, osc$null_name, downline_element_state, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

            IF (upline_element_state = cmc$on) AND (downline_element_state = cmc$on) THEN
              cmv$peripheral_element_table.pointer^ [i].physical_descriptor.equipment_connection^ [j].
                    status := cmc$active;
            ELSE
              cmv$peripheral_element_table.pointer^ [i].physical_descriptor.equipment_connection^ [j].
                    status := cmc$inactive;
            IFEND;
          FOREND;

        = cmc$communications_element, cmc$external_processor_element, cmc$storage_device_element =

          { These elements are the last in the path and have no downline connections.

        ELSE
        CASEND;
      FOREND;
    END /main_program/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND cmp$update_connection_states_r1;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$update_logical_unit_table', EJECT ??

  PROCEDURE [XDCL, #GATE] cmp$update_logical_unit_table
    (    logical_unit: iot$logical_unit;
         state: cmt$element_state;
     VAR status: ost$status);

    IF cmv$logical_unit_table = NIL THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$it_nil_lut,
            'The logical unit table is inaccessable in cmp$update_logical_unit_table.', status);
      RETURN; {----->
    IFEND;

    IF logical_unit > UPPERBOUND (cmv$logical_unit_table^) THEN
      osp$set_status_abnormal (cmc$configuration_management_id, cme$it_lun_not_in_range,
            'Logical_unit_number out of bounds in cmp$update_logical_unit_table.', status);
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$logical_unit_lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    CASE state OF
    = cmc$on =
      cmv$logical_unit_table^ [logical_unit].element_access := $cmt$element_access [cmc$read, cmc$write];
      cmv$logical_unit_table^ [logical_unit].element_capability :=
            $cmt$element_capabilities [cmc$volume_assignment, cmc$io_request_submission,
            cmc$concurrent_maintenance];
    = cmc$down =
      cmv$logical_unit_table^ [logical_unit].element_access := $cmt$element_access [cmc$read, cmc$write];
      cmv$logical_unit_table^ [logical_unit].element_capability :=
            $cmt$element_capabilities [cmc$concurrent_maintenance, cmc$dedicated_maintenance];
    ELSE { = cmc$off = }
      cmv$logical_unit_table^ [logical_unit].element_access := $cmt$element_access [];
      cmv$logical_unit_table^ [logical_unit].element_capability := $cmt$element_capabilities [];
    CASEND;

    osp$clear_signature_lock (cmv$logical_unit_lock, status);

  PROCEND cmp$update_logical_unit_table;
?? OLDTITLE ??
?? NEWTITLE := 'cmp$validate_unused_channel ', EJECT ??

{ PURPOSE:
{   This procedure validates maintenance usage on a channel that is unused by NOS/VE.
{
{ NOTE:
{   For certain devices such as ISD1/ISD2/CM3, NOS/VE only uses the first channel on a dual access
{   configuration, thus it does not know about the other access. Therefore, maintenance should be prevented
{   from using the second access as NOS/VE will not be able to honor the other channel lock entry.

  PROCEDURE [XDCL, #GATE] cmp$validate_unused_channel
    (    channel_name: cmt$element_name;
         iou_name: cmt$element_name;
     VAR maintenance_allowed: boolean;
     VAR status: ost$status);

    VAR
      active_unit: boolean,
      channel_element_p: ^cmt$element_definition,
      channel_port_number: 0 .. 1,
      controller_entry_p: ^cmt$peripheral_element_entry,
      controller_found: boolean,
      dummy_reservation: cmt$element_reservation,
      element_descriptor: cmt$element_descriptor,
      iou_number: dst$iou_number,
      job_name: jmt$system_supplied_name,
      logical_pp_index: iot$pp_number,
      lun: iot$logical_unit,
      pen: cmt$physical_equipment_number,
      pet_index: integer,
      ppit_p: ^iot$pp_interface_table,
      user_job_name: jmt$user_supplied_name;

    status.normal := TRUE;
    controller_found := FALSE;
    maintenance_allowed := TRUE;

    cmp$convert_iou_name (iou_name, iou_number, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    cmp$pc_get_element (channel_name, iou_name, channel_element_p, status);
    IF NOT status.normal THEN

      { Channel is not in VE configuration.

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

    cmp$get_logical_pp_index (channel_element_p^, logical_pp_index, status);
    IF NOT status.normal THEN
      IF status.condition = cme$pc_not_logically_conf THEN
        status.normal := TRUE;
      IFEND;
      RETURN; {----->
    IFEND;

    CASE cmv$logical_pp_table_p^ [logical_pp_index].controller_info.controller_type OF
    = cmc$ms7154_x .. cmc$ms7155_1x, cmc$ms7255_1_1, cmc$ms7255_1_2, cmc$mscm3_ct, cmc$mt5698_xx,
          cmc$ms5831_x, cmc$msntdc_1, cmc$msntdc_2 =
      pmp$get_job_names (user_job_name, job_name, status);
    ELSE
      {
      { Other disk subsystems are OK for maintenance access.
      {
      RETURN; {----->
    CASEND;

    IF channel_element_p^.data_channel.port = cmc$port_b THEN
      channel_port_number := 1;
    ELSE
      channel_port_number := 0;
    IFEND;

  /loop_1/
    FOR pen := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
      IF NOT channel_element_p^.data_channel.connection.equipment [pen].configured THEN
        CYCLE /loop_1/; {----->
      IFEND;

      element_descriptor.element_type := cmc$controller_element;
      element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
      element_descriptor.peripheral_descriptor.element_name :=
            channel_element_p^.data_channel.connection.equipment [pen].element_name;

      cmp$search_peripheral_table (element_descriptor, dummy_reservation, {not_in_configuration} FALSE,
            pet_index, status);
      IF NOT status.normal THEN
        CYCLE /loop_1/; {----->
      IFEND;
      controller_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

      msp$search_con_access_job (pet_index, job_name, controller_found, status);
      IF controller_found THEN
        EXIT /loop_1/; {----->
      IFEND;
    FOREND /loop_1/;

    IF controller_found AND (controller_entry_p^.element_status.state = cmc$down) THEN
      maintenance_allowed := TRUE;
      RETURN; {----->
    IFEND;

    active_unit := FALSE;
    ppit_p := cmv$logical_pp_table_p^ [logical_pp_index].pp_info.pp_interface_table_p;

  /search_for_active_unit/
    FOR lun := LOWERBOUND (ppit_p^.unit_descriptors) TO UPPERBOUND (ppit_p^.unit_descriptors) DO
      IF ppit_p^.unit_descriptors [lun].unit_interface_table = NIL THEN
        CYCLE /search_for_active_unit/; {----->
      IFEND;

      IF ppit_p^.unit_descriptors [lun].physical_path.port <> channel_port_number THEN
        CYCLE /search_for_active_unit/; {----->
      IFEND;

      IF ppit_p^.unit_descriptors [lun].unit_interface_table_rma <> 0 THEN
        IF controller_found THEN
          IF ppit_p^.unit_descriptors [lun].physical_path.controller_number = pen THEN
            active_unit := TRUE;
            EXIT /search_for_active_unit/; {----->
          IFEND
        ELSE
          active_unit := TRUE;
          EXIT /search_for_active_unit/; {----->
        IFEND;
      IFEND;
    FOREND /search_for_active_unit/;

    maintenance_allowed := active_unit;

  PROCEND cmp$validate_unused_channel;

?? OLDTITLE ??
?? NEWTITLE := 'msp$mark_element_requested', EJECT ??

{ PURPOSE:
{   This procedure updates the peripheral element table as being requested for maintenance access (CONCURRENT
{   or DEDICATED).  When an entry has been marked as dedicated access, subsequent dedicated maintenance access
{   on that entry will be denied.

  PROCEDURE [XDCL, #GATE] msp$mark_element_requested
    (    element: cmt$element_descriptor;
         access_type: mst$access_type;
         job_name: jmt$system_supplied_name;
         gtid: ost$global_task_id;
     VAR status: ost$status);

    VAR
      entry_p: ^cmt$peripheral_element_entry,
      element_reservation: cmt$element_reservation,
      peripheral_index: integer;

    cmp$search_peripheral_table (element, element_reservation, FALSE, peripheral_index, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF access_type = msc$dedicated_access THEN
      entry_p := ^cmv$peripheral_element_table.pointer^ [peripheral_index];
      entry_p^.maintenance_activity.access := msc$dedicated_access;
      entry_p^.maintenance_activity.dedicated_accessor.active := TRUE;
      entry_p^.maintenance_activity.dedicated_accessor.job_identification := job_name;
      entry_p^.gtid := gtid;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status);

  PROCEND msp$mark_element_requested;
?? OLDTITLE ??
?? NEWTITLE := 'msp$search_con_access_job', EJECT ??

  PROCEDURE [XDCL, #GATE] msp$search_con_access_job
    (    peripheral_index: integer;
         job_name: jmt$system_supplied_name;
     VAR found: boolean;
     VAR status: ost$status);

    VAR
      access: mst$access_type,
      con_access_job_list_p: mst$con_access_job_list;

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

    access := cmv$peripheral_element_table.pointer^ [peripheral_index].maintenance_activity.access;

    CASE access OF
    = msc$concurrent_access =
      con_access_job_list_p := cmv$peripheral_element_table.pointer^ [peripheral_index].maintenance_activity.
            con_access_job_list;
      WHILE con_access_job_list_p <> NIL DO
        IF con_access_job_list_p^.job_name = job_name THEN
          found := TRUE;
          RETURN; {----->
        IFEND;
        con_access_job_list_p := con_access_job_list_p^.forward_link;
      WHILEND;
    = msc$dedicated_access =
      found := cmv$peripheral_element_table.pointer^ [peripheral_index].maintenance_activity.
            dedicated_accessor.job_identification = job_name;
    ELSE
    CASEND;

  PROCEND msp$search_con_access_job;
?? OLDTITLE ??
?? NEWTITLE := 'msp$unmark_element_requested', EJECT ??

{ PURPOSE:
{   This procedure unmark an element entry as a result of msp$release_maintenance_access.

  PROCEDURE [XDCL, #GATE] msp$unmark_element_requested
    (    job_name: jmt$system_supplied_name;
         gtid: ost$global_task_id;
         peripheral_index: integer;
         mainframe_id: pmt$mainframe_id;
     VAR dedicated_access_released: boolean;
     VAR status: ost$status);

    VAR
      entry_p: ^cmt$peripheral_element_entry,
      iou_number: dst$iou_number,
      pc_index: integer,
      status_p: ^ost$status,
      table_index: integer;

    dedicated_access_released := FALSE;
    osp$set_signature_lock (cmv$peripheral_element_table.lock, osc$wait, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    { Check WRONG JOB, no DEDICATED or CONCURRENT ACCESS }

    entry_p := ^cmv$peripheral_element_table.pointer^ [peripheral_index];

  /main_program/
    BEGIN
      IF entry_p^.maintenance_activity.access = msc$dedicated_access THEN
        IF entry_p^.maintenance_activity.dedicated_accessor.job_identification <> job_name THEN
          osp$set_status_abnormal (msc$maintenance_services_id, mse$dedicated_access_granted,
                entry_p^.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter,
                entry_p^.maintenance_activity.dedicated_accessor.job_identification, status);
          EXIT /main_program/; {----->
        IFEND;

        entry_p^.maintenance_activity.dedicated_accessor.job_identification := ' ';
        entry_p^.maintenance_activity.dedicated_accessor.active := FALSE;
        entry_p^.maintenance_activity.access := msc$concurrent_access;
        entry_p^.maintenance_activity.con_access_job_list := NIL;
        entry_p^.gtid.index := 4095;
        entry_p^.gtid.seqno := 255;
        dedicated_access_released := TRUE;

        { Check to see if the element is in the active physical configuration having multiple channel
        { connections.  If so, release all additional channels to the real state system.

      /pc_loop_1/
        FOR pc_index := 1 TO UPPERBOUND (cmv$physical_configuration^) DO
          IF (cmv$physical_configuration^ [pc_index].element_type =
                entry_p^.physical_descriptor.element_type) AND (cmv$physical_configuration^ [pc_index].
                element_name = entry_p^.element_name) THEN

            { Release all channels connected to controller to the real state system }
            cmp$request_channels (dsc$rrt_return_channel, cmv$physical_configuration^ [pc_index],
                  mainframe_id, status);
            IF NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;
            EXIT /pc_loop_1/; {----->
          IFEND;
        FOREND /pc_loop_1/;
      IFEND;
    END /main_program/;

    IF status.normal THEN
      status_p := ^status;
    ELSE
      PUSH status_p;
    IFEND;

    osp$clear_signature_lock (cmv$peripheral_element_table.lock, status_p^);

  PROCEND msp$unmark_element_requested;
?? OLDTITLE ??
MODEND cmm$manage_cm_tables_r1;
