?? RIGHT := 110 ??
?? NEWTITLE := 'Connection Management Interfaces' ??
MODULE cmm$connection_manager;
{
{ PURPOSE: This module contains interfaces that maintain and display information
{          about connections between elements in a configuration.  The connection
{          information is stored in the physical_descriptor field of the
{          peripheral_element_table which resides in the mainframe_wired segment.
{
{ DESIGN:  A connection status may be in one of three states:
{            cmc$active - both the upline and downline elements are in the ON state.
{            cmc$inactive - either one or both of the upline and downline elements are
{                           in the OFF or DOWN state.
{            cmc$disabled - both the upline and downline element are in the ON state
{                           but an automatic reconfiguration has disabled the connection
{                           and reconfigured to a redundant path.


?? PUSH (LISTEXT := ON) ??
*copyc cme$logical_configuration_mgr
*copyc cmt$connection
*copyc cmt$element_descriptor
*copyc cmt$element_reservation
*copyc cmt$upline_connection
*copyc cmv$peripheral_element_table
*copyc cmv$physical_configuration
*copyc ost$status
?? POP ??
*copyc cmp$get_element_definition
*copyc cmp$get_mainframe_element
*copyc cmp$search_peripheral_table
*copyc pmp$get_mainframe_id
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal

?? TITLE := '  cmp$get_connection_list', EJECT ??

{
{ PURPOSE:
{   This procedure will return an array that contains connection information for
{   every connection in every path that contains the specified element.  For example,
{   if a channel is specified the array would contain all channel/controller connections
{   and all controller /unit connections accessible by the channel.  The connection
{   information includes the upline element name, the downline element name and the
{   connection status.  The connection count will return the number of connections
{   found.  If the array supplied was not large enough to hold all connections found
{   this value can be used to allocate an array of the proper size before calling this
{   procedure again.
{

  PROCEDURE [XDCL, #GATE] cmp$get_connection_list
    (    element_definition: cmt$element_definition;
     VAR connection_count: integer;
     VAR connection_list: ^array [1 .. * ] of cmt$connection;
     VAR status: ost$status);

    VAR
      controller_definition: cmt$element_definition,
      dummy_reservation: cmt$element_reservation,
      element_descriptor: cmt$element_descriptor,
      i: integer,
      iou_channel: cmt$element_name,
      j: integer,
      mainframe_id: pmt$mainframe_id,
      pet_index: integer,
      pet_index_2: integer,
      upline_connection: cmt$upline_connection;

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

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

    CASE element_definition.element_type OF
    = cmc$data_channel_element =
      {
      { Find the channel in the peripheral_element table.
      {
      element_descriptor.element_type := element_definition.element_type;
      element_descriptor.channel_descriptor.iou := element_definition.data_channel.iou;
      element_descriptor.channel_descriptor.use_logical_identification := TRUE;
      element_descriptor.channel_descriptor.name := element_definition.element_name;
      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      iou_channel := element_definition.data_channel.iou;
      iou_channel (5) := '/';
      iou_channel (6, * ) := element_definition.element_name;

      FOR i := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
            channel_connection^) DO
        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          connection_list^ [connection_count].upline_element := iou_channel;
          connection_list^ [connection_count].downline_element := cmv$peripheral_element_table.
                pointer^ [pet_index].physical_descriptor.channel_connection^ [i].downline_element;
          connection_list^ [connection_count].status := cmv$peripheral_element_table.pointer^ [pet_index].
                physical_descriptor.channel_connection^ [i].status;
        IFEND;

        cmp$get_mainframe_element (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
              channel_connection^ [i].downline_element, element_definition.data_channel.iou,
              controller_definition, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        CASE controller_definition.element_type OF
        = cmc$controller_element, cmc$channel_adapter_element =
          element_descriptor.element_type := controller_definition.element_type;
          element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
          element_descriptor.peripheral_descriptor.element_name := controller_definition.element_name;

          cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index_2, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          FOR j := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index_2].physical_descriptor.
                equipment_connection^) DO
            connection_count := connection_count + 1;
            IF connection_count <= UPPERBOUND (connection_list^) THEN
              connection_list^ [connection_count].upline_element :=
                    element_descriptor.peripheral_descriptor.element_name;
              connection_list^ [connection_count].downline_element := cmv$peripheral_element_table.
                    pointer^ [pet_index_2].physical_descriptor.equipment_connection^ [j].downline_element;
              connection_list^ [connection_count].status := cmv$peripheral_element_table.
                    pointer^ [pet_index_2].physical_descriptor.equipment_connection^ [j].status;
            IFEND;
          FOREND;
        ELSE
        CASEND;
      FOREND;

    = cmc$communications_element =

    /equipment_loop_1/
      FOR i := LOWERVALUE (cmt$communications_port_number) TO UPPERVALUE (cmt$communications_port_number) DO
        IF NOT element_definition.communications_element.connection.port [i].configured THEN
          CYCLE /equipment_loop_1/;
        IFEND;

        upline_connection := element_definition.communications_element.connection.port [i];
        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        IF upline_connection.mainframe_ownership <> mainframe_id THEN
          CYCLE /equipment_loop_1/
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          iou_channel := upline_connection.iou;
          iou_channel (5) := '/';
          iou_channel (6, * ) := upline_connection.element_name;

          connection_list^ [connection_count].upline_element := iou_channel;
          connection_list^ [connection_count].downline_element := element_definition.element_name;
          cmp$get_connection_status (element_descriptor, element_definition.element_name,
                connection_list^ [connection_count].status, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      FOREND /equipment_loop_1/;

    = cmc$external_processor_element =

    /external_processor_loop_1/
      FOR i := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
        IF element_definition.external_processor.connection.io_port [i].configured THEN
          upline_connection := element_definition.external_processor.connection.io_port [i];
          IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                  element_definition.element_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                  status);
            RETURN;
          IFEND;

          IF upline_connection.mainframe_ownership <> mainframe_id THEN
            CYCLE /external_processor_loop_1/;
          IFEND;

          element_descriptor.element_type := upline_connection.upline_connection_type;
          element_descriptor.channel_descriptor.name := upline_connection.element_name;
          element_descriptor.channel_descriptor.iou := upline_connection.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;

          connection_count := connection_count + 1;
          IF connection_count <= UPPERBOUND (connection_list^) THEN
            iou_channel := upline_connection.iou;
            iou_channel (5) := '/';
            iou_channel (6, * ) := upline_connection.element_name;

            connection_list^ [connection_count].upline_element := iou_channel;
            connection_list^ [connection_count].downline_element := element_definition.element_name;
            cmp$get_connection_status (element_descriptor, element_definition.element_name,
                  connection_list^ [connection_count].status, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
        IFEND;
      FOREND /external_processor_loop_1/;

    = cmc$controller_element =

    /controller_loop_1/
      FOR i := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
        IF element_definition.controller.connection.port [i].configured THEN
          upline_connection := element_definition.controller.connection.port [i];
          IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                  element_definition.element_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                  status);
            RETURN;
          IFEND;

          IF upline_connection.mainframe_ownership <> mainframe_id THEN
            CYCLE /controller_loop_1/;
          IFEND;

          element_descriptor.element_type := upline_connection.upline_connection_type;
          element_descriptor.channel_descriptor.name := upline_connection.element_name;
          element_descriptor.channel_descriptor.iou := upline_connection.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;

          connection_count := connection_count + 1;
          IF connection_count <= UPPERBOUND (connection_list^) THEN
            iou_channel := upline_connection.iou;
            iou_channel (5) := '/';
            iou_channel (6, * ) := upline_connection.element_name;

            connection_list^ [connection_count].upline_element := iou_channel;
            connection_list^ [connection_count].downline_element := element_definition.element_name;
            cmp$get_connection_status (element_descriptor, element_definition.element_name,
                  connection_list^ [connection_count].status, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
        IFEND;
      FOREND /controller_loop_1/;

      element_descriptor.element_type := element_definition.element_type;
      element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
      element_descriptor.peripheral_descriptor.element_name := element_definition.element_name;
      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      FOR i := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
            equipment_connection^) DO
        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          connection_list^ [connection_count].upline_element := element_definition.element_name;
          connection_list^ [connection_count].downline_element := cmv$peripheral_element_table.
                pointer^ [pet_index].physical_descriptor.equipment_connection^ [i].downline_element;
          connection_list^ [connection_count].status := cmv$peripheral_element_table.pointer^ [pet_index].
                physical_descriptor.equipment_connection^ [i].status;
        IFEND;
      FOREND;

    = cmc$channel_adapter_element =
      IF element_definition.channel_adapter.connection.channel.configured THEN
        upline_connection := element_definition.channel_adapter.connection.channel;
        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          iou_channel := upline_connection.iou;
          iou_channel (5) := '/';
          iou_channel (6, * ) := upline_connection.element_name;

          connection_list^ [connection_count].upline_element := iou_channel;
          connection_list^ [connection_count].downline_element := element_definition.element_name;
          cmp$get_connection_status (element_descriptor, element_definition.element_name,
                connection_list^ [connection_count].status, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      IFEND;

      element_descriptor.element_type := element_definition.element_type;
      element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
      element_descriptor.peripheral_descriptor.element_name := element_definition.element_name;
      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      FOR i := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
            equipment_connection^) DO
        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          connection_list^ [connection_count].upline_element := element_definition.element_name;
          connection_list^ [connection_count].downline_element := cmv$peripheral_element_table.
                pointer^ [pet_index].physical_descriptor.equipment_connection^ [i].downline_element;
          connection_list^ [connection_count].status := cmv$peripheral_element_table.pointer^ [pet_index].
                physical_descriptor.equipment_connection^ [i].status;
        IFEND;
      FOREND;

    = cmc$storage_device_element =
      IF element_definition.product_id.product_number = '  $887' THEN
        cmp$get_hydra_connection_list (element_definition, connection_count, connection_list, status);
        RETURN;
      IFEND;

    /unit_loop/
      FOR i := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        IF NOT element_definition.storage_device.connection.port [i].configured THEN
          CYCLE /unit_loop/;
        IFEND;
        upline_connection := element_definition.storage_device.connection.port [i];

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
        element_descriptor.peripheral_descriptor.element_name := upline_connection.element_name;

        cmp$get_element_definition (element_descriptor, controller_definition, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        CASE upline_connection.upline_connection_type OF
        = cmc$controller_element =

        /controller_loop_2/
          FOR j := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
            IF NOT controller_definition.controller.connection.port [j].configured THEN
              CYCLE /controller_loop_2/;
            IFEND;

            upline_connection := controller_definition.controller.connection.port [j];
            IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
              osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                    controller_definition.element_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                    status);
              RETURN;
            IFEND;

            IF upline_connection.mainframe_ownership <> mainframe_id THEN
              CYCLE /controller_loop_2/;
            IFEND;

            element_descriptor.element_type := upline_connection.upline_connection_type;
            element_descriptor.channel_descriptor.name := upline_connection.element_name;
            element_descriptor.channel_descriptor.iou := upline_connection.iou;
            element_descriptor.channel_descriptor.use_logical_identification := TRUE;

            connection_count := connection_count + 1;
            IF connection_count <= UPPERBOUND (connection_list^) THEN
              iou_channel := upline_connection.iou;
              iou_channel (5) := '/';
              iou_channel (6, * ) := upline_connection.element_name;

              connection_list^ [connection_count].upline_element := iou_channel;
              connection_list^ [connection_count].downline_element := controller_definition.element_name;
              cmp$get_connection_status (element_descriptor, controller_definition.element_name,
                    connection_list^ [connection_count].status, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
            IFEND;
          FOREND /controller_loop_2/;

        = cmc$channel_adapter_element =
          upline_connection := controller_definition.channel_adapter.connection.channel;
          IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
            osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                  controller_definition.element_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                  status);
            RETURN;
          IFEND;

          element_descriptor.element_type := upline_connection.upline_connection_type;
          element_descriptor.channel_descriptor.name := upline_connection.element_name;
          element_descriptor.channel_descriptor.iou := upline_connection.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;

          connection_count := connection_count + 1;
          IF connection_count <= UPPERBOUND (connection_list^) THEN
            iou_channel := upline_connection.iou;
            iou_channel (5) := '/';
            iou_channel (6, * ) := upline_connection.element_name;

            connection_list^ [connection_count].upline_element := iou_channel;
            connection_list^ [connection_count].downline_element := controller_definition.element_name;
            cmp$get_connection_status (element_descriptor, controller_definition.element_name,
                  connection_list^ [connection_count].status, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;

        ELSE
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
        CASEND;

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

        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          connection_list^ [connection_count].upline_element := controller_definition.element_name;
          connection_list^ [connection_count].downline_element := element_definition.element_name;
          cmp$get_connection_status (element_descriptor, element_definition.element_name,
                connection_list^ [connection_count].status, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      FOREND /unit_loop/;

    ELSE
    CASEND;

  PROCEND cmp$get_connection_list;

?? TITLE := '  cmp$get_connection_status', EJECT ??
{
{ PURPOSE:
{   This procedure will return the current status for the connection which includes
{   the specified upline element and downline element.
{

  PROCEDURE [XDCL, #GATE] cmp$get_connection_status
    (    upline_element_descriptor: cmt$element_descriptor;
         downline_element_name: cmt$element_name;
     VAR connection_status: cmt$connection_status;
     VAR status: ost$status);

    VAR
      dummy_reservation: cmt$element_reservation,
      element_name: cmt$element_name,
      i: integer,
      pet_index: integer;

    status.normal := TRUE;

    cmp$search_peripheral_table (upline_element_descriptor, dummy_reservation, FALSE, pet_index, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE upline_element_descriptor.element_type OF
    = cmc$data_channel_element =
      FOR i := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
            channel_connection^) DO
        IF cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.channel_connection^ [i].
              downline_element = downline_element_name THEN
          connection_status := cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
                channel_connection^ [i].status;
          RETURN;
        IFEND;
      FOREND;

      IF upline_element_descriptor.channel_descriptor.use_logical_identification THEN
        element_name := upline_element_descriptor.channel_descriptor.name;
      ELSE
        element_name := osc$null_name;
      IFEND;
      osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_downline_connection,
            element_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, downline_element_name, status);
      RETURN;

    = cmc$controller_element, cmc$channel_adapter_element =
      FOR i := 1 TO UPPERBOUND (cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
            equipment_connection^) DO
        IF cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.equipment_connection^ [i].
              downline_element = downline_element_name THEN
          connection_status := cmv$peripheral_element_table.pointer^ [pet_index].physical_descriptor.
                equipment_connection^ [i].status;
          RETURN;
        IFEND;
      FOREND;

      IF upline_element_descriptor.peripheral_descriptor.use_logical_identification THEN
        element_name := upline_element_descriptor.peripheral_descriptor.element_name;
      ELSE
        element_name := osc$null_name;
      IFEND;
      osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_downline_connection,
            element_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, downline_element_name, status);
      RETURN;

    = cmc$communications_element, cmc$external_processor_element, cmc$storage_device_element =
      IF upline_element_descriptor.peripheral_descriptor.use_logical_identification THEN
        element_name := upline_element_descriptor.peripheral_descriptor.element_name;
      ELSE
        element_name := osc$null_name;
      IFEND;
      osp$set_status_abnormal (cmc$configuration_management_id, cme$unsupported_connection,
            element_name, status);
      RETURN;
    ELSE
    CASEND;

  PROCEND cmp$get_connection_status;

?? TITLE := '  cmp$get_hydra_connection_list', EJECT ??
{
{ PURPOSE:
{   This procedure will return an array that contains connection information for
{   every connection in every path that contains the specified HYDRA mass storage
{   element.  The connection information includes the upline element name, the
{   downline element name and the connection status.  The connection count will
{   return the number of connections found.  If the array supplied was not large
{   enough to hold all connections found this value can be used to allocate an
{   array of the proper size before calling this procedure again.
{

  PROCEDURE cmp$get_hydra_connection_list
    (    element_definition: cmt$element_definition;
     VAR connection_count: integer;
     VAR connection_list: ^array [1 .. * ] of cmt$connection;
     VAR status: ost$status);

    VAR
      element_descriptor: cmt$element_descriptor,
      i: integer,
      iou_channel: cmt$element_name,
      upline_connection: cmt$upline_connection;

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

    FOR i := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
      IF element_definition.storage_device.connection.port [i].configured THEN
        upline_connection := element_definition.storage_device.connection.port [i];

        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        connection_count := connection_count + 1;
        IF connection_count <= UPPERBOUND (connection_list^) THEN
          iou_channel := upline_connection.iou;
          iou_channel (5) := '/';
          iou_channel (6, * ) := upline_connection.element_name;

          connection_list^ [connection_count].upline_element := iou_channel;
          connection_list^ [connection_count].downline_element := element_definition.element_name;
          cmp$get_connection_status (element_descriptor, element_definition.element_name,
                connection_list^ [connection_count].status, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      IFEND;
    FOREND;
  PROCEND cmp$get_hydra_connection_list;

?? TITLE := '  cmp$locate_disabled_connection', EJECT ??

{
{ PURPOSE:
{   This procedure will search all downline and upline connections of the
{   specified element for a disabled connection.  If a connection_status
{    of CMC$DISABLED is found the parameter disabled_connection_exists will
{    be set to TRUE, otherwise it will be set to FALSE.

  PROCEDURE [XDCL, #GATE] cmp$locate_disabled_connection
    (    element_definition: cmt$element_definition;
     VAR disabled_connection_exists: boolean;
     VAR status: ost$status);

    VAR
      connection_status: cmt$connection_status,
      dummy_reservation: cmt$element_reservation,
      element_descriptor: cmt$element_descriptor,
      i: integer,
      j: integer,
      mainframe_id: pmt$mainframe_id,
      pet_entry_p: ^cmt$peripheral_element_entry,
      pet_index: integer,
      upline_connection: cmt$upline_connection;

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

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

    CASE element_definition.element_type OF
    = cmc$data_channel_element =
      {
      { Find the channel in the peripheral_element table.
      {
      element_descriptor.element_type := element_definition.element_type;
      element_descriptor.channel_descriptor.iou := element_definition.data_channel.iou;
      element_descriptor.channel_descriptor.use_logical_identification := TRUE;
      element_descriptor.channel_descriptor.name := element_definition.element_name;
      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

      FOR i := 1 TO UPPERBOUND (pet_entry_p^.physical_descriptor.channel_connection^) DO
        IF pet_entry_p^.physical_descriptor.channel_connection^ [i].status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
          RETURN;
        IFEND;
      FOREND;

    = cmc$communications_element =

    /equipment_loop_1/
      FOR i := LOWERVALUE (cmt$communications_port_number) TO UPPERVALUE (cmt$communications_port_number) DO
        IF NOT element_definition.communications_element.connection.port [i].configured THEN
          CYCLE /equipment_loop_1/;
        IFEND;

        upline_connection := element_definition.communications_element.connection.port [i];
        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        IF upline_connection.mainframe_ownership <> mainframe_id THEN
          CYCLE /equipment_loop_1/
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        cmp$get_connection_status (element_descriptor, element_definition.element_name, connection_status,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF connection_status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
        IFEND;

      FOREND /equipment_loop_1/;

    = cmc$external_processor_element =
    /ext_proc_loop/
      FOR i := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
        IF NOT element_definition.external_processor.connection.io_port [i].configured THEN
          CYCLE /ext_proc_loop/;
        IFEND;

        upline_connection := element_definition.external_processor.connection.io_port [i];
        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        cmp$get_connection_status (element_descriptor, element_definition.element_name, connection_status,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF connection_status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
        IFEND;
      FOREND;

    = cmc$controller_element =
      element_descriptor.element_type := element_definition.element_type;
      element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
      element_descriptor.peripheral_descriptor.element_name := element_definition.element_name;
      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

      FOR i := 1 TO UPPERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^) DO
        IF pet_entry_p^.physical_descriptor.equipment_connection^ [i].status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
          RETURN;
        IFEND;
      FOREND;

    = cmc$channel_adapter_element =
      IF element_definition.channel_adapter.connection.channel.configured THEN
        upline_connection := element_definition.channel_adapter.connection.channel;
        IF upline_connection.upline_connection_type <> cmc$data_channel_element THEN
          osp$set_status_abnormal (cmc$configuration_management_id, cme$invalid_upline_connection,
                element_definition.element_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, upline_connection.element_name,
                status);
          RETURN;
        IFEND;

        element_descriptor.element_type := upline_connection.upline_connection_type;
        element_descriptor.channel_descriptor.name := upline_connection.element_name;
        element_descriptor.channel_descriptor.iou := upline_connection.iou;
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;

        cmp$get_connection_status (element_descriptor, element_definition.element_name, connection_status,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF connection_status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
        IFEND;
      IFEND;

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

      cmp$search_peripheral_table (element_descriptor, dummy_reservation, FALSE, pet_index, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      pet_entry_p := ^cmv$peripheral_element_table.pointer^ [pet_index];

      FOR i := 1 TO UPPERBOUND (pet_entry_p^.physical_descriptor.equipment_connection^) DO
        IF pet_entry_p^.physical_descriptor.equipment_connection^ [i].status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
          RETURN;
        IFEND;
      FOREND;

    = cmc$storage_device_element =

    /unit_loop/
      FOR i := LOWERVALUE (cmt$data_storage_port_number) TO UPPERVALUE (cmt$data_storage_port_number) DO
        IF NOT element_definition.storage_device.connection.port [i].configured THEN
          CYCLE /unit_loop/;
        IFEND;

        upline_connection := element_definition.storage_device.connection.port [i];

        element_descriptor.element_type := upline_connection.upline_connection_type;
        CASE upline_connection.upline_connection_type OF
        = cmc$data_channel_element =
          element_descriptor.channel_descriptor.iou := upline_connection.iou;
          element_descriptor.channel_descriptor.use_logical_identification := TRUE;
          element_descriptor.channel_descriptor.name := upline_connection.element_name;

        = cmc$controller_element, cmc$channel_adapter_element =
          element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
          element_descriptor.peripheral_descriptor.element_name := upline_connection.element_name;
        ELSE
        CASEND;

        cmp$get_connection_status (element_descriptor, element_definition.element_name, connection_status,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF connection_status = cmc$disabled THEN
          disabled_connection_exists := TRUE;
        IFEND;

      FOREND /unit_loop/;

    ELSE
    CASEND;

  PROCEND cmp$locate_disabled_connection;

MODEND cmm$connection_manager;
